@theokit/sdk 4.63.1 → 4.63.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +52 -0
- package/dist/{agent-YWMBM7LX.js → agent-3JK7VXNN.js} +5 -5
- package/dist/{agent-YWMBM7LX.js.map → agent-3JK7VXNN.js.map} +1 -1
- package/dist/{agent-WK7MKIMH.cjs → agent-PVINJTUR.cjs} +6 -6
- package/dist/{agent-WK7MKIMH.cjs.map → agent-PVINJTUR.cjs.map} +1 -1
- package/dist/{chunk-KIH6IZ43.js → chunk-25BD2R5G.js} +24 -7
- package/dist/chunk-25BD2R5G.js.map +1 -0
- package/dist/{chunk-DKD3MH6A.js → chunk-ACDLHN3W.js} +3 -3
- package/dist/{chunk-DKD3MH6A.js.map → chunk-ACDLHN3W.js.map} +1 -1
- package/dist/{chunk-BVJJ3DRV.js → chunk-GPKAF7SG.js} +3 -3
- package/dist/{chunk-BVJJ3DRV.js.map → chunk-GPKAF7SG.js.map} +1 -1
- package/dist/{chunk-6RKUO7AW.cjs → chunk-IAHZCGBE.cjs} +5 -4
- package/dist/chunk-IAHZCGBE.cjs.map +1 -0
- package/dist/{chunk-ZMRD5DZQ.cjs → chunk-JJ3OVRUM.cjs} +39 -22
- package/dist/chunk-JJ3OVRUM.cjs.map +1 -0
- package/dist/{chunk-UEXIJTLC.js → chunk-L3MTL4NA.js} +3 -3
- package/dist/{chunk-UEXIJTLC.js.map → chunk-L3MTL4NA.js.map} +1 -1
- package/dist/{chunk-GEEXBYFL.js → chunk-L4BDVXIM.js} +4 -3
- package/dist/chunk-L4BDVXIM.js.map +1 -0
- package/dist/{chunk-HOXVQ5FR.cjs → chunk-OFRFZRQ4.cjs} +8 -8
- package/dist/{chunk-HOXVQ5FR.cjs.map → chunk-OFRFZRQ4.cjs.map} +1 -1
- package/dist/{chunk-ITYQ6VBP.cjs → chunk-VLVVJLDH.cjs} +14 -14
- package/dist/{chunk-ITYQ6VBP.cjs.map → chunk-VLVVJLDH.cjs.map} +1 -1
- package/dist/{chunk-Q7LPTOD6.cjs → chunk-ZWRG4NWT.cjs} +4 -4
- package/dist/{chunk-Q7LPTOD6.cjs.map → chunk-ZWRG4NWT.cjs.map} +1 -1
- package/dist/cron.cjs +5 -5
- package/dist/cron.js +4 -4
- package/dist/eval.cjs +4 -4
- package/dist/eval.js +3 -3
- package/dist/{index-manager-UZBF22BJ.cjs → index-manager-2SRX45WJ.cjs} +6 -5
- package/dist/{index-manager-UZBF22BJ.cjs.map → index-manager-2SRX45WJ.cjs.map} +1 -1
- package/dist/{index-manager-RBDHP3PM.js → index-manager-SP4ISSDX.js} +5 -4
- package/dist/{index-manager-RBDHP3PM.js.map → index-manager-SP4ISSDX.js.map} +1 -1
- package/dist/index.cjs +26 -26
- package/dist/index.js +8 -8
- package/dist/internal/memory/storage/index.cjs +31 -30
- package/dist/internal/memory/storage/index.js +3 -2
- package/dist/internal/memory/storage/memory-root.d.cts +10 -0
- package/dist/internal/memory/storage/memory-root.d.ts +10 -0
- package/docs/error-codes.md +1 -1
- package/package.json +1 -1
- package/dist/chunk-6RKUO7AW.cjs.map +0 -1
- package/dist/chunk-GEEXBYFL.js.map +0 -1
- package/dist/chunk-KIH6IZ43.js.map +0 -1
- package/dist/chunk-ZMRD5DZQ.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/memory/escape-like-pattern.ts","../src/internal/memory/memory-index.ts","../src/internal/memory/lance-memory-adapter.ts","../src/internal/memory/index-manager-dispatch.ts","../src/internal/memory/sqlite-vec-loader.ts","../src/internal/memory/storage/chunk-markdown.ts","../src/internal/memory/vec-index.ts","../src/internal/memory/index-manager.ts"],"names":["ConfigurationError","LanceIndex","createHash","LruEmbeddingCache","resolveMemoryRoot","defaultIndexPath","projectMemoryDir","openMemoryDb","collectMarkdownFiles","readFile","sha256","stat","sanitizeFts5Query","truncateSnippet","resolveWeights","blendScores"],"mappings":"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","file":"chunk-ITYQ6VBP.cjs","sourcesContent":["/**\n * Escapes a user query for a SQL `LIKE ... ESCAPE '\\'` clause.\n *\n * The order of the three replacements is the whole correctness argument, so it is its own\n * function rather than a chain inline at the call site.\n *\n * The previous version escaped `%` and `_` but not the escape character itself, which is the\n * defect CodeQL reports as `js/incomplete-sanitization` (alerts #14, #15). Two things went wrong,\n * and the second is the one that matters:\n *\n * \"back\\slash\" -> \"%back\\slash%\" the `\\s` is an escape of `s`, which LIKE does not define\n * \"x\\%y\" -> \"%x\\\\%y%\" the inserted `\\` is consumed escaping the user's `\\`,\n * leaving `%` UNESCAPED — a wildcard the caller did not\n * write, matching anything between `x\\` and `y`\n *\n * The second is wildcard injection: a search for a literal string silently becomes a scan. In a\n * memory index that is both a wrong answer and a way to pull back rows the query never asked for.\n *\n * Escaping the backslash FIRST is what fixes it — afterwards every `\\` in the string is one this\n * function put there, so the later replacements cannot collide with a user-supplied one.\n */\nexport function escapeLikePattern(query: string): string {\n return `%${query.replace(/\\\\/g, \"\\\\\\\\\").replace(/%/g, \"\\\\%\").replace(/_/g, \"\\\\_\")}%`;\n}\n","/**\n * Common `MemoryIndex` interface shared between the SQLite-backed\n * `IndexManager` (default) and the Lance-backed adapter (ADR D43, shipped\n * v1.4.0 via lancedb-backend-ship-v1-1 plan).\n *\n * Consumers (`local-agent-memory.ts`, `active-memory.ts`, `tools.ts`,\n * `runActiveMemory`) only ever call `sync()`, `search()`, `status()`,\n * `close()` — the union of those four methods is the portable surface.\n *\n * Why a separate file (vs declaring inline in `index-manager.ts`)? D43\n * promised \"extract an abstract `MemoryIndex` interface in\n * `internal/memory/index-interface.ts`\". Keeping the contract physically\n * separated from one of its implementations preserves OCP — future\n * backends (Qdrant, PGVector) can land without touching IndexManager.\n *\n * @internal\n */\n\nimport type { IndexStatus, MemorySearchHit, SearchOptions } from \"./index-manager-contract.js\";\n\n// Re-export consumer-facing shapes for stable internal import paths.\nexport type { IndexStatus, MemorySearchHit, SearchOptions };\n\nexport interface SyncResult {\n filesScanned: number;\n filesUpdated: number;\n chunksWritten: number;\n chunksEmbedded: number;\n}\n\n/**\n * Common search-options parser used by both `IndexManager.search` and\n * `LanceMemoryAdapter.search`. Returns the normalized cap + minimum-score\n * floor — eliminates jscpd duplication while keeping per-backend search\n * logic distinct.\n */\nexport function parseSearchOptions(options: SearchOptions = {}): {\n maxResults: number;\n minScore: number;\n} {\n return {\n maxResults: Math.max(1, options.maxResults ?? 10),\n minScore: options.minScore ?? 0,\n };\n}\n\nexport interface MemoryIndex {\n /**\n * Walk the memory corpus + reindex changed files. Lance backend has no\n * markdown corpus to walk — its adapter returns zero counts (no-op) and\n * relies on explicit `addFact` calls instead.\n */\n sync(): Promise<SyncResult>;\n\n /**\n * Semantic + textual search over the indexed corpus. Both backends\n * return the same `MemorySearchHit[]` shape; Lance leaves `textScore`\n * undefined (vector-only — no FTS5 layer).\n */\n search(query: string, options?: SearchOptions): Promise<MemorySearchHit[]>;\n\n /** Snapshot of the index health (backend type + counts). */\n status(): IndexStatus;\n\n /** Release native handles. Idempotent. */\n close(): Promise<void> | void;\n}\n","/**\n * `LanceMemoryAdapter` — wraps `LanceIndex` to expose the common\n * `MemoryIndex` interface (sync/search/status/close) so consumers of\n * `IndexManager.open({ backend: \"lance\" })` get a drop-in replacement\n * for the SQLite-backed `IndexManager`.\n *\n * Semantic deltas vs SQLite (documented so callers know what to expect):\n *\n * - `sync()` is a NO-OP. Lance is a pure vector store — there is no\n * markdown corpus to crawl. Returns zero counts. Consumers writing\n * facts use `LanceIndex.addFacts` directly (exposed via the index\n * object returned to advanced callers).\n * - `search()` performs vector-only retrieval. `MemorySearchHit.textScore`\n * is undefined (no FTS5 layer); `vectorScore === score`.\n * - `status()` reports `backend: \"hybrid\"` only when an embedding runtime\n * is wired (always the case for Lance — embedding is required at open).\n * `chunksIndexed` reflects total Lance row count; `filesIndexed` is 0\n * because Lance does not track file provenance per-row.\n *\n * Ships with the lancedb-backend-ship-v1-1 plan (close D12, supersede via\n * D43). v1.4.0 of `@theokit/sdk`.\n *\n * @internal\n */\n\nimport type { IndexStatus, MemorySearchHit, SearchOptions } from \"./index-manager-contract.js\";\nimport type { LanceIndex } from \"./lance-index.js\";\nimport { type MemoryIndex, parseSearchOptions, type SyncResult } from \"./memory-index.js\";\n\n/**\n * Default namespace used when consumers call `search()` without specifying\n * one. The SQLite `IndexManager` does not surface namespace in its public\n * `search()` signature either — both backends therefore behave consistently\n * under the \"single-workspace, single-namespace\" assumption that v1.4 ships.\n *\n * v1.5 candidate: surface `namespace` in `SearchOptions` (additive — no\n * breaking change) so multi-tenant Lance consumers can scope queries.\n */\nconst DEFAULT_NAMESPACE = \"default\";\n\n/** Empty sync result — Lance has no corpus to walk. */\nconst EMPTY_SYNC_RESULT: SyncResult = Object.freeze({\n filesScanned: 0,\n filesUpdated: 0,\n chunksWritten: 0,\n chunksEmbedded: 0,\n});\n\nexport class LanceMemoryAdapter implements MemoryIndex {\n constructor(private readonly inner: LanceIndex) {}\n\n /**\n * No-op for Lance — see file header. Returns zero counts so callers'\n * existing logging (`filesScanned: X`) does not break.\n */\n async sync(): Promise<SyncResult> {\n return EMPTY_SYNC_RESULT;\n }\n\n // jscpd:ignore-start — search signature + early-out is idiomatic\n // overlap with IndexManager.search; further factoring would hurt\n // readability (the bodies diverge sharply right after).\n async search(query: string, options: SearchOptions = {}): Promise<MemorySearchHit[]> {\n if (query.trim().length === 0) return [];\n const { maxResults, minScore } = parseSearchOptions(options);\n // jscpd:ignore-end\n const lanceHits = await this.inner.search(query, {\n namespace: DEFAULT_NAMESPACE,\n limit: maxResults * 2,\n ...(options.sources !== undefined ? { sources: options.sources } : {}),\n });\n return lanceHits\n .filter((h) => h.score >= minScore)\n .slice(0, maxResults)\n .map((h) => translateLanceHit(h, query));\n }\n\n status(): IndexStatus {\n // chunksIndexed via a synchronous best-effort — Lance API is async so\n // we surface zero here and document that consumers needing exact counts\n // should call `inner.countFacts()` directly.\n return {\n backend: \"hybrid\",\n filesIndexed: 0,\n chunksIndexed: 0,\n };\n }\n\n async close(): Promise<void> {\n await this.inner.close();\n }\n\n /**\n * Escape hatch for advanced callers (migration tool, benchmark script)\n * that need direct access to addFacts/countFacts/removeFacts.\n */\n unwrap(): LanceIndex {\n return this.inner;\n }\n}\n\n/**\n * Translate `LanceSearchHit` to `MemorySearchHit`. Field mapping:\n *\n * - `id` → `path` (Lance has no file-system provenance; use opaque id)\n * - `text` → `snippet` (truncated to 200 chars matching IndexManager convention)\n * - `score` → combined (0.7 × vectorScore + 0.3 × textScore)\n * - `vectorScore` → from Lance's distance metric\n * - `textScore` → T4.5 client-side term-overlap ratio (removes ADR D43 vector-only caveat)\n * - `source` → `source`\n * - synthetic `startLine: 0, endLine: 0` (Lance has no line info)\n * - synthetic `citation: id` (no path:line citation available)\n */\nfunction translateLanceHit(\n hit: { id: string; text: string; source: \"memory\" | \"sessions\" | \"wiki\"; score: number },\n query?: string,\n): MemorySearchHit {\n const textScore = query !== undefined ? computeTermOverlapScore(query, hit.text) : 0;\n const vectorScore = hit.score;\n // Hybrid combination: 70% vector (semantic) + 30% text (lexical).\n const combined = 0.7 * vectorScore + 0.3 * textScore;\n return {\n path: hit.id,\n startLine: 0,\n endLine: 0,\n score: combined,\n textScore,\n vectorScore,\n snippet: hit.text.slice(0, 200),\n source: hit.source,\n citation: hit.id,\n };\n}\n\n/**\n * T4.5 — Client-side term-overlap score for Lance hybrid search.\n * Counts what fraction of query terms appear in the text (case-insensitive).\n * Simple but effective for re-ranking vector hits by lexical relevance.\n * Returns 0..1 where 1 = all query terms present.\n */\nfunction computeTermOverlapScore(query: string, text: string): number {\n const queryTerms = query\n .toLowerCase()\n .split(/\\s+/)\n .filter((t) => t.length > 1);\n if (queryTerms.length === 0) return 0;\n const textLower = text.toLowerCase();\n const matched = queryTerms.filter((term) => textLower.includes(term)).length;\n return matched / queryTerms.length;\n}\n","/**\n * Dispatch helpers for `IndexManager.open`. Extracted to keep\n * `index-manager.ts` under the G8 400-LoC budget (lancedb-backend-ship-v1-1).\n *\n * @internal\n */\n\nimport { ConfigurationError } from \"../../errors.js\";\nimport type { MemoryBackend, OpenIndexOptions } from \"./index-manager-contract.js\";\nimport { LanceIndex } from \"./lance-index.js\";\nimport { LanceMemoryAdapter } from \"./lance-memory-adapter.js\";\nimport type { MemoryIndex } from \"./memory-index.js\";\n\n/** Valid backend identifiers — runtime guard against TS-narrowing escapes (EC-1). */\nexport const VALID_BACKENDS: readonly MemoryBackend[] = [\"sqlite-vec\", \"lance\"];\n\n/**\n * EC-1: runtime guard for `opts.backend`. TS union is compile-time only;\n * consumers passing JS `as any` typos must hit a typed error, not silent\n * SQLite fallback.\n */\nexport function assertValidBackend(backend: string): asserts backend is MemoryBackend {\n if (!VALID_BACKENDS.includes(backend as MemoryBackend)) {\n throw new ConfigurationError(\n `Invalid memory backend \"${backend}\". Valid values: ${VALID_BACKENDS.join(\", \")}.`,\n { code: \"invalid_memory_backend\" },\n );\n }\n}\n\n/**\n * Lance-path open. Throws `lance_requires_embedding` when no embedding\n * runtime is provided (Lance is vector-only — no FTS fallback).\n * Surfaces `lance_backend_unavailable` from LanceIndex.open when peer\n * dep is absent.\n */\nexport async function openLanceIndex(opts: OpenIndexOptions): Promise<MemoryIndex> {\n if (opts.embedding === undefined) {\n throw new ConfigurationError(\n \"Lance backend requires an embedding runtime. Pass `embedding: { provider, model, apiKey }` in Memory.create options (or omit `backend` to use SQLite default).\",\n { code: \"lance_requires_embedding\" },\n );\n }\n const lance = await LanceIndex.open({\n cwd: opts.cwd,\n embedding: opts.embedding,\n ...(opts.filePath !== undefined ? { storagePath: opts.filePath } : {}),\n });\n return new LanceMemoryAdapter(lance);\n}\n","import { ConfigurationError } from \"../../errors.js\";\nimport type { MemoryDb } from \"./index-db.js\";\n\n/**\n * Load the `sqlite-vec` extension into an opened SQLite connection.\n *\n * Wraps the native `load(db)` call from the `sqlite-vec` npm package with a\n * typed error path (EC-8 of the edge-case review) so callers see a\n * `sqlite_vec_unavailable` ConfigurationError instead of a raw native error.\n *\n * @internal\n */\nexport async function loadSqliteVecExtension(db: MemoryDb): Promise<void> {\n try {\n const mod = await import(\"sqlite-vec\");\n const loadFn = (mod as { load?: (db: unknown) => void }).load;\n if (typeof loadFn !== \"function\") {\n throw new Error(\"sqlite-vec module exposes no `load` export\");\n }\n loadFn(db);\n } catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n throw new ConfigurationError(\n `sqlite-vec extension unavailable. Install \\`sqlite-vec\\` and ensure the native binary matches your Node + OS. Cause: ${message}`,\n { code: \"sqlite_vec_unavailable\", cause },\n );\n }\n}\n","import { createHash } from \"node:crypto\";\n\nimport type { MemoryChunk } from \"../types.js\";\n\n/**\n * Split a markdown document into semantically meaningful chunks (ADR D1 of\n * memory-system-peer-project-parity).\n *\n * Algorithm:\n * 1. Walk lines tracking the current heading (latest `^#+ ` line).\n * 2. Split chunks at the next heading boundary AND on blank-line paragraph\n * boundaries.\n * 3. If a single paragraph exceeds `maxChars`, split it at the nearest\n * whitespace ≤ maxChars (word-aligned per edge-case review EC-6) —\n * never mid-word.\n *\n * Mirrors peer-project's `chunkMarkdown` from\n * `packages/memory-host-sdk/src/host/chunk-markdown.ts`.\n *\n * @internal\n */\n\nexport interface ChunkMarkdownOptions {\n /** Maximum chars per chunk. Default 800. */\n maxChars?: number;\n /** Minimum chars per chunk (avoids splintering tiny lines). Default 80. */\n minChars?: number;\n}\n\nconst HEADING_RE = /^(#{1,6})\\s+(.+?)\\s*$/;\n\ninterface ChunkAccumulator {\n chunks: MemoryChunk[];\n lines: string[];\n start: number;\n heading: string | undefined;\n}\n\nexport function chunkMarkdown(text: string, options: ChunkMarkdownOptions = {}): MemoryChunk[] {\n const maxChars = options.maxChars ?? 800;\n if (text.length === 0) return [];\n const lines = text.split(\"\\n\");\n const acc: ChunkAccumulator = { chunks: [], lines: [], start: 1, heading: undefined };\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const lineNumber = i + 1;\n processLine(acc, line, lineNumber, maxChars);\n }\n flushAccumulator(acc, lines.length, maxChars);\n return acc.chunks;\n}\n\nfunction processLine(\n acc: ChunkAccumulator,\n line: string,\n lineNumber: number,\n maxChars: number,\n): void {\n const headingMatch = HEADING_RE.exec(line);\n const isBlank = line.trim().length === 0;\n if (headingMatch !== null && acc.lines.length > 0) {\n flushAccumulator(acc, lineNumber - 1, maxChars);\n }\n if (headingMatch !== null) acc.heading = headingMatch[2];\n acc.lines.push(line);\n if (isBlank && acc.lines.length > 1) {\n const joined = acc.lines.join(\"\\n\");\n if (joined.trim().length > 0) flushAccumulator(acc, lineNumber, maxChars);\n }\n}\n\nfunction flushAccumulator(acc: ChunkAccumulator, endLineExclusive: number, maxChars: number): void {\n if (acc.lines.length === 0) return;\n const chunkText = acc.lines.join(\"\\n\");\n if (chunkText.trim().length === 0) {\n acc.lines = [];\n acc.start = endLineExclusive + 1;\n return;\n }\n if (chunkText.length > maxChars) {\n pushOversizedSlices(acc.chunks, chunkText, acc.start, acc.heading, maxChars);\n } else {\n acc.chunks.push(buildChunk(chunkText, acc.start, endLineExclusive, acc.heading));\n }\n acc.lines = [];\n acc.start = endLineExclusive + 1;\n}\n\nfunction buildChunk(\n text: string,\n startLine: number,\n endLine: number,\n heading: string | undefined,\n): MemoryChunk {\n return {\n startLine,\n endLine,\n text,\n hash: createHash(\"sha256\").update(text).digest(\"hex\"),\n ...(heading !== undefined ? { heading } : {}),\n };\n}\n\nfunction pushOversizedSlices(\n chunks: MemoryChunk[],\n text: string,\n startLine: number,\n heading: string | undefined,\n maxChars: number,\n): void {\n let remaining = text;\n let lineCursor = startLine;\n while (remaining.length > maxChars) {\n const splitAt = findWordBoundarySplit(remaining, maxChars);\n const slice = remaining.slice(0, splitAt);\n const sliceLines = slice.split(\"\\n\").length;\n chunks.push(buildChunk(slice, lineCursor, lineCursor + sliceLines - 1, heading));\n remaining = remaining.slice(splitAt).replace(/^\\s+/, \"\");\n lineCursor += sliceLines - 1;\n }\n if (remaining.length > 0) {\n const sliceLines = remaining.split(\"\\n\").length;\n chunks.push(buildChunk(remaining, lineCursor, lineCursor + sliceLines - 1, heading));\n }\n}\n\n/**\n * Find a split point ≤ maxChars that lands on a whitespace boundary so we\n * don't slice a word in half. Falls back to maxChars if no whitespace is\n * within range (very rare — a single token > maxChars).\n */\nfunction findWordBoundarySplit(text: string, maxChars: number): number {\n if (text.length <= maxChars) return text.length;\n // Walk backward from maxChars looking for whitespace.\n for (let i = maxChars; i > Math.max(0, maxChars - 200); i--) {\n if (/\\s/.test(text[i] ?? \"x\")) return i;\n }\n // No whitespace within 200 chars of the cap — accept a hard split.\n return maxChars;\n}\n","import type { EmbeddingRuntime } from \"./embedding-adapter.js\";\nimport type { MemoryDb } from \"./index-db.js\";\n\n/**\n * Vector index helpers (ADR D2 + D4 of memory-system-peer-project-parity).\n *\n * Embeddings live in `embeddings(chunk_id, vec)` — a `vec0` virtual table\n * provided by the sqlite-vec extension. Embedding identity (providerId +\n * model + dimension) lives in the `meta` table; mismatches force a full\n * re-embed sweep (EC-1).\n *\n * @internal\n */\n\nexport const META_KEY_PROVIDER_ID = \"embedding.providerId\";\nexport const META_KEY_MODEL = \"embedding.model\";\nexport const META_KEY_DIMENSION = \"embedding.dimension\";\n\nexport interface EmbeddingIdentity {\n providerId: string;\n model: string;\n dimension: number;\n}\n\nexport function readEmbeddingIdentity(db: MemoryDb): EmbeddingIdentity | undefined {\n const get = (key: string): string | undefined => {\n const row = db.prepare(\"SELECT value FROM meta WHERE key = ?\").get(key);\n return row !== undefined ? String(row.value) : undefined;\n };\n const providerId = get(META_KEY_PROVIDER_ID);\n const model = get(META_KEY_MODEL);\n const dimRaw = get(META_KEY_DIMENSION);\n if (providerId === undefined || model === undefined || dimRaw === undefined) return undefined;\n const dimension = Number(dimRaw);\n if (!Number.isFinite(dimension) || dimension <= 0) return undefined;\n return { providerId, model, dimension };\n}\n\nexport function writeEmbeddingIdentity(db: MemoryDb, identity: EmbeddingIdentity): void {\n const stmt = db.prepare(\n \"INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value\",\n );\n stmt.run(META_KEY_PROVIDER_ID, identity.providerId);\n stmt.run(META_KEY_MODEL, identity.model);\n stmt.run(META_KEY_DIMENSION, String(identity.dimension));\n}\n\nexport function identityMatches(a: EmbeddingIdentity, b: EmbeddingIdentity): boolean {\n return a.providerId === b.providerId && a.model === b.model && a.dimension === b.dimension;\n}\n\nexport function dropVectorIndex(db: MemoryDb): void {\n db.exec(\"DROP TABLE IF EXISTS embeddings\");\n}\n\nexport function createVectorIndex(db: MemoryDb, dimension: number): void {\n db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS embeddings USING vec0(\n chunk_id INTEGER PRIMARY KEY,\n vec FLOAT[${dimension}]\n )`);\n}\n\n/** Pack a Float32Array into a Buffer suitable for sqlite-vec BLOB binding. */\nexport function packVector(vec: ReadonlyArray<number>): Buffer {\n const f32 = new Float32Array(vec.length);\n for (let i = 0; i < vec.length; i++) f32[i] = vec[i] ?? 0;\n return Buffer.from(f32.buffer);\n}\n\nexport function upsertEmbedding(db: MemoryDb, chunkId: number, vec: ReadonlyArray<number>): void {\n // sqlite-vec vec0 virtual tables don't support UPSERT — emulate via\n // DELETE-then-INSERT. vec0 REJECTS JS Number for chunk_id columns; it\n // requires BigInt binding. Verified via repro against vec0 v0.1.9.\n const id = BigInt(chunkId);\n db.prepare(\"DELETE FROM embeddings WHERE chunk_id = ?\").run(id);\n db.prepare(\"INSERT INTO embeddings (chunk_id, vec) VALUES (?, ?)\").run(id, packVector(vec));\n}\n\nexport interface VectorHitRow {\n chunk_id: number;\n distance: number;\n}\n\nexport function vectorSearch(\n db: MemoryDb,\n query: ReadonlyArray<number>,\n k: number,\n): VectorHitRow[] {\n // sqlite-vec returns distance (lower = closer). Use KNN syntax. k needs\n // a BigInt-typed binding too.\n const rows = db\n .prepare(\n `SELECT chunk_id, distance FROM embeddings\n WHERE vec MATCH ? AND k = ?\n ORDER BY distance`,\n )\n .all(packVector(query), BigInt(k));\n return rows.map((row) => ({ chunk_id: Number(row.chunk_id), distance: Number(row.distance) }));\n}\n\nexport interface EmbedAllArgs {\n db: MemoryDb;\n runtime: EmbeddingRuntime;\n}\n\n/** Embed every chunk that doesn't yet have a vector. */\nexport async function embedMissingChunks(args: EmbedAllArgs): Promise<number> {\n const rows = args.db\n .prepare(\n `SELECT chunks.id as id, chunks.text as text\n FROM chunks\n LEFT JOIN embeddings ON embeddings.chunk_id = chunks.id\n WHERE embeddings.chunk_id IS NULL`,\n )\n .all();\n if (rows.length === 0) return 0;\n const normalized = rows.map((row) => ({ id: Number(row.id), text: String(row.text ?? \"\") }));\n const vectors = await args.runtime.embed(normalized.map((r) => r.text));\n for (let i = 0; i < normalized.length; i++) {\n const row = normalized[i];\n const vector = vectors[i];\n if (row === undefined || vector === undefined) continue;\n upsertEmbedding(args.db, row.id, vector);\n }\n return normalized.length;\n}\n","import { createHash } from \"node:crypto\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport { sanitizeFts5Query } from \"../persistence/fts5-sanitize.js\";\nimport type { EmbeddingRuntime } from \"./embedding-adapter.js\";\nimport { LruEmbeddingCache } from \"./embedding-cache.js\";\nimport { escapeLikePattern } from \"./escape-like-pattern.js\";\nimport { defaultIndexPath, type MemoryDb, openMemoryDb } from \"./index-db.js\";\nimport { assertValidBackend, openLanceIndex } from \"./index-manager-dispatch.js\";\nimport {\n blendScores,\n collectMarkdownFiles,\n resolveWeights,\n sha256,\n truncateSnippet,\n} from \"./index-manager-helpers.js\";\nimport { type MemoryIndex, parseSearchOptions } from \"./memory-index.js\";\nimport { loadSqliteVecExtension } from \"./sqlite-vec-loader.js\";\nimport { chunkMarkdown } from \"./storage/chunk-markdown.js\";\nimport { type MemoryRoot, projectMemoryDir, resolveMemoryRoot } from \"./storage/memory-root.js\";\n\n// T4.1 — query-vector LRU cache (DR4 finding #1). Keyed by\n// sha256(query); caches the embedding vector so repeated search\n// queries skip the HTTP round-trip (p99 1.5-3s → ~0ms on hit).\n// Process-wide singleton with bounded capacity (default 2000 queries).\nconst queryVectorCache = new LruEmbeddingCache(2000);\n\nimport {\n createVectorIndex,\n dropVectorIndex,\n embedMissingChunks,\n identityMatches,\n readEmbeddingIdentity,\n vectorSearch,\n writeEmbeddingIdentity,\n} from \"./vec-index.js\";\n\n/**\n * Memory index manager (ADR D2). FTS5-only at Phase 3; vector index lands in\n * Phase 5.\n *\n * Lifecycle:\n * const idx = await IndexManager.open({ cwd });\n * await idx.sync();\n * const hits = await idx.search(\"query\");\n * idx.close();\n *\n * @internal\n */\n\n// T2.1 / ADR D433 — these types now live in `index-manager-contract.ts`\n// to break the 3-cycle memory cluster. Re-exported here for back-compat\n// with downstream importers that historically pulled from this file.\nexport type {\n IndexStatus,\n MemoryBackend,\n MemorySearchHit,\n OpenIndexOptions,\n SearchOptions,\n} from \"./index-manager-contract.js\";\n\nimport type {\n IndexStatus,\n MemorySearchHit,\n OpenIndexOptions,\n SearchOptions,\n} from \"./index-manager-contract.js\";\n\nexport class IndexManager implements MemoryIndex {\n private lastSyncMs: number | undefined;\n private vectorReady = false;\n\n private constructor(\n private readonly memoryRoot: MemoryRoot,\n private readonly db: MemoryDb,\n private readonly embedding: EmbeddingRuntime | undefined,\n ) {}\n\n /**\n * Open a memory index. Dispatches to SQLite (default) or Lance (opt-in\n * via `backend: \"lance\"`). See `openLanceInternal` for Lance-specific\n * preconditions + typed errors.\n */\n static async open(opts: OpenIndexOptions & { backend: \"lance\" }): Promise<MemoryIndex>;\n static async open(\n opts: Omit<OpenIndexOptions, \"backend\"> | (OpenIndexOptions & { backend?: \"sqlite-vec\" }),\n ): Promise<IndexManager>;\n static async open(opts: OpenIndexOptions): Promise<MemoryIndex> {\n const backend = opts.backend ?? \"sqlite-vec\";\n assertValidBackend(backend);\n if (backend === \"lance\") return await openLanceIndex(opts);\n return await IndexManager.openSqliteInternal(opts);\n }\n\n /** Internal SQLite-path open. Renamed from previous public `open`. */\n private static async openSqliteInternal(opts: OpenIndexOptions): Promise<IndexManager> {\n const memoryRoot = opts.memoryRoot ?? resolveMemoryRoot(opts.cwd);\n // What gets INDEXED and where the DATABASE lives are two decisions, and they diverge on\n // purpose. The corpus is the configured root; the database stays in the project store, because\n // `memory.directory` may name the directory the Claude Code CLI manages and that CLI has no\n // index format (`docs/memory-decisions.md` § 1). Collapsing them writes a binary the partner\n // does not understand into a directory it owns.\n const filePath = opts.filePath ?? defaultIndexPath(projectMemoryDir(opts.cwd));\n const db = await openMemoryDb({ filePath });\n const manager = new IndexManager(memoryRoot, db, opts.embedding);\n if (opts.embedding !== undefined) await manager.initVectorBackend(opts.embedding);\n return manager;\n }\n\n private async initVectorBackend(runtime: EmbeddingRuntime): Promise<void> {\n await loadSqliteVecExtension(this.db);\n const currentIdentity = {\n providerId: runtime.id,\n model: runtime.model,\n dimension: runtime.dimension,\n };\n const persisted = readEmbeddingIdentity(this.db);\n if (persisted !== undefined && !identityMatches(persisted, currentIdentity)) {\n // EC-1: dimension/model/provider changed — drop the vector index and\n // force a full re-embed on next sync.\n dropVectorIndex(this.db);\n }\n createVectorIndex(this.db, runtime.dimension);\n writeEmbeddingIdentity(this.db, currentIdentity);\n this.vectorReady = true;\n }\n\n /** Walk the memory corpus + (re)index changed files. */\n async sync(): Promise<{\n filesScanned: number;\n filesUpdated: number;\n chunksWritten: number;\n chunksEmbedded: number;\n }> {\n const files = await collectMarkdownFiles(this.memoryRoot);\n let filesUpdated = 0;\n let chunksWritten = 0;\n const existingByPath = this.loadFilesIndex();\n for (const entry of files) {\n const raw = await readFile(entry.absolutePath, \"utf8\");\n const hash = sha256(raw);\n const existing = existingByPath.get(entry.absolutePath);\n if (existing !== undefined && existing.hash === hash) continue;\n const stats = await stat(entry.absolutePath);\n const fileId = this.upsertFile(\n entry.absolutePath,\n entry.relPath,\n hash,\n stats.mtimeMs,\n entry.source,\n );\n this.deleteChunksForFile(fileId);\n const chunks = chunkMarkdown(raw);\n for (const chunk of chunks) {\n this.insertChunk(fileId, chunk.startLine, chunk.endLine, chunk.text, chunk.hash);\n }\n filesUpdated += 1;\n chunksWritten += chunks.length;\n }\n let chunksEmbedded = 0;\n if (this.vectorReady && this.embedding !== undefined) {\n chunksEmbedded = await embedMissingChunks({ db: this.db, runtime: this.embedding });\n }\n this.lastSyncMs = Date.now();\n return { filesScanned: files.length, filesUpdated, chunksWritten, chunksEmbedded };\n }\n\n async search(query: string, options: SearchOptions = {}): Promise<MemorySearchHit[]> {\n if (query.trim().length === 0) return [];\n const { maxResults, minScore } = parseSearchOptions(options);\n const textHits = this.ftsSearch(query, maxResults * 2);\n const vectorHitsById = await this.vectorSearchById(query, maxResults * 2);\n const combined = this.combineHybridScores(textHits, vectorHitsById, options);\n return combined\n .filter((h) => h.score >= minScore)\n .filter((h) => options.sources === undefined || options.sources.includes(h.source))\n .slice(0, maxResults);\n }\n\n status(): IndexStatus {\n const files = this.db.prepare(\"SELECT COUNT(*) as n FROM files\").get() ?? { n: 0 };\n const chunks = this.db.prepare(\"SELECT COUNT(*) as n FROM chunks\").get() ?? { n: 0 };\n const status: IndexStatus = {\n backend: this.vectorReady ? \"hybrid\" : \"fts-only\",\n filesIndexed: Number(files.n ?? 0),\n chunksIndexed: Number(chunks.n ?? 0),\n };\n if (this.lastSyncMs !== undefined) status.lastSyncMs = this.lastSyncMs;\n return status;\n }\n\n // ───── search internals ──────────────────────────────────────────────\n\n private ftsSearch(query: string, limit: number): Array<MemorySearchHit & { chunkId: number }> {\n // EC-3: short-circuit when sanitizer reduces input to empty string.\n // Calling `MATCH ''` would error inside FTS5 on some SQLite versions.\n const sanitized = sanitizeFts5Query(query);\n if (sanitized.length === 0) return [];\n const stmt = this.db.prepare(\n `SELECT chunks.id as id, files.rel_path as rel_path, files.source as source,\n chunks.start_line as start_line, chunks.end_line as end_line,\n chunks.text as text, bm25(chunks_fts) as bm25_score\n FROM chunks_fts\n JOIN chunks ON chunks_fts.rowid = chunks.id\n JOIN files ON chunks.file_id = files.id\n WHERE chunks_fts MATCH ?\n ORDER BY bm25_score\n LIMIT ?`,\n );\n let rows: Array<Record<string, unknown>> = [];\n try {\n rows = stmt.all(sanitized, limit);\n } catch {\n // T4.8 — CJK fallback: FTS5's default tokenizer chokes on CJK\n // characters (no word boundaries). Instead of returning empty,\n // fall back to a LIKE search which handles CJK correctly (slower\n // but correct). ADR D64 documents the trigram-routing deferral.\n return this.likeSearchFallback(query, limit);\n }\n return rows.map((row) => {\n const bm25 = Number(row.bm25_score ?? 0);\n const textScore = bm25 < 0 ? 1 / (1 + Math.abs(bm25)) : 1 / (1 + bm25);\n const startLine = Number(row.start_line ?? 0);\n const endLine = Number(row.end_line ?? 0);\n const path = String(row.rel_path);\n return {\n path,\n startLine,\n endLine,\n score: textScore,\n textScore,\n snippet: truncateSnippet(String(row.text ?? \"\")),\n source: String(row.source) as \"memory\" | \"sessions\" | \"wiki\",\n citation: `${path}:${startLine}-${endLine}`,\n // sneak the chunk id through for the hybrid join below\n // (cast away later)\n chunkId: Number(row.id),\n } as MemorySearchHit & { chunkId: number };\n });\n }\n\n /**\n * T4.8 — LIKE-based fallback for CJK and other scripts that FTS5's\n * default tokenizer cannot segment. Slower than FTS5 (full table scan)\n * but correct for any Unicode input. Returns the same shape as\n * `ftsSearch` so callers are unaware of the fallback.\n */\n private likeSearchFallback(\n query: string,\n limit: number,\n ): Array<MemorySearchHit & { chunkId: number }> {\n const pattern = escapeLikePattern(query);\n const stmt = this.db.prepare(\n `SELECT chunks.id as id, files.rel_path as rel_path, files.source as source,\n chunks.start_line as start_line, chunks.end_line as end_line,\n chunks.text as text\n FROM chunks\n JOIN files ON chunks.file_id = files.id\n WHERE chunks.text LIKE ? ESCAPE '\\\\'\n LIMIT ?`,\n );\n const rows = stmt.all(pattern, limit) as Array<Record<string, unknown>>;\n return rows.map((row) => {\n const path = String(row.rel_path ?? \"\");\n const startLine = Number(row.start_line ?? 0);\n const endLine = Number(row.end_line ?? 0);\n return {\n path,\n startLine,\n endLine,\n score: 0.5, // LIKE has no relevance score — use a neutral midpoint\n textScore: 0.5,\n snippet: truncateSnippet(String(row.text ?? \"\")),\n source: String(row.source) as \"memory\" | \"sessions\" | \"wiki\",\n citation: `${path}:${startLine}-${endLine}`,\n chunkId: Number(row.id),\n } as MemorySearchHit & { chunkId: number };\n });\n }\n\n private async vectorSearchById(\n query: string,\n limit: number,\n ): Promise<Map<number, { vectorScore: number; snippet?: string }>> {\n if (!this.vectorReady || this.embedding === undefined) return new Map();\n // T4.1 — query-vector LRU cache. The embed call is the p99 hottest\n // path (1.5-3s per hit). Cache by sha256(query) so repeated queries\n // skip the HTTP round-trip entirely. The embedding cache (T4.4\n // globalEmbeddingCache) catches text-level dedup; this catches the\n // query-level search-result dedup on top.\n const cacheKey = createHash(\"sha256\").update(query).digest(\"hex\");\n const cached = queryVectorCache.get(cacheKey);\n const queryVec = cached ?? (await this.embedding.embed([query]))[0];\n if (queryVec === undefined) return new Map();\n if (cached === undefined) queryVectorCache.set(cacheKey, queryVec);\n const rows = vectorSearch(this.db, queryVec, limit);\n // sqlite-vec distance: lower = closer. Normalize to 0..1 with higher = better.\n const out = new Map<number, { vectorScore: number }>();\n for (const row of rows) {\n const score = 1 / (1 + Math.max(0, row.distance));\n out.set(row.chunk_id, { vectorScore: score });\n }\n return out;\n }\n\n private combineHybridScores(\n textHits: Array<MemorySearchHit & { chunkId: number }>,\n vectorHitsById: Map<number, { vectorScore: number }>,\n options: SearchOptions,\n ): MemorySearchHit[] {\n const weights = resolveWeights(options);\n const merged = this.mergeHits(textHits, vectorHitsById);\n const combined = [...merged.values()].map((hit) =>\n blendScores(hit, vectorHitsById.get(hit.chunkId)?.vectorScore ?? 0, weights),\n );\n return combined.sort((a, b) => b.score - a.score);\n }\n\n private mergeHits(\n textHits: Array<MemorySearchHit & { chunkId: number }>,\n vectorHitsById: Map<number, { vectorScore: number }>,\n ): Map<number, MemorySearchHit & { chunkId: number }> {\n const merged = new Map<number, MemorySearchHit & { chunkId: number }>();\n for (const hit of textHits) merged.set(hit.chunkId, hit);\n const missingIds = [...vectorHitsById.keys()].filter((id) => !merged.has(id));\n if (missingIds.length > 0) {\n for (const hit of this.fetchChunksByIds(missingIds)) {\n merged.set(hit.chunkId, { ...hit, score: 0, textScore: 0 });\n }\n }\n return merged;\n }\n\n private fetchChunksByIds(\n ids: ReadonlyArray<number>,\n ): Array<MemorySearchHit & { chunkId: number }> {\n if (ids.length === 0) return [];\n const placeholders = ids.map(() => \"?\").join(\",\");\n const rows = this.db\n .prepare(\n `SELECT chunks.id as id, files.rel_path as rel_path, files.source as source,\n chunks.start_line as start_line, chunks.end_line as end_line,\n chunks.text as text\n FROM chunks JOIN files ON chunks.file_id = files.id\n WHERE chunks.id IN (${placeholders})`,\n )\n .all(...ids);\n return rows.map((row) => {\n const startLine = Number(row.start_line ?? 0);\n const endLine = Number(row.end_line ?? 0);\n const path = String(row.rel_path);\n return {\n chunkId: Number(row.id),\n path,\n startLine,\n endLine,\n score: 0,\n textScore: 0,\n snippet: truncateSnippet(String(row.text ?? \"\")),\n source: String(row.source) as \"memory\" | \"sessions\" | \"wiki\",\n citation: `${path}:${startLine}-${endLine}`,\n };\n });\n }\n\n // ───── persistence helpers ─────────────────────────────────────────\n\n private loadFilesIndex(): Map<string, { id: number; hash: string }> {\n const rows = this.db.prepare(\"SELECT id, path, hash FROM files\").all() as Array<{\n id: number;\n path: string;\n hash: string;\n }>;\n return new Map(rows.map((row) => [row.path, { id: row.id, hash: row.hash }]));\n }\n\n private upsertFile(\n absPath: string,\n relPath: string,\n hash: string,\n mtimeMs: number,\n source: \"memory\" | \"wiki\" | \"sessions\" = \"memory\",\n ): number {\n const stmt = this.db.prepare(\n `INSERT INTO files (path, rel_path, mtime, hash, source) VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(path) DO UPDATE SET hash = excluded.hash, mtime = excluded.mtime, source = excluded.source\n RETURNING id`,\n );\n const row = stmt.get(absPath, relPath, Math.floor(mtimeMs), hash, source) as { id: number };\n return row.id;\n }\n\n private deleteChunksForFile(fileId: number): void {\n this.db.prepare(\"DELETE FROM chunks WHERE file_id = ?\").run(fileId);\n }\n\n private insertChunk(\n fileId: number,\n startLine: number,\n endLine: number,\n text: string,\n hash: string,\n ): void {\n this.db\n .prepare(\n \"INSERT INTO chunks (file_id, start_line, end_line, text, hash) VALUES (?, ?, ?, ?, ?)\",\n )\n .run(fileId, startLine, endLine, text, hash);\n }\n\n close(): void {\n this.db.close();\n }\n}\n\n// Replaced by `sanitizeFts5Query` from `internal/persistence/fts5-sanitize.ts`\n// (T5.2, ADR D64). The new sanitizer is the 6-step port of Hermes'\n// `_sanitize_fts5_query` and handles hyphens/dots/underscores correctly\n// without quoting every token.\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/memory/escape-like-pattern.ts","../src/internal/memory/memory-index.ts","../src/internal/memory/lance-memory-adapter.ts","../src/internal/memory/index-manager-dispatch.ts","../src/internal/memory/sqlite-vec-loader.ts","../src/internal/memory/storage/chunk-markdown.ts","../src/internal/memory/vec-index.ts","../src/internal/memory/index-manager.ts"],"names":["ConfigurationError","LanceIndex","createHash","LruEmbeddingCache","resolveMemoryRoot","defaultIndexPath","projectMemoryDir","openMemoryDb","collectMarkdownFiles","readFile","sha256","stat","sanitizeFts5Query","truncateSnippet","resolveWeights","blendScores"],"mappings":"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","file":"chunk-VLVVJLDH.cjs","sourcesContent":["/**\n * Escapes a user query for a SQL `LIKE ... ESCAPE '\\'` clause.\n *\n * The order of the three replacements is the whole correctness argument, so it is its own\n * function rather than a chain inline at the call site.\n *\n * The previous version escaped `%` and `_` but not the escape character itself, which is the\n * defect CodeQL reports as `js/incomplete-sanitization` (alerts #14, #15). Two things went wrong,\n * and the second is the one that matters:\n *\n * \"back\\slash\" -> \"%back\\slash%\" the `\\s` is an escape of `s`, which LIKE does not define\n * \"x\\%y\" -> \"%x\\\\%y%\" the inserted `\\` is consumed escaping the user's `\\`,\n * leaving `%` UNESCAPED — a wildcard the caller did not\n * write, matching anything between `x\\` and `y`\n *\n * The second is wildcard injection: a search for a literal string silently becomes a scan. In a\n * memory index that is both a wrong answer and a way to pull back rows the query never asked for.\n *\n * Escaping the backslash FIRST is what fixes it — afterwards every `\\` in the string is one this\n * function put there, so the later replacements cannot collide with a user-supplied one.\n */\nexport function escapeLikePattern(query: string): string {\n return `%${query.replace(/\\\\/g, \"\\\\\\\\\").replace(/%/g, \"\\\\%\").replace(/_/g, \"\\\\_\")}%`;\n}\n","/**\n * Common `MemoryIndex` interface shared between the SQLite-backed\n * `IndexManager` (default) and the Lance-backed adapter (ADR D43, shipped\n * v1.4.0 via lancedb-backend-ship-v1-1 plan).\n *\n * Consumers (`local-agent-memory.ts`, `active-memory.ts`, `tools.ts`,\n * `runActiveMemory`) only ever call `sync()`, `search()`, `status()`,\n * `close()` — the union of those four methods is the portable surface.\n *\n * Why a separate file (vs declaring inline in `index-manager.ts`)? D43\n * promised \"extract an abstract `MemoryIndex` interface in\n * `internal/memory/index-interface.ts`\". Keeping the contract physically\n * separated from one of its implementations preserves OCP — future\n * backends (Qdrant, PGVector) can land without touching IndexManager.\n *\n * @internal\n */\n\nimport type { IndexStatus, MemorySearchHit, SearchOptions } from \"./index-manager-contract.js\";\n\n// Re-export consumer-facing shapes for stable internal import paths.\nexport type { IndexStatus, MemorySearchHit, SearchOptions };\n\nexport interface SyncResult {\n filesScanned: number;\n filesUpdated: number;\n chunksWritten: number;\n chunksEmbedded: number;\n}\n\n/**\n * Common search-options parser used by both `IndexManager.search` and\n * `LanceMemoryAdapter.search`. Returns the normalized cap + minimum-score\n * floor — eliminates jscpd duplication while keeping per-backend search\n * logic distinct.\n */\nexport function parseSearchOptions(options: SearchOptions = {}): {\n maxResults: number;\n minScore: number;\n} {\n return {\n maxResults: Math.max(1, options.maxResults ?? 10),\n minScore: options.minScore ?? 0,\n };\n}\n\nexport interface MemoryIndex {\n /**\n * Walk the memory corpus + reindex changed files. Lance backend has no\n * markdown corpus to walk — its adapter returns zero counts (no-op) and\n * relies on explicit `addFact` calls instead.\n */\n sync(): Promise<SyncResult>;\n\n /**\n * Semantic + textual search over the indexed corpus. Both backends\n * return the same `MemorySearchHit[]` shape; Lance leaves `textScore`\n * undefined (vector-only — no FTS5 layer).\n */\n search(query: string, options?: SearchOptions): Promise<MemorySearchHit[]>;\n\n /** Snapshot of the index health (backend type + counts). */\n status(): IndexStatus;\n\n /** Release native handles. Idempotent. */\n close(): Promise<void> | void;\n}\n","/**\n * `LanceMemoryAdapter` — wraps `LanceIndex` to expose the common\n * `MemoryIndex` interface (sync/search/status/close) so consumers of\n * `IndexManager.open({ backend: \"lance\" })` get a drop-in replacement\n * for the SQLite-backed `IndexManager`.\n *\n * Semantic deltas vs SQLite (documented so callers know what to expect):\n *\n * - `sync()` is a NO-OP. Lance is a pure vector store — there is no\n * markdown corpus to crawl. Returns zero counts. Consumers writing\n * facts use `LanceIndex.addFacts` directly (exposed via the index\n * object returned to advanced callers).\n * - `search()` performs vector-only retrieval. `MemorySearchHit.textScore`\n * is undefined (no FTS5 layer); `vectorScore === score`.\n * - `status()` reports `backend: \"hybrid\"` only when an embedding runtime\n * is wired (always the case for Lance — embedding is required at open).\n * `chunksIndexed` reflects total Lance row count; `filesIndexed` is 0\n * because Lance does not track file provenance per-row.\n *\n * Ships with the lancedb-backend-ship-v1-1 plan (close D12, supersede via\n * D43). v1.4.0 of `@theokit/sdk`.\n *\n * @internal\n */\n\nimport type { IndexStatus, MemorySearchHit, SearchOptions } from \"./index-manager-contract.js\";\nimport type { LanceIndex } from \"./lance-index.js\";\nimport { type MemoryIndex, parseSearchOptions, type SyncResult } from \"./memory-index.js\";\n\n/**\n * Default namespace used when consumers call `search()` without specifying\n * one. The SQLite `IndexManager` does not surface namespace in its public\n * `search()` signature either — both backends therefore behave consistently\n * under the \"single-workspace, single-namespace\" assumption that v1.4 ships.\n *\n * v1.5 candidate: surface `namespace` in `SearchOptions` (additive — no\n * breaking change) so multi-tenant Lance consumers can scope queries.\n */\nconst DEFAULT_NAMESPACE = \"default\";\n\n/** Empty sync result — Lance has no corpus to walk. */\nconst EMPTY_SYNC_RESULT: SyncResult = Object.freeze({\n filesScanned: 0,\n filesUpdated: 0,\n chunksWritten: 0,\n chunksEmbedded: 0,\n});\n\nexport class LanceMemoryAdapter implements MemoryIndex {\n constructor(private readonly inner: LanceIndex) {}\n\n /**\n * No-op for Lance — see file header. Returns zero counts so callers'\n * existing logging (`filesScanned: X`) does not break.\n */\n async sync(): Promise<SyncResult> {\n return EMPTY_SYNC_RESULT;\n }\n\n // jscpd:ignore-start — search signature + early-out is idiomatic\n // overlap with IndexManager.search; further factoring would hurt\n // readability (the bodies diverge sharply right after).\n async search(query: string, options: SearchOptions = {}): Promise<MemorySearchHit[]> {\n if (query.trim().length === 0) return [];\n const { maxResults, minScore } = parseSearchOptions(options);\n // jscpd:ignore-end\n const lanceHits = await this.inner.search(query, {\n namespace: DEFAULT_NAMESPACE,\n limit: maxResults * 2,\n ...(options.sources !== undefined ? { sources: options.sources } : {}),\n });\n return lanceHits\n .filter((h) => h.score >= minScore)\n .slice(0, maxResults)\n .map((h) => translateLanceHit(h, query));\n }\n\n status(): IndexStatus {\n // chunksIndexed via a synchronous best-effort — Lance API is async so\n // we surface zero here and document that consumers needing exact counts\n // should call `inner.countFacts()` directly.\n return {\n backend: \"hybrid\",\n filesIndexed: 0,\n chunksIndexed: 0,\n };\n }\n\n async close(): Promise<void> {\n await this.inner.close();\n }\n\n /**\n * Escape hatch for advanced callers (migration tool, benchmark script)\n * that need direct access to addFacts/countFacts/removeFacts.\n */\n unwrap(): LanceIndex {\n return this.inner;\n }\n}\n\n/**\n * Translate `LanceSearchHit` to `MemorySearchHit`. Field mapping:\n *\n * - `id` → `path` (Lance has no file-system provenance; use opaque id)\n * - `text` → `snippet` (truncated to 200 chars matching IndexManager convention)\n * - `score` → combined (0.7 × vectorScore + 0.3 × textScore)\n * - `vectorScore` → from Lance's distance metric\n * - `textScore` → T4.5 client-side term-overlap ratio (removes ADR D43 vector-only caveat)\n * - `source` → `source`\n * - synthetic `startLine: 0, endLine: 0` (Lance has no line info)\n * - synthetic `citation: id` (no path:line citation available)\n */\nfunction translateLanceHit(\n hit: { id: string; text: string; source: \"memory\" | \"sessions\" | \"wiki\"; score: number },\n query?: string,\n): MemorySearchHit {\n const textScore = query !== undefined ? computeTermOverlapScore(query, hit.text) : 0;\n const vectorScore = hit.score;\n // Hybrid combination: 70% vector (semantic) + 30% text (lexical).\n const combined = 0.7 * vectorScore + 0.3 * textScore;\n return {\n path: hit.id,\n startLine: 0,\n endLine: 0,\n score: combined,\n textScore,\n vectorScore,\n snippet: hit.text.slice(0, 200),\n source: hit.source,\n citation: hit.id,\n };\n}\n\n/**\n * T4.5 — Client-side term-overlap score for Lance hybrid search.\n * Counts what fraction of query terms appear in the text (case-insensitive).\n * Simple but effective for re-ranking vector hits by lexical relevance.\n * Returns 0..1 where 1 = all query terms present.\n */\nfunction computeTermOverlapScore(query: string, text: string): number {\n const queryTerms = query\n .toLowerCase()\n .split(/\\s+/)\n .filter((t) => t.length > 1);\n if (queryTerms.length === 0) return 0;\n const textLower = text.toLowerCase();\n const matched = queryTerms.filter((term) => textLower.includes(term)).length;\n return matched / queryTerms.length;\n}\n","/**\n * Dispatch helpers for `IndexManager.open`. Extracted to keep\n * `index-manager.ts` under the G8 400-LoC budget (lancedb-backend-ship-v1-1).\n *\n * @internal\n */\n\nimport { ConfigurationError } from \"../../errors.js\";\nimport type { MemoryBackend, OpenIndexOptions } from \"./index-manager-contract.js\";\nimport { LanceIndex } from \"./lance-index.js\";\nimport { LanceMemoryAdapter } from \"./lance-memory-adapter.js\";\nimport type { MemoryIndex } from \"./memory-index.js\";\n\n/** Valid backend identifiers — runtime guard against TS-narrowing escapes (EC-1). */\nexport const VALID_BACKENDS: readonly MemoryBackend[] = [\"sqlite-vec\", \"lance\"];\n\n/**\n * EC-1: runtime guard for `opts.backend`. TS union is compile-time only;\n * consumers passing JS `as any` typos must hit a typed error, not silent\n * SQLite fallback.\n */\nexport function assertValidBackend(backend: string): asserts backend is MemoryBackend {\n if (!VALID_BACKENDS.includes(backend as MemoryBackend)) {\n throw new ConfigurationError(\n `Invalid memory backend \"${backend}\". Valid values: ${VALID_BACKENDS.join(\", \")}.`,\n { code: \"invalid_memory_backend\" },\n );\n }\n}\n\n/**\n * Lance-path open. Throws `lance_requires_embedding` when no embedding\n * runtime is provided (Lance is vector-only — no FTS fallback).\n * Surfaces `lance_backend_unavailable` from LanceIndex.open when peer\n * dep is absent.\n */\nexport async function openLanceIndex(opts: OpenIndexOptions): Promise<MemoryIndex> {\n if (opts.embedding === undefined) {\n throw new ConfigurationError(\n \"Lance backend requires an embedding runtime. Pass `embedding: { provider, model, apiKey }` in Memory.create options (or omit `backend` to use SQLite default).\",\n { code: \"lance_requires_embedding\" },\n );\n }\n const lance = await LanceIndex.open({\n cwd: opts.cwd,\n embedding: opts.embedding,\n ...(opts.filePath !== undefined ? { storagePath: opts.filePath } : {}),\n });\n return new LanceMemoryAdapter(lance);\n}\n","import { ConfigurationError } from \"../../errors.js\";\nimport type { MemoryDb } from \"./index-db.js\";\n\n/**\n * Load the `sqlite-vec` extension into an opened SQLite connection.\n *\n * Wraps the native `load(db)` call from the `sqlite-vec` npm package with a\n * typed error path (EC-8 of the edge-case review) so callers see a\n * `sqlite_vec_unavailable` ConfigurationError instead of a raw native error.\n *\n * @internal\n */\nexport async function loadSqliteVecExtension(db: MemoryDb): Promise<void> {\n try {\n const mod = await import(\"sqlite-vec\");\n const loadFn = (mod as { load?: (db: unknown) => void }).load;\n if (typeof loadFn !== \"function\") {\n throw new Error(\"sqlite-vec module exposes no `load` export\");\n }\n loadFn(db);\n } catch (cause) {\n const message = cause instanceof Error ? cause.message : String(cause);\n throw new ConfigurationError(\n `sqlite-vec extension unavailable. Install \\`sqlite-vec\\` and ensure the native binary matches your Node + OS. Cause: ${message}`,\n { code: \"sqlite_vec_unavailable\", cause },\n );\n }\n}\n","import { createHash } from \"node:crypto\";\n\nimport type { MemoryChunk } from \"../types.js\";\n\n/**\n * Split a markdown document into semantically meaningful chunks (ADR D1 of\n * memory-system-peer-project-parity).\n *\n * Algorithm:\n * 1. Walk lines tracking the current heading (latest `^#+ ` line).\n * 2. Split chunks at the next heading boundary AND on blank-line paragraph\n * boundaries.\n * 3. If a single paragraph exceeds `maxChars`, split it at the nearest\n * whitespace ≤ maxChars (word-aligned per edge-case review EC-6) —\n * never mid-word.\n *\n * Mirrors peer-project's `chunkMarkdown` from\n * `packages/memory-host-sdk/src/host/chunk-markdown.ts`.\n *\n * @internal\n */\n\nexport interface ChunkMarkdownOptions {\n /** Maximum chars per chunk. Default 800. */\n maxChars?: number;\n /** Minimum chars per chunk (avoids splintering tiny lines). Default 80. */\n minChars?: number;\n}\n\nconst HEADING_RE = /^(#{1,6})\\s+(.+?)\\s*$/;\n\ninterface ChunkAccumulator {\n chunks: MemoryChunk[];\n lines: string[];\n start: number;\n heading: string | undefined;\n}\n\nexport function chunkMarkdown(text: string, options: ChunkMarkdownOptions = {}): MemoryChunk[] {\n const maxChars = options.maxChars ?? 800;\n if (text.length === 0) return [];\n const lines = text.split(\"\\n\");\n const acc: ChunkAccumulator = { chunks: [], lines: [], start: 1, heading: undefined };\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i] ?? \"\";\n const lineNumber = i + 1;\n processLine(acc, line, lineNumber, maxChars);\n }\n flushAccumulator(acc, lines.length, maxChars);\n return acc.chunks;\n}\n\nfunction processLine(\n acc: ChunkAccumulator,\n line: string,\n lineNumber: number,\n maxChars: number,\n): void {\n const headingMatch = HEADING_RE.exec(line);\n const isBlank = line.trim().length === 0;\n if (headingMatch !== null && acc.lines.length > 0) {\n flushAccumulator(acc, lineNumber - 1, maxChars);\n }\n if (headingMatch !== null) acc.heading = headingMatch[2];\n acc.lines.push(line);\n if (isBlank && acc.lines.length > 1) {\n const joined = acc.lines.join(\"\\n\");\n if (joined.trim().length > 0) flushAccumulator(acc, lineNumber, maxChars);\n }\n}\n\nfunction flushAccumulator(acc: ChunkAccumulator, endLineExclusive: number, maxChars: number): void {\n if (acc.lines.length === 0) return;\n const chunkText = acc.lines.join(\"\\n\");\n if (chunkText.trim().length === 0) {\n acc.lines = [];\n acc.start = endLineExclusive + 1;\n return;\n }\n if (chunkText.length > maxChars) {\n pushOversizedSlices(acc.chunks, chunkText, acc.start, acc.heading, maxChars);\n } else {\n acc.chunks.push(buildChunk(chunkText, acc.start, endLineExclusive, acc.heading));\n }\n acc.lines = [];\n acc.start = endLineExclusive + 1;\n}\n\nfunction buildChunk(\n text: string,\n startLine: number,\n endLine: number,\n heading: string | undefined,\n): MemoryChunk {\n return {\n startLine,\n endLine,\n text,\n hash: createHash(\"sha256\").update(text).digest(\"hex\"),\n ...(heading !== undefined ? { heading } : {}),\n };\n}\n\nfunction pushOversizedSlices(\n chunks: MemoryChunk[],\n text: string,\n startLine: number,\n heading: string | undefined,\n maxChars: number,\n): void {\n let remaining = text;\n let lineCursor = startLine;\n while (remaining.length > maxChars) {\n const splitAt = findWordBoundarySplit(remaining, maxChars);\n const slice = remaining.slice(0, splitAt);\n const sliceLines = slice.split(\"\\n\").length;\n chunks.push(buildChunk(slice, lineCursor, lineCursor + sliceLines - 1, heading));\n remaining = remaining.slice(splitAt).replace(/^\\s+/, \"\");\n lineCursor += sliceLines - 1;\n }\n if (remaining.length > 0) {\n const sliceLines = remaining.split(\"\\n\").length;\n chunks.push(buildChunk(remaining, lineCursor, lineCursor + sliceLines - 1, heading));\n }\n}\n\n/**\n * Find a split point ≤ maxChars that lands on a whitespace boundary so we\n * don't slice a word in half. Falls back to maxChars if no whitespace is\n * within range (very rare — a single token > maxChars).\n */\nfunction findWordBoundarySplit(text: string, maxChars: number): number {\n if (text.length <= maxChars) return text.length;\n // Walk backward from maxChars looking for whitespace.\n for (let i = maxChars; i > Math.max(0, maxChars - 200); i--) {\n if (/\\s/.test(text[i] ?? \"x\")) return i;\n }\n // No whitespace within 200 chars of the cap — accept a hard split.\n return maxChars;\n}\n","import type { EmbeddingRuntime } from \"./embedding-adapter.js\";\nimport type { MemoryDb } from \"./index-db.js\";\n\n/**\n * Vector index helpers (ADR D2 + D4 of memory-system-peer-project-parity).\n *\n * Embeddings live in `embeddings(chunk_id, vec)` — a `vec0` virtual table\n * provided by the sqlite-vec extension. Embedding identity (providerId +\n * model + dimension) lives in the `meta` table; mismatches force a full\n * re-embed sweep (EC-1).\n *\n * @internal\n */\n\nexport const META_KEY_PROVIDER_ID = \"embedding.providerId\";\nexport const META_KEY_MODEL = \"embedding.model\";\nexport const META_KEY_DIMENSION = \"embedding.dimension\";\n\nexport interface EmbeddingIdentity {\n providerId: string;\n model: string;\n dimension: number;\n}\n\nexport function readEmbeddingIdentity(db: MemoryDb): EmbeddingIdentity | undefined {\n const get = (key: string): string | undefined => {\n const row = db.prepare(\"SELECT value FROM meta WHERE key = ?\").get(key);\n return row !== undefined ? String(row.value) : undefined;\n };\n const providerId = get(META_KEY_PROVIDER_ID);\n const model = get(META_KEY_MODEL);\n const dimRaw = get(META_KEY_DIMENSION);\n if (providerId === undefined || model === undefined || dimRaw === undefined) return undefined;\n const dimension = Number(dimRaw);\n if (!Number.isFinite(dimension) || dimension <= 0) return undefined;\n return { providerId, model, dimension };\n}\n\nexport function writeEmbeddingIdentity(db: MemoryDb, identity: EmbeddingIdentity): void {\n const stmt = db.prepare(\n \"INSERT INTO meta (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value\",\n );\n stmt.run(META_KEY_PROVIDER_ID, identity.providerId);\n stmt.run(META_KEY_MODEL, identity.model);\n stmt.run(META_KEY_DIMENSION, String(identity.dimension));\n}\n\nexport function identityMatches(a: EmbeddingIdentity, b: EmbeddingIdentity): boolean {\n return a.providerId === b.providerId && a.model === b.model && a.dimension === b.dimension;\n}\n\nexport function dropVectorIndex(db: MemoryDb): void {\n db.exec(\"DROP TABLE IF EXISTS embeddings\");\n}\n\nexport function createVectorIndex(db: MemoryDb, dimension: number): void {\n db.exec(`CREATE VIRTUAL TABLE IF NOT EXISTS embeddings USING vec0(\n chunk_id INTEGER PRIMARY KEY,\n vec FLOAT[${dimension}]\n )`);\n}\n\n/** Pack a Float32Array into a Buffer suitable for sqlite-vec BLOB binding. */\nexport function packVector(vec: ReadonlyArray<number>): Buffer {\n const f32 = new Float32Array(vec.length);\n for (let i = 0; i < vec.length; i++) f32[i] = vec[i] ?? 0;\n return Buffer.from(f32.buffer);\n}\n\nexport function upsertEmbedding(db: MemoryDb, chunkId: number, vec: ReadonlyArray<number>): void {\n // sqlite-vec vec0 virtual tables don't support UPSERT — emulate via\n // DELETE-then-INSERT. vec0 REJECTS JS Number for chunk_id columns; it\n // requires BigInt binding. Verified via repro against vec0 v0.1.9.\n const id = BigInt(chunkId);\n db.prepare(\"DELETE FROM embeddings WHERE chunk_id = ?\").run(id);\n db.prepare(\"INSERT INTO embeddings (chunk_id, vec) VALUES (?, ?)\").run(id, packVector(vec));\n}\n\nexport interface VectorHitRow {\n chunk_id: number;\n distance: number;\n}\n\nexport function vectorSearch(\n db: MemoryDb,\n query: ReadonlyArray<number>,\n k: number,\n): VectorHitRow[] {\n // sqlite-vec returns distance (lower = closer). Use KNN syntax. k needs\n // a BigInt-typed binding too.\n const rows = db\n .prepare(\n `SELECT chunk_id, distance FROM embeddings\n WHERE vec MATCH ? AND k = ?\n ORDER BY distance`,\n )\n .all(packVector(query), BigInt(k));\n return rows.map((row) => ({ chunk_id: Number(row.chunk_id), distance: Number(row.distance) }));\n}\n\nexport interface EmbedAllArgs {\n db: MemoryDb;\n runtime: EmbeddingRuntime;\n}\n\n/** Embed every chunk that doesn't yet have a vector. */\nexport async function embedMissingChunks(args: EmbedAllArgs): Promise<number> {\n const rows = args.db\n .prepare(\n `SELECT chunks.id as id, chunks.text as text\n FROM chunks\n LEFT JOIN embeddings ON embeddings.chunk_id = chunks.id\n WHERE embeddings.chunk_id IS NULL`,\n )\n .all();\n if (rows.length === 0) return 0;\n const normalized = rows.map((row) => ({ id: Number(row.id), text: String(row.text ?? \"\") }));\n const vectors = await args.runtime.embed(normalized.map((r) => r.text));\n for (let i = 0; i < normalized.length; i++) {\n const row = normalized[i];\n const vector = vectors[i];\n if (row === undefined || vector === undefined) continue;\n upsertEmbedding(args.db, row.id, vector);\n }\n return normalized.length;\n}\n","import { createHash } from \"node:crypto\";\nimport { readFile, stat } from \"node:fs/promises\";\nimport { sanitizeFts5Query } from \"../persistence/fts5-sanitize.js\";\nimport type { EmbeddingRuntime } from \"./embedding-adapter.js\";\nimport { LruEmbeddingCache } from \"./embedding-cache.js\";\nimport { escapeLikePattern } from \"./escape-like-pattern.js\";\nimport { defaultIndexPath, type MemoryDb, openMemoryDb } from \"./index-db.js\";\nimport { assertValidBackend, openLanceIndex } from \"./index-manager-dispatch.js\";\nimport {\n blendScores,\n collectMarkdownFiles,\n resolveWeights,\n sha256,\n truncateSnippet,\n} from \"./index-manager-helpers.js\";\nimport { type MemoryIndex, parseSearchOptions } from \"./memory-index.js\";\nimport { loadSqliteVecExtension } from \"./sqlite-vec-loader.js\";\nimport { chunkMarkdown } from \"./storage/chunk-markdown.js\";\nimport { type MemoryRoot, projectMemoryDir, resolveMemoryRoot } from \"./storage/memory-root.js\";\n\n// T4.1 — query-vector LRU cache (DR4 finding #1). Keyed by\n// sha256(query); caches the embedding vector so repeated search\n// queries skip the HTTP round-trip (p99 1.5-3s → ~0ms on hit).\n// Process-wide singleton with bounded capacity (default 2000 queries).\nconst queryVectorCache = new LruEmbeddingCache(2000);\n\nimport {\n createVectorIndex,\n dropVectorIndex,\n embedMissingChunks,\n identityMatches,\n readEmbeddingIdentity,\n vectorSearch,\n writeEmbeddingIdentity,\n} from \"./vec-index.js\";\n\n/**\n * Memory index manager (ADR D2). FTS5-only at Phase 3; vector index lands in\n * Phase 5.\n *\n * Lifecycle:\n * const idx = await IndexManager.open({ cwd });\n * await idx.sync();\n * const hits = await idx.search(\"query\");\n * idx.close();\n *\n * @internal\n */\n\n// T2.1 / ADR D433 — these types now live in `index-manager-contract.ts`\n// to break the 3-cycle memory cluster. Re-exported here for back-compat\n// with downstream importers that historically pulled from this file.\nexport type {\n IndexStatus,\n MemoryBackend,\n MemorySearchHit,\n OpenIndexOptions,\n SearchOptions,\n} from \"./index-manager-contract.js\";\n\nimport type {\n IndexStatus,\n MemorySearchHit,\n OpenIndexOptions,\n SearchOptions,\n} from \"./index-manager-contract.js\";\n\nexport class IndexManager implements MemoryIndex {\n private lastSyncMs: number | undefined;\n private vectorReady = false;\n\n private constructor(\n private readonly memoryRoot: MemoryRoot,\n private readonly db: MemoryDb,\n private readonly embedding: EmbeddingRuntime | undefined,\n ) {}\n\n /**\n * Open a memory index. Dispatches to SQLite (default) or Lance (opt-in\n * via `backend: \"lance\"`). See `openLanceInternal` for Lance-specific\n * preconditions + typed errors.\n */\n static async open(opts: OpenIndexOptions & { backend: \"lance\" }): Promise<MemoryIndex>;\n static async open(\n opts: Omit<OpenIndexOptions, \"backend\"> | (OpenIndexOptions & { backend?: \"sqlite-vec\" }),\n ): Promise<IndexManager>;\n static async open(opts: OpenIndexOptions): Promise<MemoryIndex> {\n const backend = opts.backend ?? \"sqlite-vec\";\n assertValidBackend(backend);\n if (backend === \"lance\") return await openLanceIndex(opts);\n return await IndexManager.openSqliteInternal(opts);\n }\n\n /** Internal SQLite-path open. Renamed from previous public `open`. */\n private static async openSqliteInternal(opts: OpenIndexOptions): Promise<IndexManager> {\n const memoryRoot = opts.memoryRoot ?? resolveMemoryRoot(opts.cwd);\n // What gets INDEXED and where the DATABASE lives are two decisions, and they diverge on\n // purpose. The corpus is the configured root; the database stays in the project store, because\n // `memory.directory` may name the directory the Claude Code CLI manages and that CLI has no\n // index format (`docs/memory-decisions.md` § 1). Collapsing them writes a binary the partner\n // does not understand into a directory it owns.\n const filePath = opts.filePath ?? defaultIndexPath(projectMemoryDir(opts.cwd));\n const db = await openMemoryDb({ filePath });\n const manager = new IndexManager(memoryRoot, db, opts.embedding);\n if (opts.embedding !== undefined) await manager.initVectorBackend(opts.embedding);\n return manager;\n }\n\n private async initVectorBackend(runtime: EmbeddingRuntime): Promise<void> {\n await loadSqliteVecExtension(this.db);\n const currentIdentity = {\n providerId: runtime.id,\n model: runtime.model,\n dimension: runtime.dimension,\n };\n const persisted = readEmbeddingIdentity(this.db);\n if (persisted !== undefined && !identityMatches(persisted, currentIdentity)) {\n // EC-1: dimension/model/provider changed — drop the vector index and\n // force a full re-embed on next sync.\n dropVectorIndex(this.db);\n }\n createVectorIndex(this.db, runtime.dimension);\n writeEmbeddingIdentity(this.db, currentIdentity);\n this.vectorReady = true;\n }\n\n /** Walk the memory corpus + (re)index changed files. */\n async sync(): Promise<{\n filesScanned: number;\n filesUpdated: number;\n chunksWritten: number;\n chunksEmbedded: number;\n }> {\n const files = await collectMarkdownFiles(this.memoryRoot);\n let filesUpdated = 0;\n let chunksWritten = 0;\n const existingByPath = this.loadFilesIndex();\n for (const entry of files) {\n const raw = await readFile(entry.absolutePath, \"utf8\");\n const hash = sha256(raw);\n const existing = existingByPath.get(entry.absolutePath);\n if (existing !== undefined && existing.hash === hash) continue;\n const stats = await stat(entry.absolutePath);\n const fileId = this.upsertFile(\n entry.absolutePath,\n entry.relPath,\n hash,\n stats.mtimeMs,\n entry.source,\n );\n this.deleteChunksForFile(fileId);\n const chunks = chunkMarkdown(raw);\n for (const chunk of chunks) {\n this.insertChunk(fileId, chunk.startLine, chunk.endLine, chunk.text, chunk.hash);\n }\n filesUpdated += 1;\n chunksWritten += chunks.length;\n }\n let chunksEmbedded = 0;\n if (this.vectorReady && this.embedding !== undefined) {\n chunksEmbedded = await embedMissingChunks({ db: this.db, runtime: this.embedding });\n }\n this.lastSyncMs = Date.now();\n return { filesScanned: files.length, filesUpdated, chunksWritten, chunksEmbedded };\n }\n\n async search(query: string, options: SearchOptions = {}): Promise<MemorySearchHit[]> {\n if (query.trim().length === 0) return [];\n const { maxResults, minScore } = parseSearchOptions(options);\n const textHits = this.ftsSearch(query, maxResults * 2);\n const vectorHitsById = await this.vectorSearchById(query, maxResults * 2);\n const combined = this.combineHybridScores(textHits, vectorHitsById, options);\n return combined\n .filter((h) => h.score >= minScore)\n .filter((h) => options.sources === undefined || options.sources.includes(h.source))\n .slice(0, maxResults);\n }\n\n status(): IndexStatus {\n const files = this.db.prepare(\"SELECT COUNT(*) as n FROM files\").get() ?? { n: 0 };\n const chunks = this.db.prepare(\"SELECT COUNT(*) as n FROM chunks\").get() ?? { n: 0 };\n const status: IndexStatus = {\n backend: this.vectorReady ? \"hybrid\" : \"fts-only\",\n filesIndexed: Number(files.n ?? 0),\n chunksIndexed: Number(chunks.n ?? 0),\n };\n if (this.lastSyncMs !== undefined) status.lastSyncMs = this.lastSyncMs;\n return status;\n }\n\n // ───── search internals ──────────────────────────────────────────────\n\n private ftsSearch(query: string, limit: number): Array<MemorySearchHit & { chunkId: number }> {\n // EC-3: short-circuit when sanitizer reduces input to empty string.\n // Calling `MATCH ''` would error inside FTS5 on some SQLite versions.\n const sanitized = sanitizeFts5Query(query);\n if (sanitized.length === 0) return [];\n const stmt = this.db.prepare(\n `SELECT chunks.id as id, files.rel_path as rel_path, files.source as source,\n chunks.start_line as start_line, chunks.end_line as end_line,\n chunks.text as text, bm25(chunks_fts) as bm25_score\n FROM chunks_fts\n JOIN chunks ON chunks_fts.rowid = chunks.id\n JOIN files ON chunks.file_id = files.id\n WHERE chunks_fts MATCH ?\n ORDER BY bm25_score\n LIMIT ?`,\n );\n let rows: Array<Record<string, unknown>> = [];\n try {\n rows = stmt.all(sanitized, limit);\n } catch {\n // T4.8 — CJK fallback: FTS5's default tokenizer chokes on CJK\n // characters (no word boundaries). Instead of returning empty,\n // fall back to a LIKE search which handles CJK correctly (slower\n // but correct). ADR D64 documents the trigram-routing deferral.\n return this.likeSearchFallback(query, limit);\n }\n return rows.map((row) => {\n const bm25 = Number(row.bm25_score ?? 0);\n const textScore = bm25 < 0 ? 1 / (1 + Math.abs(bm25)) : 1 / (1 + bm25);\n const startLine = Number(row.start_line ?? 0);\n const endLine = Number(row.end_line ?? 0);\n const path = String(row.rel_path);\n return {\n path,\n startLine,\n endLine,\n score: textScore,\n textScore,\n snippet: truncateSnippet(String(row.text ?? \"\")),\n source: String(row.source) as \"memory\" | \"sessions\" | \"wiki\",\n citation: `${path}:${startLine}-${endLine}`,\n // sneak the chunk id through for the hybrid join below\n // (cast away later)\n chunkId: Number(row.id),\n } as MemorySearchHit & { chunkId: number };\n });\n }\n\n /**\n * T4.8 — LIKE-based fallback for CJK and other scripts that FTS5's\n * default tokenizer cannot segment. Slower than FTS5 (full table scan)\n * but correct for any Unicode input. Returns the same shape as\n * `ftsSearch` so callers are unaware of the fallback.\n */\n private likeSearchFallback(\n query: string,\n limit: number,\n ): Array<MemorySearchHit & { chunkId: number }> {\n const pattern = escapeLikePattern(query);\n const stmt = this.db.prepare(\n `SELECT chunks.id as id, files.rel_path as rel_path, files.source as source,\n chunks.start_line as start_line, chunks.end_line as end_line,\n chunks.text as text\n FROM chunks\n JOIN files ON chunks.file_id = files.id\n WHERE chunks.text LIKE ? ESCAPE '\\\\'\n LIMIT ?`,\n );\n const rows = stmt.all(pattern, limit) as Array<Record<string, unknown>>;\n return rows.map((row) => {\n const path = String(row.rel_path ?? \"\");\n const startLine = Number(row.start_line ?? 0);\n const endLine = Number(row.end_line ?? 0);\n return {\n path,\n startLine,\n endLine,\n score: 0.5, // LIKE has no relevance score — use a neutral midpoint\n textScore: 0.5,\n snippet: truncateSnippet(String(row.text ?? \"\")),\n source: String(row.source) as \"memory\" | \"sessions\" | \"wiki\",\n citation: `${path}:${startLine}-${endLine}`,\n chunkId: Number(row.id),\n } as MemorySearchHit & { chunkId: number };\n });\n }\n\n private async vectorSearchById(\n query: string,\n limit: number,\n ): Promise<Map<number, { vectorScore: number; snippet?: string }>> {\n if (!this.vectorReady || this.embedding === undefined) return new Map();\n // T4.1 — query-vector LRU cache. The embed call is the p99 hottest\n // path (1.5-3s per hit). Cache by sha256(query) so repeated queries\n // skip the HTTP round-trip entirely. The embedding cache (T4.4\n // globalEmbeddingCache) catches text-level dedup; this catches the\n // query-level search-result dedup on top.\n const cacheKey = createHash(\"sha256\").update(query).digest(\"hex\");\n const cached = queryVectorCache.get(cacheKey);\n const queryVec = cached ?? (await this.embedding.embed([query]))[0];\n if (queryVec === undefined) return new Map();\n if (cached === undefined) queryVectorCache.set(cacheKey, queryVec);\n const rows = vectorSearch(this.db, queryVec, limit);\n // sqlite-vec distance: lower = closer. Normalize to 0..1 with higher = better.\n const out = new Map<number, { vectorScore: number }>();\n for (const row of rows) {\n const score = 1 / (1 + Math.max(0, row.distance));\n out.set(row.chunk_id, { vectorScore: score });\n }\n return out;\n }\n\n private combineHybridScores(\n textHits: Array<MemorySearchHit & { chunkId: number }>,\n vectorHitsById: Map<number, { vectorScore: number }>,\n options: SearchOptions,\n ): MemorySearchHit[] {\n const weights = resolveWeights(options);\n const merged = this.mergeHits(textHits, vectorHitsById);\n const combined = [...merged.values()].map((hit) =>\n blendScores(hit, vectorHitsById.get(hit.chunkId)?.vectorScore ?? 0, weights),\n );\n return combined.sort((a, b) => b.score - a.score);\n }\n\n private mergeHits(\n textHits: Array<MemorySearchHit & { chunkId: number }>,\n vectorHitsById: Map<number, { vectorScore: number }>,\n ): Map<number, MemorySearchHit & { chunkId: number }> {\n const merged = new Map<number, MemorySearchHit & { chunkId: number }>();\n for (const hit of textHits) merged.set(hit.chunkId, hit);\n const missingIds = [...vectorHitsById.keys()].filter((id) => !merged.has(id));\n if (missingIds.length > 0) {\n for (const hit of this.fetchChunksByIds(missingIds)) {\n merged.set(hit.chunkId, { ...hit, score: 0, textScore: 0 });\n }\n }\n return merged;\n }\n\n private fetchChunksByIds(\n ids: ReadonlyArray<number>,\n ): Array<MemorySearchHit & { chunkId: number }> {\n if (ids.length === 0) return [];\n const placeholders = ids.map(() => \"?\").join(\",\");\n const rows = this.db\n .prepare(\n `SELECT chunks.id as id, files.rel_path as rel_path, files.source as source,\n chunks.start_line as start_line, chunks.end_line as end_line,\n chunks.text as text\n FROM chunks JOIN files ON chunks.file_id = files.id\n WHERE chunks.id IN (${placeholders})`,\n )\n .all(...ids);\n return rows.map((row) => {\n const startLine = Number(row.start_line ?? 0);\n const endLine = Number(row.end_line ?? 0);\n const path = String(row.rel_path);\n return {\n chunkId: Number(row.id),\n path,\n startLine,\n endLine,\n score: 0,\n textScore: 0,\n snippet: truncateSnippet(String(row.text ?? \"\")),\n source: String(row.source) as \"memory\" | \"sessions\" | \"wiki\",\n citation: `${path}:${startLine}-${endLine}`,\n };\n });\n }\n\n // ───── persistence helpers ─────────────────────────────────────────\n\n private loadFilesIndex(): Map<string, { id: number; hash: string }> {\n const rows = this.db.prepare(\"SELECT id, path, hash FROM files\").all() as Array<{\n id: number;\n path: string;\n hash: string;\n }>;\n return new Map(rows.map((row) => [row.path, { id: row.id, hash: row.hash }]));\n }\n\n private upsertFile(\n absPath: string,\n relPath: string,\n hash: string,\n mtimeMs: number,\n source: \"memory\" | \"wiki\" | \"sessions\" = \"memory\",\n ): number {\n const stmt = this.db.prepare(\n `INSERT INTO files (path, rel_path, mtime, hash, source) VALUES (?, ?, ?, ?, ?)\n ON CONFLICT(path) DO UPDATE SET hash = excluded.hash, mtime = excluded.mtime, source = excluded.source\n RETURNING id`,\n );\n const row = stmt.get(absPath, relPath, Math.floor(mtimeMs), hash, source) as { id: number };\n return row.id;\n }\n\n private deleteChunksForFile(fileId: number): void {\n this.db.prepare(\"DELETE FROM chunks WHERE file_id = ?\").run(fileId);\n }\n\n private insertChunk(\n fileId: number,\n startLine: number,\n endLine: number,\n text: string,\n hash: string,\n ): void {\n this.db\n .prepare(\n \"INSERT INTO chunks (file_id, start_line, end_line, text, hash) VALUES (?, ?, ?, ?, ?)\",\n )\n .run(fileId, startLine, endLine, text, hash);\n }\n\n close(): void {\n this.db.close();\n }\n}\n\n// Replaced by `sanitizeFts5Query` from `internal/persistence/fts5-sanitize.ts`\n// (T5.2, ADR D64). The new sanitizer is the 6-step port of Hermes'\n// `_sanitize_fts5_query` and handles hyphens/dots/underscores correctly\n// without quoting every token.\n"]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkJJ3OVRUM_cjs = require('./chunk-JJ3OVRUM.cjs');
|
|
4
4
|
var chunk3FFAEAUJ_cjs = require('./chunk-3FFAEAUJ.cjs');
|
|
5
5
|
var chunkNINIJCHU_cjs = require('./chunk-NINIJCHU.cjs');
|
|
6
6
|
var chunk4ZHTIJNE_cjs = require('./chunk-4ZHTIJNE.cjs');
|
|
@@ -377,7 +377,7 @@ async function createCronJob(options) {
|
|
|
377
377
|
const runtime = detectRuntime(options);
|
|
378
378
|
const now = Date.now();
|
|
379
379
|
const job = {
|
|
380
|
-
id:
|
|
380
|
+
id: chunkJJ3OVRUM_cjs.generateCronId(),
|
|
381
381
|
cron: options.cron,
|
|
382
382
|
timezone,
|
|
383
383
|
enabled: options.enabled ?? true,
|
|
@@ -454,5 +454,5 @@ async function updateJobStatus(jobId, enabled) {
|
|
|
454
454
|
}
|
|
455
455
|
|
|
456
456
|
exports.Cron = Cron;
|
|
457
|
-
//# sourceMappingURL=chunk-
|
|
458
|
-
//# sourceMappingURL=chunk-
|
|
457
|
+
//# sourceMappingURL=chunk-ZWRG4NWT.cjs.map
|
|
458
|
+
//# sourceMappingURL=chunk-ZWRG4NWT.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/internal/cron/run-job.ts","../src/internal/cron/fire-handler.ts","../src/internal/cron/store.ts","../src/internal/cron/scheduler.ts","../src/internal/cron/validate.ts","../src/cron.ts"],"names":["ConfigurationError","getAgentFacade","UnknownAgentError","submit","Croner","resolveApiKey","generateCronId"],"mappings":"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","file":"chunk-Q7LPTOD6.cjs","sourcesContent":["import { ConfigurationError, UnknownAgentError } from \"../../errors.js\";\nimport type { AgentOptions } from \"../../types/agent.js\";\nimport type { CronJob } from \"../../types/cron.js\";\nimport type { Run, SDKUserMessage } from \"../../types/run.js\";\nimport type { WorkflowRun } from \"../../types/workflow.js\";\nimport { getAgentFacade } from \"../runtime/registry/agent-factory-registry.js\";\n\n/**\n * Execute a cron job. Dispatches to one of three targets:\n * - `workflow` (SE35) → `workflow.run(inputData)` on the held instance (the\n * instance carries its own `.run`, so this module never imports `workflow.ts`),\n * returning the already-terminal {@link WorkflowRun}.\n * - `agent` → an ephemeral agent per fire; `agent.send(message)` → {@link Run}.\n * - `agentId` → reuse an existing agent; `agent.send(message)` → {@link Run}.\n *\n * Used by both `Cron.run(jobId)` (manual off-schedule fire) and the scheduler's\n * default fire handler. ADR 0014.\n *\n * @internal\n */\nexport async function runCronJob(job: CronJob): Promise<Run | WorkflowRun> {\n // `Workflow.run()` resolves only on a TERMINAL run (completed/failed/suspended/\n // cancelled — the executor never returns `status: \"running\"`), so the fire\n // handler treats the returned WorkflowRun as terminal (no `.wait()`).\n if (job.workflow !== undefined) return job.workflow.run(job.inputData);\n if (job.agent !== undefined) return runWithEphemeralAgent(job.agent, requireMessage(job));\n if (job.agentId !== undefined) return runWithExistingAgent(job.agentId, requireMessage(job));\n throw new ConfigurationError(\n `Cron job ${job.id} has no target (agent, agentId, or workflow) — cannot run.`,\n { code: \"cron_no_target\" },\n );\n}\n\n/**\n * Discriminate the {@link runCronJob} union: an agent `Run` is deferred (carries\n * `.wait()`/`.cancel()`); a {@link WorkflowRun} is already terminal (no `.wait()`).\n * @internal\n */\nexport function isAgentRun(outcome: Run | WorkflowRun): outcome is Run {\n return typeof (outcome as Run).wait === \"function\";\n}\n\n/** Agent targets require a message; fail-loud if one somehow reached a fire without it. */\nfunction requireMessage(job: CronJob): string | SDKUserMessage {\n if (job.message === undefined) {\n throw new ConfigurationError(`Cron job ${job.id} is an agent target but has no message.`, {\n code: \"cron_missing_message\",\n });\n }\n return job.message;\n}\n\nasync function runWithExistingAgent(\n agentId: string,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const info = await getAgentFacade()\n .get(agentId)\n .catch(() => undefined);\n if (info === undefined) {\n throw new UnknownAgentError(\n `Cron job references agentId \"${agentId}\" but no such agent is registered. The agent may have been disposed or the process restarted without persisting the agent registry.`,\n { code: \"agent_not_registered\" },\n );\n }\n const agent = await getAgentFacade().resume(agentId);\n return agent.send(message);\n}\n\nasync function runWithEphemeralAgent(\n baseOptions: AgentOptions,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const agent = await getAgentFacade().create(baseOptions);\n return agent.send(message);\n}\n","/**\n * Default cron fire handler (extracted from `Cron.start` for testability + G8).\n *\n * Every fire registers as a Task (ADRs D363/D374) so callers observe it via\n * `Task.list` / `Task.subscribe`. SE35 (ADR 0014): the fire target may be an\n * agent (a deferred {@link Run} — abort-wire + `wait()`) OR a workflow (an\n * already-terminal {@link WorkflowRun} — no `wait()`); `isAgentRun` discriminates\n * so the handler records the correct terminal status/runId for each shape.\n *\n * @internal\n */\n\nimport type { CronJob } from \"../../types/cron.js\";\nimport { submit as taskRegistrySubmit } from \"../task/registry.js\";\nimport { isAgentRun, runCronJob } from \"./run-job.js\";\n\nexport async function fireCronJobAsTask(job: CronJob): Promise<void> {\n // The task id namespace `cron-{jobId}-{fireEpochMs}` honors D368/EC-5.\n const fireTs = Date.now();\n const taskId = `cron-${job.id}-${fireTs}`;\n try {\n await taskRegistrySubmit({\n kind: \"cron\",\n id: taskId,\n allowReservedPrefix: true,\n meta: { jobId: job.id, jobName: job.name, schedule: job.cron, firedAt: fireTs },\n work: async (ctx) => {\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) {\n // Agent target — the Run is deferred: abort-wire + await terminal.\n ctx.signal.addEventListener(\"abort\", () => void outcome.cancel().catch(() => {}), {\n once: true,\n });\n const result = await outcome.wait();\n ctx.emit({ status: result.status, runId: outcome.id });\n return { status: result.status, runId: outcome.id };\n }\n // SE35 workflow target — the WorkflowRun is ALREADY terminal (no wait()).\n ctx.emit({ status: outcome.status, runId: outcome.id });\n return { status: outcome.status, runId: outcome.id };\n },\n });\n } catch {\n // Task registry must not break cron — fall through to a direct run. No\n // double-execution: `taskRegistrySubmit` runs `work` (which calls\n // `runCronJob`) fire-and-forget, so a throw here means the SUBMIT itself\n // failed (id/registry setup) BEFORE `work` started — the job never ran, and\n // this is its first + only execution.\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) await outcome.wait();\n }\n}\n","import type { CronJob } from \"../../types/cron.js\";\n\n/**\n * Process-wide cron job store. In Phase 1 we keep all jobs in memory\n * (across local + cloud runtimes). Local-runtime persistence to\n * `.theokit/cron/jobs.json` lands when the local runtime adapter is wired.\n *\n * @internal\n */\nconst jobs = new Map<string, CronJob>();\n\n/** Snapshot of every known cron job. @internal */\nexport function listJobs(): CronJob[] {\n return Array.from(jobs.values());\n}\n\n/** Total job count across runtimes. @internal */\nexport function jobCount(): number {\n return jobs.size;\n}\n\n/** Fetch a single job by id, or `undefined` if it does not exist. @internal */\nexport function getJob(jobId: string): CronJob | undefined {\n return jobs.get(jobId);\n}\n\n/** Insert or replace a job. @internal */\nexport function upsertJob(job: CronJob): void {\n jobs.set(job.id, job);\n}\n\n/** Delete a job. Returns `true` if a job was removed. @internal */\nexport function deleteJob(jobId: string): boolean {\n return jobs.delete(jobId);\n}\n\n/** Test-only: drop every job. @internal */\nexport function clearJobs(): void {\n jobs.clear();\n}\n","import { Cron as Croner } from \"croner\";\n\nimport type { CronJob } from \"../../types/cron.js\";\nimport { listJobs, upsertJob } from \"./store.js\";\n\n/**\n * Real local cron scheduler. When `Cron.start()` is called the scheduler\n * installs a Croner timer per enabled local job; on fire the registered\n * fire handler runs the underlying agent. `Cron.stop()` tears every timer\n * down but keeps the jobs in the store.\n *\n * @internal\n */\n\nexport type CronFireHandler = (job: CronJob) => Promise<void> | void;\n\ninterface SchedulerState {\n running: boolean;\n cwd?: string;\n timers: Map<string, Croner>;\n fireHandler?: CronFireHandler;\n}\n\nconst state: SchedulerState = { running: false, timers: new Map() };\n\n/**\n * Register the callback invoked when a job fires. The runtime adapter\n * supplies a handler that actually executes the agent; fixture-mode tests\n * leave it unset so timers tick without side effects.\n *\n * @internal\n */\nexport function setCronFireHandler(handler: CronFireHandler | undefined): void {\n state.fireHandler = handler;\n}\n\n/** Activate the scheduler and install timers for every enabled local job. @internal */\nexport function startScheduler(cwd?: string): void {\n state.running = true;\n if (cwd !== undefined) state.cwd = cwd;\n for (const job of listJobs()) {\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n }\n}\n\n/** Deactivate the scheduler. Stops every timer; jobs remain in the store. @internal */\nexport function stopScheduler(): void {\n state.running = false;\n for (const timer of state.timers.values()) timer.stop();\n state.timers.clear();\n}\n\n/** Schedule a single job. No-op if the scheduler is not running. @internal */\nexport function scheduleJob(job: CronJob): void {\n if (!state.running) return;\n unscheduleJob(job.id);\n const expression = normalizeExpression(job.cron);\n const timer = new Croner(\n expression,\n { timezone: job.timezone, name: job.id, protect: true },\n () => {\n void fireJob(job.id);\n },\n );\n state.timers.set(job.id, timer);\n refreshNextRunAt(job.id, timer);\n}\n\n/** Tear down the timer for a single job. @internal */\nexport function unscheduleJob(jobId: string): boolean {\n const timer = state.timers.get(jobId);\n if (timer === undefined) return false;\n timer.stop();\n state.timers.delete(jobId);\n return true;\n}\n\n/** Snapshot of the scheduler's running flag and configured workspace. @internal */\nexport function getSchedulerState(): { running: boolean; cwd?: string } {\n const result: { running: boolean; cwd?: string } = { running: state.running };\n if (state.cwd !== undefined) result.cwd = state.cwd;\n return result;\n}\n\nasync function fireJob(jobId: string): Promise<void> {\n const fresh = listJobs().find((entry) => entry.id === jobId);\n if (fresh === undefined || fresh.enabled === false) return;\n const handler = state.fireHandler;\n upsertJob({ ...fresh, lastRunAt: Date.now() });\n if (handler === undefined) return;\n try {\n await handler(fresh);\n } catch {\n // Swallow handler errors — the scheduler must keep ticking. Real\n // surface for run failures lives on the Run.wait() result itself.\n }\n}\n\nfunction refreshNextRunAt(jobId: string, timer: Croner): void {\n const next = timer.nextRun();\n if (next === null) return;\n const existing = listJobs().find((entry) => entry.id === jobId);\n if (existing === undefined) return;\n upsertJob({ ...existing, nextRunAt: next.getTime() });\n}\n\nfunction normalizeExpression(cron: string): string {\n switch (cron) {\n case \"@hourly\":\n return \"0 * * * *\";\n case \"@daily\":\n return \"0 0 * * *\";\n case \"@weekly\":\n return \"0 0 * * 0\";\n case \"@monthly\":\n return \"0 0 1 * *\";\n case \"@yearly\":\n return \"0 0 1 1 *\";\n default:\n return cron;\n }\n}\n","import { ConfigurationError } from \"../../errors.js\";\n\n/**\n * POSIX-cron + shorthand validators used by `Cron.create()`. Throws\n * `ConfigurationError` with a stable message and code on invalid input.\n *\n * @internal\n */\n\nconst SHORTHANDS = new Set([\"@hourly\", \"@daily\", \"@weekly\", \"@monthly\", \"@yearly\"]);\n\ninterface FieldRange {\n min: number;\n max: number;\n}\n\nconst FIELD_RANGES: readonly FieldRange[] = [\n { min: 0, max: 59 }, // minute\n { min: 0, max: 23 }, // hour\n { min: 1, max: 31 }, // day-of-month\n { min: 1, max: 12 }, // month\n { min: 0, max: 6 }, // day-of-week\n];\n\n/**\n * Validate a cron expression. Accepts shorthand (`@hourly`, ..., `@yearly`)\n * or 5-field POSIX cron with star, literals, star/N step, N-M range, and\n * N,M,P list.\n *\n * @internal\n */\nexport function validateCronExpression(cron: string): void {\n if (typeof cron !== \"string\" || cron.length === 0) {\n throw new ConfigurationError(\"Invalid cron expression: empty\", {\n code: \"invalid_cron\",\n });\n }\n if (cron.startsWith(\"@\")) {\n if (!SHORTHANDS.has(cron)) {\n throw new ConfigurationError(`Invalid cron expression: unknown shorthand ${cron}`, {\n code: \"invalid_cron\",\n });\n }\n return;\n }\n\n const fields = cron.trim().split(/\\s+/);\n if (fields.length !== FIELD_RANGES.length) {\n throw new ConfigurationError(\n `Invalid cron expression: ${cron} (expected ${FIELD_RANGES.length} fields, got ${fields.length})`,\n { code: \"invalid_cron\" },\n );\n }\n for (const [index, range] of FIELD_RANGES.entries()) {\n // The length check above already established one field per range, so the lookup is total.\n // B-116: this replaces a `range === undefined` guard that no caller could reach — its single\n // caller only ran with exactly 5 fields, and FIELD_RANGES has exactly 5 entries, so the branch\n // stayed at 0 executions through 37 tests written specifically to enter it.\n const field = fields[index] as string;\n if (!isValidCronField(field, range)) {\n throw new ConfigurationError(`Invalid cron expression: ${cron} (field ${index + 1})`, {\n code: \"invalid_cron\",\n });\n }\n }\n}\n\nfunction isValidCronField(field: string, range: FieldRange): boolean {\n if (field === \"*\") return true;\n if (field.startsWith(\"*/\")) return isValidStep(field.slice(2), range);\n if (field.includes(\",\")) {\n return field.split(\",\").every((part) => isValidCronField(part, range));\n }\n if (field.includes(\"-\")) return isValidRange(field, range);\n return isValidLiteral(field, range);\n}\n\n/**\n * Digits, and nothing else. `Number.parseInt` stops at the first non-digit, so it reads `\"5abc\"` as\n * `5` and `\"0x5\"` as `0` — a numeric field parsed that way accepts garbage that happens to start\n * with a digit.\n *\n * This replaces the `String(n) === field` round-trip the literal and step validators used to carry.\n * The round-trip refused the garbage correctly but also refused `\"07\"`, because `String(7) !== \"07\"`\n * — and `isValidRange` never had it at all, so `\"1-5abc\"` was accepted while `\"5abc\"` was refused\n * (B-121). One predicate, applied to every field shape, closes both halves.\n *\n * The boundary that matters is croner 9, the scheduler this SDK actually fires jobs with. Measured\n * 2026-08-19: it ACCEPTS `\"07 * * * *\"` (next run at :07) and REFUSES `\"5abc\"`, `\"1-5abc\"`,\n * `\"1abc-5\"`, `\"0x5\"`, `\"5.9\"`, `\"+5\"` and `\"1e1\"` as \"illegal character\" (B-122). Validating\n * stricter than the engine rejects schedules that would have run; validating looser only moves the\n * failure from `Cron.create()` to fire time, where nobody is watching.\n *\n * @internal\n */\nconst DIGITS_ONLY = /^\\d+$/;\n\nfunction parseFieldNumber(text: string): number | undefined {\n if (!DIGITS_ONLY.test(text)) return undefined;\n return Number.parseInt(text, 10);\n}\n\nfunction isValidStep(stepStr: string, range: FieldRange): boolean {\n const step = parseFieldNumber(stepStr);\n return step !== undefined && step > 0 && step <= range.max;\n}\n\nfunction isValidRange(field: string, range: FieldRange): boolean {\n const parts = field.split(\"-\");\n if (parts.length !== 2) return false;\n const [startStr, endStr] = parts;\n if (startStr === undefined || endStr === undefined) return false;\n const start = parseFieldNumber(startStr);\n const end = parseFieldNumber(endStr);\n if (start === undefined || end === undefined) return false;\n return start >= range.min && end <= range.max && start <= end;\n}\n\nfunction isValidLiteral(field: string, range: FieldRange): boolean {\n const n = parseFieldNumber(field);\n return n !== undefined && n >= range.min && n <= range.max;\n}\n\n/**\n * Validate an IANA timezone. Uses `Intl.DateTimeFormat`'s strict timezone\n * lookup; invalid values raise `RangeError` which we wrap.\n *\n * @internal\n */\nexport function validateTimezone(timezone: string): void {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: timezone });\n } catch {\n throw new ConfigurationError(`Invalid IANA timezone: ${timezone}`, {\n code: \"invalid_timezone\",\n });\n }\n}\n\n/**\n * Heuristic next-fire-at estimator for fixture mode. Returns a timestamp\n * one hour in the future for shorthand/POSIX inputs. Real scheduling uses\n * a proper evaluator wired in by the local scheduler.\n *\n * @internal\n */\nexport function estimateNextRunAt(_cron: string, _timezone: string): number {\n return Date.now() + 60 * 60 * 1000;\n}\n","// Bootstrap import: loading this facade must register the public Agent facade\n// into the agent-factory-registry seam, because `internal/cron/run-job.ts`\n// resolves it via `getAgentFacade()` at runtime instead of importing `agent.ts`\n// directly (which would invert the public-api -> internal dependency\n// direction). The `@theokit/sdk/cron` sub-path entry would otherwise throw\n// \"Agent facade not registered\" at runtime.\nimport \"./agent.js\";\nimport { ConfigurationError, UnknownAgentError } from \"./errors.js\";\nimport { fireCronJobAsTask } from \"./internal/cron/fire-handler.js\";\nimport { runCronJob } from \"./internal/cron/run-job.js\";\nimport {\n getSchedulerState,\n scheduleJob,\n setCronFireHandler,\n startScheduler,\n stopScheduler,\n unscheduleJob,\n} from \"./internal/cron/scheduler.js\";\nimport { deleteJob, getJob, jobCount, listJobs, upsertJob } from \"./internal/cron/store.js\";\nimport {\n estimateNextRunAt,\n validateCronExpression,\n validateTimezone,\n} from \"./internal/cron/validate.js\";\nimport { resolveApiKey } from \"./internal/env.js\";\nimport { generateCronId } from \"./internal/ids.js\";\nimport type { AgentOptions, ListResult } from \"./types/agent.js\";\nimport type {\n CronCreateOptions,\n CronGetOptions,\n CronJob,\n CronListOptions,\n CronOperationOptions,\n CronRunOptions,\n CronRuntime,\n CronSchedulerStatus,\n CronStartOptions,\n} from \"./types/cron.js\";\nimport type { Run } from \"./types/run.js\";\n\n/**\n * Static façade for scheduling Theo agent runs on a cron expression.\n *\n * @public\n */\nexport class Cron {\n private constructor() {\n // Static-only façade.\n }\n\n /**\n * Create and persist a cron job.\n *\n * @public\n */\n static async create(options: CronCreateOptions): Promise<CronJob> {\n const job = await createCronJob(options);\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n return job;\n }\n\n /**\n * List cron jobs (local, cloud, or both).\n *\n * @public\n */\n static list(options: CronListOptions = {}): Promise<ListResult<CronJob>> {\n const runtimeFilter = options.runtime;\n const items = listJobs().filter((job) =>\n runtimeFilter === undefined ? true : job.runtime === runtimeFilter,\n );\n return Promise.resolve({ items });\n }\n\n /**\n * Get a single cron job by ID.\n *\n * @public\n */\n static get(jobId: string, _options: CronGetOptions = {}): Promise<CronJob> {\n const job = getJob(jobId);\n if (job === undefined) {\n return Promise.reject(\n new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" }),\n );\n }\n return Promise.resolve(job);\n }\n\n /**\n * Delete a cron job permanently.\n *\n * @public\n */\n static delete(jobId: string, _options: CronOperationOptions = {}): Promise<void> {\n unscheduleJob(jobId);\n deleteJob(jobId);\n return Promise.resolve();\n }\n\n /**\n * Re-enable a paused cron job.\n *\n * @public\n */\n static async enable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, true);\n }\n\n /**\n * Pause a cron job without deleting it.\n *\n * @public\n */\n static async disable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, false);\n }\n\n /**\n * Manually trigger a cron job off-schedule. Returns the resulting `Run`\n * (agent target) or `WorkflowRun` (workflow target — SE35).\n *\n * @public\n */\n static async run(\n jobId: string,\n _options: CronRunOptions = {},\n ): Promise<Run | import(\"./types/workflow.js\").WorkflowRun> {\n const job = getJob(jobId);\n if (job === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n return runCronJob(job);\n }\n\n /**\n * Activate the in-process scheduler for local cron jobs.\n *\n * @public\n */\n static start(options: CronStartOptions = {}): Promise<void> {\n // Install the default fire handler so timer ticks actually drive a real\n // agent/workflow run. Users can override via `setCronFireHandler` from\n // `@theokit/sdk/internal` (test-mode hook). Handler body lives in\n // `internal/cron/fire-handler.ts` (testable + G8).\n setCronFireHandler(fireCronJobAsTask);\n startScheduler(options.cwd);\n return Promise.resolve();\n }\n\n /**\n * Stop the in-process scheduler. Jobs are preserved.\n *\n * @public\n */\n static stop(): Promise<void> {\n stopScheduler();\n return Promise.resolve();\n }\n\n /**\n * Snapshot of the local scheduler.\n *\n * @public\n */\n static status(_options: CronStartOptions = {}): Promise<CronSchedulerStatus> {\n const scheduler = getSchedulerState();\n return Promise.resolve({ running: scheduler.running, jobCount: jobCount() });\n }\n}\n\nasync function createCronJob(options: CronCreateOptions): Promise<CronJob> {\n validateCronTarget(options);\n\n validateCronExpression(options.cron);\n const timezone = options.timezone ?? \"UTC\";\n validateTimezone(timezone);\n\n // apiKey is accepted but not required for cron-create in fixture mode.\n resolveApiKey(options.apiKey);\n\n const runtime = detectRuntime(options);\n const now = Date.now();\n const job: CronJob = {\n id: generateCronId(),\n cron: options.cron,\n timezone,\n enabled: options.enabled ?? true,\n status: options.enabled === false ? \"paused\" : \"scheduled\",\n runtime,\n createdAt: now,\n nextRunAt: estimateNextRunAt(options.cron, timezone),\n ...(options.name !== undefined ? { name: options.name } : {}),\n ...(options.message !== undefined ? { message: options.message } : {}),\n ...(options.agent !== undefined ? { agent: options.agent } : {}),\n ...(options.agentId !== undefined ? { agentId: options.agentId } : {}),\n ...(options.workflow !== undefined ? { workflow: options.workflow } : {}),\n ...(options.inputData !== undefined ? { inputData: options.inputData } : {}),\n };\n upsertJob(job);\n return job;\n}\n\n/**\n * SE35 (ADR 0014) — exactly ONE target (`agent` | `agentId` | `workflow`).\n * Agent targets require `message`; a workflow target takes `inputData` and MUST\n * NOT set `message`.\n */\nfunction validateCronTarget(options: CronCreateOptions): void {\n const targets = [options.agent, options.agentId, options.workflow].filter(\n (t) => t !== undefined,\n ).length;\n if (targets > 1) {\n throw new ConfigurationError(\n \"agent, agentId, and workflow are mutually exclusive — pass exactly one target.\",\n { code: \"cron_ambiguous_target\" },\n );\n }\n if (targets === 0) {\n throw new ConfigurationError(\n \"Cron job requires exactly one target: agent, agentId, or workflow.\",\n { code: \"cron_no_target\" },\n );\n }\n if (options.workflow !== undefined && options.message !== undefined) {\n throw new ConfigurationError(\n \"A workflow cron target takes inputData, not a message — remove `message`.\",\n { code: \"cron_workflow_message\" },\n );\n }\n if (options.workflow === undefined && options.message === undefined) {\n throw new ConfigurationError(\"An agent cron target requires a message.\", {\n code: \"cron_missing_message\",\n });\n }\n}\n\nfunction detectRuntime(options: CronCreateOptions): CronRuntime {\n // SE35 — a workflow target is a held in-memory instance; it can only run in\n // the local (in-process) scheduler. A workflow instance cannot cross the\n // cloud process boundary (ADR 0014).\n if (options.workflow !== undefined) return \"local\";\n if (options.agentId !== undefined) {\n return options.agentId.startsWith(\"bc-\") ? \"cloud\" : \"local\";\n }\n const agent = options.agent as AgentOptions | undefined;\n if (agent?.cloud !== undefined) return \"cloud\";\n return \"local\";\n}\n\nasync function updateJobStatus(jobId: string, enabled: boolean): Promise<CronJob> {\n const existing = getJob(jobId);\n if (existing === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n const updated: CronJob = {\n ...existing,\n enabled,\n status: enabled ? \"scheduled\" : \"paused\",\n };\n upsertJob(updated);\n if (updated.runtime === \"local\") {\n if (enabled) {\n scheduleJob(updated);\n } else {\n unscheduleJob(updated.id);\n }\n }\n return updated;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/internal/cron/run-job.ts","../src/internal/cron/fire-handler.ts","../src/internal/cron/store.ts","../src/internal/cron/scheduler.ts","../src/internal/cron/validate.ts","../src/cron.ts"],"names":["ConfigurationError","getAgentFacade","UnknownAgentError","submit","Croner","resolveApiKey","generateCronId"],"mappings":"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","file":"chunk-ZWRG4NWT.cjs","sourcesContent":["import { ConfigurationError, UnknownAgentError } from \"../../errors.js\";\nimport type { AgentOptions } from \"../../types/agent.js\";\nimport type { CronJob } from \"../../types/cron.js\";\nimport type { Run, SDKUserMessage } from \"../../types/run.js\";\nimport type { WorkflowRun } from \"../../types/workflow.js\";\nimport { getAgentFacade } from \"../runtime/registry/agent-factory-registry.js\";\n\n/**\n * Execute a cron job. Dispatches to one of three targets:\n * - `workflow` (SE35) → `workflow.run(inputData)` on the held instance (the\n * instance carries its own `.run`, so this module never imports `workflow.ts`),\n * returning the already-terminal {@link WorkflowRun}.\n * - `agent` → an ephemeral agent per fire; `agent.send(message)` → {@link Run}.\n * - `agentId` → reuse an existing agent; `agent.send(message)` → {@link Run}.\n *\n * Used by both `Cron.run(jobId)` (manual off-schedule fire) and the scheduler's\n * default fire handler. ADR 0014.\n *\n * @internal\n */\nexport async function runCronJob(job: CronJob): Promise<Run | WorkflowRun> {\n // `Workflow.run()` resolves only on a TERMINAL run (completed/failed/suspended/\n // cancelled — the executor never returns `status: \"running\"`), so the fire\n // handler treats the returned WorkflowRun as terminal (no `.wait()`).\n if (job.workflow !== undefined) return job.workflow.run(job.inputData);\n if (job.agent !== undefined) return runWithEphemeralAgent(job.agent, requireMessage(job));\n if (job.agentId !== undefined) return runWithExistingAgent(job.agentId, requireMessage(job));\n throw new ConfigurationError(\n `Cron job ${job.id} has no target (agent, agentId, or workflow) — cannot run.`,\n { code: \"cron_no_target\" },\n );\n}\n\n/**\n * Discriminate the {@link runCronJob} union: an agent `Run` is deferred (carries\n * `.wait()`/`.cancel()`); a {@link WorkflowRun} is already terminal (no `.wait()`).\n * @internal\n */\nexport function isAgentRun(outcome: Run | WorkflowRun): outcome is Run {\n return typeof (outcome as Run).wait === \"function\";\n}\n\n/** Agent targets require a message; fail-loud if one somehow reached a fire without it. */\nfunction requireMessage(job: CronJob): string | SDKUserMessage {\n if (job.message === undefined) {\n throw new ConfigurationError(`Cron job ${job.id} is an agent target but has no message.`, {\n code: \"cron_missing_message\",\n });\n }\n return job.message;\n}\n\nasync function runWithExistingAgent(\n agentId: string,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const info = await getAgentFacade()\n .get(agentId)\n .catch(() => undefined);\n if (info === undefined) {\n throw new UnknownAgentError(\n `Cron job references agentId \"${agentId}\" but no such agent is registered. The agent may have been disposed or the process restarted without persisting the agent registry.`,\n { code: \"agent_not_registered\" },\n );\n }\n const agent = await getAgentFacade().resume(agentId);\n return agent.send(message);\n}\n\nasync function runWithEphemeralAgent(\n baseOptions: AgentOptions,\n message: string | SDKUserMessage,\n): Promise<Run> {\n const agent = await getAgentFacade().create(baseOptions);\n return agent.send(message);\n}\n","/**\n * Default cron fire handler (extracted from `Cron.start` for testability + G8).\n *\n * Every fire registers as a Task (ADRs D363/D374) so callers observe it via\n * `Task.list` / `Task.subscribe`. SE35 (ADR 0014): the fire target may be an\n * agent (a deferred {@link Run} — abort-wire + `wait()`) OR a workflow (an\n * already-terminal {@link WorkflowRun} — no `wait()`); `isAgentRun` discriminates\n * so the handler records the correct terminal status/runId for each shape.\n *\n * @internal\n */\n\nimport type { CronJob } from \"../../types/cron.js\";\nimport { submit as taskRegistrySubmit } from \"../task/registry.js\";\nimport { isAgentRun, runCronJob } from \"./run-job.js\";\n\nexport async function fireCronJobAsTask(job: CronJob): Promise<void> {\n // The task id namespace `cron-{jobId}-{fireEpochMs}` honors D368/EC-5.\n const fireTs = Date.now();\n const taskId = `cron-${job.id}-${fireTs}`;\n try {\n await taskRegistrySubmit({\n kind: \"cron\",\n id: taskId,\n allowReservedPrefix: true,\n meta: { jobId: job.id, jobName: job.name, schedule: job.cron, firedAt: fireTs },\n work: async (ctx) => {\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) {\n // Agent target — the Run is deferred: abort-wire + await terminal.\n ctx.signal.addEventListener(\"abort\", () => void outcome.cancel().catch(() => {}), {\n once: true,\n });\n const result = await outcome.wait();\n ctx.emit({ status: result.status, runId: outcome.id });\n return { status: result.status, runId: outcome.id };\n }\n // SE35 workflow target — the WorkflowRun is ALREADY terminal (no wait()).\n ctx.emit({ status: outcome.status, runId: outcome.id });\n return { status: outcome.status, runId: outcome.id };\n },\n });\n } catch {\n // Task registry must not break cron — fall through to a direct run. No\n // double-execution: `taskRegistrySubmit` runs `work` (which calls\n // `runCronJob`) fire-and-forget, so a throw here means the SUBMIT itself\n // failed (id/registry setup) BEFORE `work` started — the job never ran, and\n // this is its first + only execution.\n const outcome = await runCronJob(job);\n if (isAgentRun(outcome)) await outcome.wait();\n }\n}\n","import type { CronJob } from \"../../types/cron.js\";\n\n/**\n * Process-wide cron job store. In Phase 1 we keep all jobs in memory\n * (across local + cloud runtimes). Local-runtime persistence to\n * `.theokit/cron/jobs.json` lands when the local runtime adapter is wired.\n *\n * @internal\n */\nconst jobs = new Map<string, CronJob>();\n\n/** Snapshot of every known cron job. @internal */\nexport function listJobs(): CronJob[] {\n return Array.from(jobs.values());\n}\n\n/** Total job count across runtimes. @internal */\nexport function jobCount(): number {\n return jobs.size;\n}\n\n/** Fetch a single job by id, or `undefined` if it does not exist. @internal */\nexport function getJob(jobId: string): CronJob | undefined {\n return jobs.get(jobId);\n}\n\n/** Insert or replace a job. @internal */\nexport function upsertJob(job: CronJob): void {\n jobs.set(job.id, job);\n}\n\n/** Delete a job. Returns `true` if a job was removed. @internal */\nexport function deleteJob(jobId: string): boolean {\n return jobs.delete(jobId);\n}\n\n/** Test-only: drop every job. @internal */\nexport function clearJobs(): void {\n jobs.clear();\n}\n","import { Cron as Croner } from \"croner\";\n\nimport type { CronJob } from \"../../types/cron.js\";\nimport { listJobs, upsertJob } from \"./store.js\";\n\n/**\n * Real local cron scheduler. When `Cron.start()` is called the scheduler\n * installs a Croner timer per enabled local job; on fire the registered\n * fire handler runs the underlying agent. `Cron.stop()` tears every timer\n * down but keeps the jobs in the store.\n *\n * @internal\n */\n\nexport type CronFireHandler = (job: CronJob) => Promise<void> | void;\n\ninterface SchedulerState {\n running: boolean;\n cwd?: string;\n timers: Map<string, Croner>;\n fireHandler?: CronFireHandler;\n}\n\nconst state: SchedulerState = { running: false, timers: new Map() };\n\n/**\n * Register the callback invoked when a job fires. The runtime adapter\n * supplies a handler that actually executes the agent; fixture-mode tests\n * leave it unset so timers tick without side effects.\n *\n * @internal\n */\nexport function setCronFireHandler(handler: CronFireHandler | undefined): void {\n state.fireHandler = handler;\n}\n\n/** Activate the scheduler and install timers for every enabled local job. @internal */\nexport function startScheduler(cwd?: string): void {\n state.running = true;\n if (cwd !== undefined) state.cwd = cwd;\n for (const job of listJobs()) {\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n }\n}\n\n/** Deactivate the scheduler. Stops every timer; jobs remain in the store. @internal */\nexport function stopScheduler(): void {\n state.running = false;\n for (const timer of state.timers.values()) timer.stop();\n state.timers.clear();\n}\n\n/** Schedule a single job. No-op if the scheduler is not running. @internal */\nexport function scheduleJob(job: CronJob): void {\n if (!state.running) return;\n unscheduleJob(job.id);\n const expression = normalizeExpression(job.cron);\n const timer = new Croner(\n expression,\n { timezone: job.timezone, name: job.id, protect: true },\n () => {\n void fireJob(job.id);\n },\n );\n state.timers.set(job.id, timer);\n refreshNextRunAt(job.id, timer);\n}\n\n/** Tear down the timer for a single job. @internal */\nexport function unscheduleJob(jobId: string): boolean {\n const timer = state.timers.get(jobId);\n if (timer === undefined) return false;\n timer.stop();\n state.timers.delete(jobId);\n return true;\n}\n\n/** Snapshot of the scheduler's running flag and configured workspace. @internal */\nexport function getSchedulerState(): { running: boolean; cwd?: string } {\n const result: { running: boolean; cwd?: string } = { running: state.running };\n if (state.cwd !== undefined) result.cwd = state.cwd;\n return result;\n}\n\nasync function fireJob(jobId: string): Promise<void> {\n const fresh = listJobs().find((entry) => entry.id === jobId);\n if (fresh === undefined || fresh.enabled === false) return;\n const handler = state.fireHandler;\n upsertJob({ ...fresh, lastRunAt: Date.now() });\n if (handler === undefined) return;\n try {\n await handler(fresh);\n } catch {\n // Swallow handler errors — the scheduler must keep ticking. Real\n // surface for run failures lives on the Run.wait() result itself.\n }\n}\n\nfunction refreshNextRunAt(jobId: string, timer: Croner): void {\n const next = timer.nextRun();\n if (next === null) return;\n const existing = listJobs().find((entry) => entry.id === jobId);\n if (existing === undefined) return;\n upsertJob({ ...existing, nextRunAt: next.getTime() });\n}\n\nfunction normalizeExpression(cron: string): string {\n switch (cron) {\n case \"@hourly\":\n return \"0 * * * *\";\n case \"@daily\":\n return \"0 0 * * *\";\n case \"@weekly\":\n return \"0 0 * * 0\";\n case \"@monthly\":\n return \"0 0 1 * *\";\n case \"@yearly\":\n return \"0 0 1 1 *\";\n default:\n return cron;\n }\n}\n","import { ConfigurationError } from \"../../errors.js\";\n\n/**\n * POSIX-cron + shorthand validators used by `Cron.create()`. Throws\n * `ConfigurationError` with a stable message and code on invalid input.\n *\n * @internal\n */\n\nconst SHORTHANDS = new Set([\"@hourly\", \"@daily\", \"@weekly\", \"@monthly\", \"@yearly\"]);\n\ninterface FieldRange {\n min: number;\n max: number;\n}\n\nconst FIELD_RANGES: readonly FieldRange[] = [\n { min: 0, max: 59 }, // minute\n { min: 0, max: 23 }, // hour\n { min: 1, max: 31 }, // day-of-month\n { min: 1, max: 12 }, // month\n { min: 0, max: 6 }, // day-of-week\n];\n\n/**\n * Validate a cron expression. Accepts shorthand (`@hourly`, ..., `@yearly`)\n * or 5-field POSIX cron with star, literals, star/N step, N-M range, and\n * N,M,P list.\n *\n * @internal\n */\nexport function validateCronExpression(cron: string): void {\n if (typeof cron !== \"string\" || cron.length === 0) {\n throw new ConfigurationError(\"Invalid cron expression: empty\", {\n code: \"invalid_cron\",\n });\n }\n if (cron.startsWith(\"@\")) {\n if (!SHORTHANDS.has(cron)) {\n throw new ConfigurationError(`Invalid cron expression: unknown shorthand ${cron}`, {\n code: \"invalid_cron\",\n });\n }\n return;\n }\n\n const fields = cron.trim().split(/\\s+/);\n if (fields.length !== FIELD_RANGES.length) {\n throw new ConfigurationError(\n `Invalid cron expression: ${cron} (expected ${FIELD_RANGES.length} fields, got ${fields.length})`,\n { code: \"invalid_cron\" },\n );\n }\n for (const [index, range] of FIELD_RANGES.entries()) {\n // The length check above already established one field per range, so the lookup is total.\n // B-116: this replaces a `range === undefined` guard that no caller could reach — its single\n // caller only ran with exactly 5 fields, and FIELD_RANGES has exactly 5 entries, so the branch\n // stayed at 0 executions through 37 tests written specifically to enter it.\n const field = fields[index] as string;\n if (!isValidCronField(field, range)) {\n throw new ConfigurationError(`Invalid cron expression: ${cron} (field ${index + 1})`, {\n code: \"invalid_cron\",\n });\n }\n }\n}\n\nfunction isValidCronField(field: string, range: FieldRange): boolean {\n if (field === \"*\") return true;\n if (field.startsWith(\"*/\")) return isValidStep(field.slice(2), range);\n if (field.includes(\",\")) {\n return field.split(\",\").every((part) => isValidCronField(part, range));\n }\n if (field.includes(\"-\")) return isValidRange(field, range);\n return isValidLiteral(field, range);\n}\n\n/**\n * Digits, and nothing else. `Number.parseInt` stops at the first non-digit, so it reads `\"5abc\"` as\n * `5` and `\"0x5\"` as `0` — a numeric field parsed that way accepts garbage that happens to start\n * with a digit.\n *\n * This replaces the `String(n) === field` round-trip the literal and step validators used to carry.\n * The round-trip refused the garbage correctly but also refused `\"07\"`, because `String(7) !== \"07\"`\n * — and `isValidRange` never had it at all, so `\"1-5abc\"` was accepted while `\"5abc\"` was refused\n * (B-121). One predicate, applied to every field shape, closes both halves.\n *\n * The boundary that matters is croner 9, the scheduler this SDK actually fires jobs with. Measured\n * 2026-08-19: it ACCEPTS `\"07 * * * *\"` (next run at :07) and REFUSES `\"5abc\"`, `\"1-5abc\"`,\n * `\"1abc-5\"`, `\"0x5\"`, `\"5.9\"`, `\"+5\"` and `\"1e1\"` as \"illegal character\" (B-122). Validating\n * stricter than the engine rejects schedules that would have run; validating looser only moves the\n * failure from `Cron.create()` to fire time, where nobody is watching.\n *\n * @internal\n */\nconst DIGITS_ONLY = /^\\d+$/;\n\nfunction parseFieldNumber(text: string): number | undefined {\n if (!DIGITS_ONLY.test(text)) return undefined;\n return Number.parseInt(text, 10);\n}\n\nfunction isValidStep(stepStr: string, range: FieldRange): boolean {\n const step = parseFieldNumber(stepStr);\n return step !== undefined && step > 0 && step <= range.max;\n}\n\nfunction isValidRange(field: string, range: FieldRange): boolean {\n const parts = field.split(\"-\");\n if (parts.length !== 2) return false;\n const [startStr, endStr] = parts;\n if (startStr === undefined || endStr === undefined) return false;\n const start = parseFieldNumber(startStr);\n const end = parseFieldNumber(endStr);\n if (start === undefined || end === undefined) return false;\n return start >= range.min && end <= range.max && start <= end;\n}\n\nfunction isValidLiteral(field: string, range: FieldRange): boolean {\n const n = parseFieldNumber(field);\n return n !== undefined && n >= range.min && n <= range.max;\n}\n\n/**\n * Validate an IANA timezone. Uses `Intl.DateTimeFormat`'s strict timezone\n * lookup; invalid values raise `RangeError` which we wrap.\n *\n * @internal\n */\nexport function validateTimezone(timezone: string): void {\n try {\n new Intl.DateTimeFormat(\"en-US\", { timeZone: timezone });\n } catch {\n throw new ConfigurationError(`Invalid IANA timezone: ${timezone}`, {\n code: \"invalid_timezone\",\n });\n }\n}\n\n/**\n * Heuristic next-fire-at estimator for fixture mode. Returns a timestamp\n * one hour in the future for shorthand/POSIX inputs. Real scheduling uses\n * a proper evaluator wired in by the local scheduler.\n *\n * @internal\n */\nexport function estimateNextRunAt(_cron: string, _timezone: string): number {\n return Date.now() + 60 * 60 * 1000;\n}\n","// Bootstrap import: loading this facade must register the public Agent facade\n// into the agent-factory-registry seam, because `internal/cron/run-job.ts`\n// resolves it via `getAgentFacade()` at runtime instead of importing `agent.ts`\n// directly (which would invert the public-api -> internal dependency\n// direction). The `@theokit/sdk/cron` sub-path entry would otherwise throw\n// \"Agent facade not registered\" at runtime.\nimport \"./agent.js\";\nimport { ConfigurationError, UnknownAgentError } from \"./errors.js\";\nimport { fireCronJobAsTask } from \"./internal/cron/fire-handler.js\";\nimport { runCronJob } from \"./internal/cron/run-job.js\";\nimport {\n getSchedulerState,\n scheduleJob,\n setCronFireHandler,\n startScheduler,\n stopScheduler,\n unscheduleJob,\n} from \"./internal/cron/scheduler.js\";\nimport { deleteJob, getJob, jobCount, listJobs, upsertJob } from \"./internal/cron/store.js\";\nimport {\n estimateNextRunAt,\n validateCronExpression,\n validateTimezone,\n} from \"./internal/cron/validate.js\";\nimport { resolveApiKey } from \"./internal/env.js\";\nimport { generateCronId } from \"./internal/ids.js\";\nimport type { AgentOptions, ListResult } from \"./types/agent.js\";\nimport type {\n CronCreateOptions,\n CronGetOptions,\n CronJob,\n CronListOptions,\n CronOperationOptions,\n CronRunOptions,\n CronRuntime,\n CronSchedulerStatus,\n CronStartOptions,\n} from \"./types/cron.js\";\nimport type { Run } from \"./types/run.js\";\n\n/**\n * Static façade for scheduling Theo agent runs on a cron expression.\n *\n * @public\n */\nexport class Cron {\n private constructor() {\n // Static-only façade.\n }\n\n /**\n * Create and persist a cron job.\n *\n * @public\n */\n static async create(options: CronCreateOptions): Promise<CronJob> {\n const job = await createCronJob(options);\n if (job.runtime === \"local\" && job.enabled !== false) scheduleJob(job);\n return job;\n }\n\n /**\n * List cron jobs (local, cloud, or both).\n *\n * @public\n */\n static list(options: CronListOptions = {}): Promise<ListResult<CronJob>> {\n const runtimeFilter = options.runtime;\n const items = listJobs().filter((job) =>\n runtimeFilter === undefined ? true : job.runtime === runtimeFilter,\n );\n return Promise.resolve({ items });\n }\n\n /**\n * Get a single cron job by ID.\n *\n * @public\n */\n static get(jobId: string, _options: CronGetOptions = {}): Promise<CronJob> {\n const job = getJob(jobId);\n if (job === undefined) {\n return Promise.reject(\n new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" }),\n );\n }\n return Promise.resolve(job);\n }\n\n /**\n * Delete a cron job permanently.\n *\n * @public\n */\n static delete(jobId: string, _options: CronOperationOptions = {}): Promise<void> {\n unscheduleJob(jobId);\n deleteJob(jobId);\n return Promise.resolve();\n }\n\n /**\n * Re-enable a paused cron job.\n *\n * @public\n */\n static async enable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, true);\n }\n\n /**\n * Pause a cron job without deleting it.\n *\n * @public\n */\n static async disable(jobId: string, _options: CronOperationOptions = {}): Promise<CronJob> {\n return updateJobStatus(jobId, false);\n }\n\n /**\n * Manually trigger a cron job off-schedule. Returns the resulting `Run`\n * (agent target) or `WorkflowRun` (workflow target — SE35).\n *\n * @public\n */\n static async run(\n jobId: string,\n _options: CronRunOptions = {},\n ): Promise<Run | import(\"./types/workflow.js\").WorkflowRun> {\n const job = getJob(jobId);\n if (job === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n return runCronJob(job);\n }\n\n /**\n * Activate the in-process scheduler for local cron jobs.\n *\n * @public\n */\n static start(options: CronStartOptions = {}): Promise<void> {\n // Install the default fire handler so timer ticks actually drive a real\n // agent/workflow run. Users can override via `setCronFireHandler` from\n // `@theokit/sdk/internal` (test-mode hook). Handler body lives in\n // `internal/cron/fire-handler.ts` (testable + G8).\n setCronFireHandler(fireCronJobAsTask);\n startScheduler(options.cwd);\n return Promise.resolve();\n }\n\n /**\n * Stop the in-process scheduler. Jobs are preserved.\n *\n * @public\n */\n static stop(): Promise<void> {\n stopScheduler();\n return Promise.resolve();\n }\n\n /**\n * Snapshot of the local scheduler.\n *\n * @public\n */\n static status(_options: CronStartOptions = {}): Promise<CronSchedulerStatus> {\n const scheduler = getSchedulerState();\n return Promise.resolve({ running: scheduler.running, jobCount: jobCount() });\n }\n}\n\nasync function createCronJob(options: CronCreateOptions): Promise<CronJob> {\n validateCronTarget(options);\n\n validateCronExpression(options.cron);\n const timezone = options.timezone ?? \"UTC\";\n validateTimezone(timezone);\n\n // apiKey is accepted but not required for cron-create in fixture mode.\n resolveApiKey(options.apiKey);\n\n const runtime = detectRuntime(options);\n const now = Date.now();\n const job: CronJob = {\n id: generateCronId(),\n cron: options.cron,\n timezone,\n enabled: options.enabled ?? true,\n status: options.enabled === false ? \"paused\" : \"scheduled\",\n runtime,\n createdAt: now,\n nextRunAt: estimateNextRunAt(options.cron, timezone),\n ...(options.name !== undefined ? { name: options.name } : {}),\n ...(options.message !== undefined ? { message: options.message } : {}),\n ...(options.agent !== undefined ? { agent: options.agent } : {}),\n ...(options.agentId !== undefined ? { agentId: options.agentId } : {}),\n ...(options.workflow !== undefined ? { workflow: options.workflow } : {}),\n ...(options.inputData !== undefined ? { inputData: options.inputData } : {}),\n };\n upsertJob(job);\n return job;\n}\n\n/**\n * SE35 (ADR 0014) — exactly ONE target (`agent` | `agentId` | `workflow`).\n * Agent targets require `message`; a workflow target takes `inputData` and MUST\n * NOT set `message`.\n */\nfunction validateCronTarget(options: CronCreateOptions): void {\n const targets = [options.agent, options.agentId, options.workflow].filter(\n (t) => t !== undefined,\n ).length;\n if (targets > 1) {\n throw new ConfigurationError(\n \"agent, agentId, and workflow are mutually exclusive — pass exactly one target.\",\n { code: \"cron_ambiguous_target\" },\n );\n }\n if (targets === 0) {\n throw new ConfigurationError(\n \"Cron job requires exactly one target: agent, agentId, or workflow.\",\n { code: \"cron_no_target\" },\n );\n }\n if (options.workflow !== undefined && options.message !== undefined) {\n throw new ConfigurationError(\n \"A workflow cron target takes inputData, not a message — remove `message`.\",\n { code: \"cron_workflow_message\" },\n );\n }\n if (options.workflow === undefined && options.message === undefined) {\n throw new ConfigurationError(\"An agent cron target requires a message.\", {\n code: \"cron_missing_message\",\n });\n }\n}\n\nfunction detectRuntime(options: CronCreateOptions): CronRuntime {\n // SE35 — a workflow target is a held in-memory instance; it can only run in\n // the local (in-process) scheduler. A workflow instance cannot cross the\n // cloud process boundary (ADR 0014).\n if (options.workflow !== undefined) return \"local\";\n if (options.agentId !== undefined) {\n return options.agentId.startsWith(\"bc-\") ? \"cloud\" : \"local\";\n }\n const agent = options.agent as AgentOptions | undefined;\n if (agent?.cloud !== undefined) return \"cloud\";\n return \"local\";\n}\n\nasync function updateJobStatus(jobId: string, enabled: boolean): Promise<CronJob> {\n const existing = getJob(jobId);\n if (existing === undefined) {\n throw new UnknownAgentError(`Cron job ${jobId} not found`, { code: \"unknown_cron_job\" });\n }\n const updated: CronJob = {\n ...existing,\n enabled,\n status: enabled ? \"scheduled\" : \"paused\",\n };\n upsertJob(updated);\n if (updated.runtime === \"local\") {\n if (enabled) {\n scheduleJob(updated);\n } else {\n unscheduleJob(updated.id);\n }\n }\n return updated;\n}\n"]}
|
package/dist/cron.cjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
require('./chunk-
|
|
3
|
+
var chunkZWRG4NWT_cjs = require('./chunk-ZWRG4NWT.cjs');
|
|
4
|
+
require('./chunk-JJ3OVRUM.cjs');
|
|
5
5
|
require('./chunk-3FFAEAUJ.cjs');
|
|
6
6
|
require('./chunk-RMWTPV3M.cjs');
|
|
7
7
|
require('./chunk-BUUUWQMB.cjs');
|
|
8
|
-
require('./chunk-
|
|
8
|
+
require('./chunk-VLVVJLDH.cjs');
|
|
9
9
|
require('./chunk-ZCIRZE37.cjs');
|
|
10
10
|
require('./chunk-BV2MWEMV.cjs');
|
|
11
11
|
require('./chunk-KQ7TS7WW.cjs');
|
|
12
12
|
require('./chunk-GHX4P3V2.cjs');
|
|
13
13
|
require('./chunk-GKEFRLU7.cjs');
|
|
14
|
-
require('./chunk-
|
|
14
|
+
require('./chunk-IAHZCGBE.cjs');
|
|
15
15
|
require('./chunk-ZLQSWSJ2.cjs');
|
|
16
16
|
require('./chunk-KYAJINUI.cjs');
|
|
17
17
|
require('./chunk-O7DK5PBJ.cjs');
|
|
@@ -61,7 +61,7 @@ require('./chunk-EG4QM7ZJ.cjs');
|
|
|
61
61
|
|
|
62
62
|
Object.defineProperty(exports, "Cron", {
|
|
63
63
|
enumerable: true,
|
|
64
|
-
get: function () { return
|
|
64
|
+
get: function () { return chunkZWRG4NWT_cjs.Cron; }
|
|
65
65
|
});
|
|
66
66
|
//# sourceMappingURL=cron.cjs.map
|
|
67
67
|
//# sourceMappingURL=cron.cjs.map
|
package/dist/cron.js
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export { Cron } from './chunk-
|
|
2
|
-
import './chunk-
|
|
1
|
+
export { Cron } from './chunk-GPKAF7SG.js';
|
|
2
|
+
import './chunk-25BD2R5G.js';
|
|
3
3
|
import './chunk-A46SWMIF.js';
|
|
4
4
|
import './chunk-4FFBAUFS.js';
|
|
5
5
|
import './chunk-K2BQQ445.js';
|
|
6
|
-
import './chunk-
|
|
6
|
+
import './chunk-L3MTL4NA.js';
|
|
7
7
|
import './chunk-K5OJUYSZ.js';
|
|
8
8
|
import './chunk-2SFBB54R.js';
|
|
9
9
|
import './chunk-UBDMVMBZ.js';
|
|
10
10
|
import './chunk-H73MEMQB.js';
|
|
11
11
|
import './chunk-XO4SOZN6.js';
|
|
12
|
-
import './chunk-
|
|
12
|
+
import './chunk-L4BDVXIM.js';
|
|
13
13
|
import './chunk-BP46RJ5X.js';
|
|
14
14
|
import './chunk-DN2PACRI.js';
|
|
15
15
|
import './chunk-TAZVKYWJ.js';
|
package/dist/eval.cjs
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkJ24VJOH3_cjs = require('./chunk-J24VJOH3.cjs');
|
|
4
|
-
var
|
|
4
|
+
var chunkJJ3OVRUM_cjs = require('./chunk-JJ3OVRUM.cjs');
|
|
5
5
|
require('./chunk-3FFAEAUJ.cjs');
|
|
6
6
|
require('./chunk-RMWTPV3M.cjs');
|
|
7
7
|
var chunkBUUUWQMB_cjs = require('./chunk-BUUUWQMB.cjs');
|
|
8
|
-
require('./chunk-
|
|
8
|
+
require('./chunk-VLVVJLDH.cjs');
|
|
9
9
|
require('./chunk-ZCIRZE37.cjs');
|
|
10
10
|
require('./chunk-BV2MWEMV.cjs');
|
|
11
11
|
require('./chunk-KQ7TS7WW.cjs');
|
|
12
12
|
require('./chunk-GHX4P3V2.cjs');
|
|
13
13
|
require('./chunk-GKEFRLU7.cjs');
|
|
14
|
-
require('./chunk-
|
|
14
|
+
require('./chunk-IAHZCGBE.cjs');
|
|
15
15
|
require('./chunk-ZLQSWSJ2.cjs');
|
|
16
16
|
require('./chunk-KYAJINUI.cjs');
|
|
17
17
|
require('./chunk-O7DK5PBJ.cjs');
|
|
@@ -784,7 +784,7 @@ function makeDefaultEmbedder(opts) {
|
|
|
784
784
|
let runtime;
|
|
785
785
|
return (texts) => {
|
|
786
786
|
if (runtime === void 0) {
|
|
787
|
-
runtime =
|
|
787
|
+
runtime = chunkJJ3OVRUM_cjs.openRouterMemoryEmbeddingProviderAdapter.create(embedderCreateOptions(opts));
|
|
788
788
|
}
|
|
789
789
|
return runtime.then((rt) => rt.embed(texts));
|
|
790
790
|
};
|