@chude/memory 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +294 -0
- package/dist/application/index.d.ts +6 -0
- package/dist/application/services/ambient-context-service.d.ts +90 -0
- package/dist/application/services/backfill-service.d.ts +71 -0
- package/dist/application/services/budget-allocator.d.ts +57 -0
- package/dist/application/services/embedding-service.d.ts +131 -0
- package/dist/application/services/export-service.d.ts +225 -0
- package/dist/application/services/extraction-pipeline.d.ts +50 -0
- package/dist/application/services/friction-service.d.ts +148 -0
- package/dist/application/services/fts-sanitizer.d.ts +25 -0
- package/dist/application/services/index.d.ts +34 -0
- package/dist/application/services/llm-extractor.d.ts +96 -0
- package/dist/application/services/memory-file-sync-service.d.ts +58 -0
- package/dist/application/services/pattern-extractor.d.ts +95 -0
- package/dist/application/services/recovery-service.d.ts +81 -0
- package/dist/application/services/rrf-fusion.d.ts +53 -0
- package/dist/application/services/smart-context-service.d.ts +126 -0
- package/dist/application/services/sync-service.d.ts +157 -0
- package/dist/application/services/temporal-decay.d.ts +62 -0
- package/dist/domain/entities/backfill-state.d.ts +56 -0
- package/dist/domain/entities/entity.d.ts +131 -0
- package/dist/domain/entities/extraction-state.d.ts +128 -0
- package/dist/domain/entities/fact.d.ts +59 -0
- package/dist/domain/entities/friction-entry.d.ts +84 -0
- package/dist/domain/entities/index.d.ts +15 -0
- package/dist/domain/entities/link.d.ts +74 -0
- package/dist/domain/entities/memory-file.d.ts +78 -0
- package/dist/domain/entities/message.d.ts +70 -0
- package/dist/domain/entities/session.d.ts +93 -0
- package/dist/domain/entities/tool-use.d.ts +85 -0
- package/dist/domain/errors/error-codes.d.ts +37 -0
- package/dist/domain/errors/index.d.ts +8 -0
- package/dist/domain/errors/memory-error.d.ts +52 -0
- package/dist/domain/errors/unknown-error.d.ts +9 -0
- package/dist/domain/index.d.ts +11 -0
- package/dist/domain/ports/embedding.d.ts +96 -0
- package/dist/domain/ports/extraction.d.ts +13 -0
- package/dist/domain/ports/index.d.ts +14 -0
- package/dist/domain/ports/redactor.d.ts +17 -0
- package/dist/domain/ports/repositories.d.ts +658 -0
- package/dist/domain/ports/services.d.ts +180 -0
- package/dist/domain/ports/signals.d.ts +82 -0
- package/dist/domain/ports/sources.d.ts +122 -0
- package/dist/domain/ports/types.d.ts +150 -0
- package/dist/domain/services/content-extractor.d.ts +61 -0
- package/dist/domain/services/index.d.ts +8 -0
- package/dist/domain/services/path-decoder.d.ts +56 -0
- package/dist/domain/services/query-parser.d.ts +47 -0
- package/dist/domain/value-objects/embedding-config.d.ts +56 -0
- package/dist/domain/value-objects/embedding-result.d.ts +46 -0
- package/dist/domain/value-objects/index.d.ts +10 -0
- package/dist/domain/value-objects/project-path.d.ts +92 -0
- package/dist/domain/value-objects/search-query.d.ts +30 -0
- package/dist/domain/value-objects/search-result.d.ts +92 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +1548 -0
- package/dist/infrastructure/database/connection.d.ts +161 -0
- package/dist/infrastructure/database/event-log.d.ts +22 -0
- package/dist/infrastructure/database/health-checker.d.ts +248 -0
- package/dist/infrastructure/database/index.d.ts +11 -0
- package/dist/infrastructure/database/repositories/backfill-state-repository.d.ts +19 -0
- package/dist/infrastructure/database/repositories/embedding-repository.d.ts +121 -0
- package/dist/infrastructure/database/repositories/entity-repository.d.ts +73 -0
- package/dist/infrastructure/database/repositories/extraction-log-repository.d.ts +17 -0
- package/dist/infrastructure/database/repositories/extraction-state-repository.d.ts +52 -0
- package/dist/infrastructure/database/repositories/fact-repository.d.ts +25 -0
- package/dist/infrastructure/database/repositories/friction-repository.d.ts +41 -0
- package/dist/infrastructure/database/repositories/index.d.ts +17 -0
- package/dist/infrastructure/database/repositories/link-repository.d.ts +64 -0
- package/dist/infrastructure/database/repositories/memory-file-repository.d.ts +28 -0
- package/dist/infrastructure/database/repositories/message-repository.d.ts +87 -0
- package/dist/infrastructure/database/repositories/session-repository.d.ts +125 -0
- package/dist/infrastructure/database/repositories/tool-use-repository.d.ts +72 -0
- package/dist/infrastructure/database/schema.d.ts +203 -0
- package/dist/infrastructure/database/services/context-service.d.ts +93 -0
- package/dist/infrastructure/database/services/hybrid-search-service.d.ts +156 -0
- package/dist/infrastructure/database/services/index.d.ts +10 -0
- package/dist/infrastructure/database/services/search-service.d.ts +57 -0
- package/dist/infrastructure/database/services/stats-service.d.ts +36 -0
- package/dist/infrastructure/embedding/background-embedder.d.ts +125 -0
- package/dist/infrastructure/embedding/embedding-provider-factory.d.ts +44 -0
- package/dist/infrastructure/embedding/index.d.ts +5 -0
- package/dist/infrastructure/embedding/ollama-provider.d.ts +41 -0
- package/dist/infrastructure/embedding/openai-provider.d.ts +38 -0
- package/dist/infrastructure/embedding/transformers-js-provider.d.ts +34 -0
- package/dist/infrastructure/external/index.d.ts +7 -0
- package/dist/infrastructure/external/qmd-runner.d.ts +36 -0
- package/dist/infrastructure/hooks/auto-memory-writer.d.ts +52 -0
- package/dist/infrastructure/hooks/config-manager.d.ts +237 -0
- package/dist/infrastructure/hooks/git-syncer.d.ts +44 -0
- package/dist/infrastructure/hooks/hook-runner.d.ts +126 -0
- package/dist/infrastructure/hooks/index.d.ts +12 -0
- package/dist/infrastructure/hooks/log-writer.d.ts +106 -0
- package/dist/infrastructure/hooks/settings-manager.d.ts +163 -0
- package/dist/infrastructure/hooks/sync-hook-script.d.ts +83 -0
- package/dist/infrastructure/hooks/sync-logger-adapter.d.ts +17 -0
- package/dist/infrastructure/index.d.ts +11 -0
- package/dist/infrastructure/llm/anthropic-extractor.d.ts +20 -0
- package/dist/infrastructure/llm/claude-cli-extractor.d.ts +14 -0
- package/dist/infrastructure/llm/claude-summary-generator.d.ts +14 -0
- package/dist/infrastructure/llm/extraction-helper.d.ts +16 -0
- package/dist/infrastructure/llm/ollama-extractor.d.ts +20 -0
- package/dist/infrastructure/llm/openai-extractor.d.ts +23 -0
- package/dist/infrastructure/migration.d.ts +103 -0
- package/dist/infrastructure/parsers/event-classifier.d.ts +111 -0
- package/dist/infrastructure/parsers/index.d.ts +8 -0
- package/dist/infrastructure/parsers/jsonl-parser.d.ts +25 -0
- package/dist/infrastructure/parsers/timestamp.d.ts +18 -0
- package/dist/infrastructure/paths.d.ts +129 -0
- package/dist/infrastructure/providers/provider-defaults.d.ts +11 -0
- package/dist/infrastructure/providers/provider-registry.d.ts +28 -0
- package/dist/infrastructure/security/pattern-redactor.d.ts +6 -0
- package/dist/infrastructure/signals/adapters.d.ts +27 -0
- package/dist/infrastructure/signals/checkpoint-manager.d.ts +83 -0
- package/dist/infrastructure/signals/index.d.ts +8 -0
- package/dist/infrastructure/signals/signal-handler.d.ts +113 -0
- package/dist/infrastructure/sources/index.d.ts +8 -0
- package/dist/infrastructure/sources/memory-file-scanner.d.ts +23 -0
- package/dist/infrastructure/sources/project-name-resolver.d.ts +67 -0
- package/dist/infrastructure/sources/session-source.d.ts +70 -0
- package/dist/presentation/cli/command-result.d.ts +10 -0
- package/dist/presentation/cli/commands/_helpers/capture-json.d.ts +36 -0
- package/dist/presentation/cli/commands/_helpers/deprecation-warning.d.ts +41 -0
- package/dist/presentation/cli/commands/backfill.d.ts +56 -0
- package/dist/presentation/cli/commands/browse.d.ts +55 -0
- package/dist/presentation/cli/commands/completion.d.ts +61 -0
- package/dist/presentation/cli/commands/context.d.ts +53 -0
- package/dist/presentation/cli/commands/doctor.d.ts +55 -0
- package/dist/presentation/cli/commands/export.d.ts +36 -0
- package/dist/presentation/cli/commands/extract.d.ts +40 -0
- package/dist/presentation/cli/commands/facts.d.ts +17 -0
- package/dist/presentation/cli/commands/friction/dashboard.d.ts +18 -0
- package/dist/presentation/cli/commands/friction/index.d.ts +12 -0
- package/dist/presentation/cli/commands/friction/list.d.ts +12 -0
- package/dist/presentation/cli/commands/friction/log.d.ts +12 -0
- package/dist/presentation/cli/commands/friction/purge.d.ts +12 -0
- package/dist/presentation/cli/commands/friction/resolve.d.ts +12 -0
- package/dist/presentation/cli/commands/friction/types.d.ts +86 -0
- package/dist/presentation/cli/commands/friction/wontfix.d.ts +12 -0
- package/dist/presentation/cli/commands/import.d.ts +38 -0
- package/dist/presentation/cli/commands/index.d.ts +51 -0
- package/dist/presentation/cli/commands/install.d.ts +67 -0
- package/dist/presentation/cli/commands/list.d.ts +61 -0
- package/dist/presentation/cli/commands/migrate.d.ts +36 -0
- package/dist/presentation/cli/commands/purge.d.ts +100 -0
- package/dist/presentation/cli/commands/query.d.ts +51 -0
- package/dist/presentation/cli/commands/related.d.ts +47 -0
- package/dist/presentation/cli/commands/remote.d.ts +36 -0
- package/dist/presentation/cli/commands/search.d.ts +100 -0
- package/dist/presentation/cli/commands/show.d.ts +51 -0
- package/dist/presentation/cli/commands/stats.d.ts +38 -0
- package/dist/presentation/cli/commands/status.d.ts +152 -0
- package/dist/presentation/cli/commands/sync/ambient.d.ts +22 -0
- package/dist/presentation/cli/commands/sync/background.d.ts +23 -0
- package/dist/presentation/cli/commands/sync/embedding-pass.d.ts +32 -0
- package/dist/presentation/cli/commands/sync/helpers.d.ts +25 -0
- package/dist/presentation/cli/commands/sync/index.d.ts +17 -0
- package/dist/presentation/cli/commands/sync/memory-files.d.ts +26 -0
- package/dist/presentation/cli/commands/sync/types.d.ts +163 -0
- package/dist/presentation/cli/commands/uninstall.d.ts +44 -0
- package/dist/presentation/cli/db-startup.d.ts +61 -0
- package/dist/presentation/cli/formatters/ai-formatter.d.ts +38 -0
- package/dist/presentation/cli/formatters/color.d.ts +82 -0
- package/dist/presentation/cli/formatters/context-formatter.d.ts +55 -0
- package/dist/presentation/cli/formatters/dto-helpers.d.ts +176 -0
- package/dist/presentation/cli/formatters/envelope.d.ts +136 -0
- package/dist/presentation/cli/formatters/error-formatter.d.ts +41 -0
- package/dist/presentation/cli/formatters/friction-dashboard.d.ts +46 -0
- package/dist/presentation/cli/formatters/index.d.ts +17 -0
- package/dist/presentation/cli/formatters/list-formatter.d.ts +48 -0
- package/dist/presentation/cli/formatters/output-formatter.d.ts +98 -0
- package/dist/presentation/cli/formatters/related-formatter.d.ts +57 -0
- package/dist/presentation/cli/formatters/show-formatter.d.ts +63 -0
- package/dist/presentation/cli/formatters/stats-formatter.d.ts +54 -0
- package/dist/presentation/cli/formatters/text-width.d.ts +37 -0
- package/dist/presentation/cli/formatters/timestamp-formatter.d.ts +38 -0
- package/dist/presentation/cli/index.d.ts +10 -0
- package/dist/presentation/cli/index.js +1664 -0
- package/dist/presentation/cli/parsers/date-parser.d.ts +28 -0
- package/dist/presentation/cli/parsers/index.d.ts +6 -0
- package/dist/presentation/cli/pickers/index.d.ts +6 -0
- package/dist/presentation/cli/pickers/session-picker.d.ts +59 -0
- package/dist/presentation/cli/progress-reporter.d.ts +199 -0
- package/package.json +94 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Schema Definitions
|
|
3
|
+
*
|
|
4
|
+
* SQLite schema with FTS5 full-text search support.
|
|
5
|
+
* Uses external content pattern for efficient FTS5 indexing.
|
|
6
|
+
*/
|
|
7
|
+
import type { Database } from "bun:sqlite";
|
|
8
|
+
/**
|
|
9
|
+
* Sessions table - stores session metadata
|
|
10
|
+
*/
|
|
11
|
+
export declare const SESSIONS_TABLE = "\nCREATE TABLE IF NOT EXISTS sessions (\n id TEXT PRIMARY KEY,\n project_path_encoded TEXT NOT NULL,\n project_path_decoded TEXT NOT NULL,\n project_name TEXT NOT NULL,\n start_time TEXT NOT NULL,\n end_time TEXT,\n message_count INTEGER DEFAULT 0,\n summary TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_sessions_project ON sessions(project_path_encoded);\nCREATE INDEX IF NOT EXISTS idx_sessions_start_time ON sessions(start_time);\n";
|
|
12
|
+
/**
|
|
13
|
+
* Messages metadata table - content table for FTS5
|
|
14
|
+
* Uses explicit rowid for FTS5 external content linkage
|
|
15
|
+
*/
|
|
16
|
+
export declare const MESSAGES_META_TABLE = "\nCREATE TABLE IF NOT EXISTS messages_meta (\n rowid INTEGER PRIMARY KEY AUTOINCREMENT,\n id TEXT UNIQUE NOT NULL,\n session_id TEXT NOT NULL,\n role TEXT NOT NULL CHECK (role IN ('user', 'assistant')),\n content TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n tool_use_ids TEXT,\n FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE\n);\nCREATE INDEX IF NOT EXISTS idx_messages_session ON messages_meta(session_id);\nCREATE INDEX IF NOT EXISTS idx_messages_timestamp ON messages_meta(timestamp);\n";
|
|
17
|
+
/**
|
|
18
|
+
* Messages FTS5 virtual table - external content pattern
|
|
19
|
+
* References messages_meta for content storage
|
|
20
|
+
*/
|
|
21
|
+
export declare const MESSAGES_FTS_TABLE = "\nCREATE VIRTUAL TABLE IF NOT EXISTS messages_fts USING fts5(\n content,\n content=messages_meta,\n content_rowid=rowid,\n tokenize='porter unicode61'\n);\n";
|
|
22
|
+
/**
|
|
23
|
+
* FTS5 synchronization triggers
|
|
24
|
+
* Keep FTS5 index in sync with messages_meta content
|
|
25
|
+
*/
|
|
26
|
+
export declare const FTS_TRIGGERS = "\nCREATE TRIGGER IF NOT EXISTS messages_fts_insert AFTER INSERT ON messages_meta BEGIN\n INSERT INTO messages_fts(rowid, content) VALUES (new.rowid, new.content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS messages_fts_delete AFTER DELETE ON messages_meta BEGIN\n INSERT INTO messages_fts(messages_fts, rowid, content) VALUES('delete', old.rowid, old.content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS messages_fts_update AFTER UPDATE ON messages_meta BEGIN\n INSERT INTO messages_fts(messages_fts, rowid, content) VALUES('delete', old.rowid, old.content);\n INSERT INTO messages_fts(rowid, content) VALUES (new.rowid, new.content);\nEND;\n";
|
|
27
|
+
/**
|
|
28
|
+
* Tool uses table - stores tool invocation records
|
|
29
|
+
*/
|
|
30
|
+
export declare const TOOL_USES_TABLE = "\nCREATE TABLE IF NOT EXISTS tool_uses (\n id TEXT PRIMARY KEY,\n session_id TEXT NOT NULL,\n name TEXT NOT NULL,\n input TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n status TEXT NOT NULL CHECK (status IN ('pending', 'success', 'error')),\n result TEXT,\n FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE\n);\nCREATE INDEX IF NOT EXISTS idx_tool_uses_session ON tool_uses(session_id);\nCREATE INDEX IF NOT EXISTS idx_tool_uses_name ON tool_uses(name);\n";
|
|
31
|
+
/**
|
|
32
|
+
* Links table - graph-like relationships between entities
|
|
33
|
+
*/
|
|
34
|
+
export declare const LINKS_TABLE = "\nCREATE TABLE IF NOT EXISTS links (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n source_type TEXT NOT NULL CHECK (source_type IN ('session', 'message', 'topic')),\n source_id TEXT NOT NULL,\n target_type TEXT NOT NULL CHECK (target_type IN ('session', 'message', 'topic')),\n target_id TEXT NOT NULL,\n relationship TEXT NOT NULL CHECK (relationship IN ('mentions', 'related_to', 'continues')),\n weight REAL DEFAULT 1.0 CHECK (weight >= 0 AND weight <= 1),\n UNIQUE(source_type, source_id, target_type, target_id, relationship)\n);\nCREATE INDEX IF NOT EXISTS idx_links_source ON links(source_type, source_id);\nCREATE INDEX IF NOT EXISTS idx_links_target ON links(target_type, target_id);\n";
|
|
35
|
+
/**
|
|
36
|
+
* Topics table - stores extracted topics
|
|
37
|
+
*/
|
|
38
|
+
export declare const TOPICS_TABLE = "\nCREATE TABLE IF NOT EXISTS topics (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n name TEXT UNIQUE NOT NULL,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_topics_name ON topics(name);\n";
|
|
39
|
+
/**
|
|
40
|
+
* Extraction state table - tracks sync progress
|
|
41
|
+
*/
|
|
42
|
+
export declare const EXTRACTION_STATE_TABLE = "\nCREATE TABLE IF NOT EXISTS extraction_state (\n id TEXT PRIMARY KEY,\n session_path TEXT UNIQUE NOT NULL,\n started_at TEXT NOT NULL,\n status TEXT NOT NULL CHECK (status IN ('pending', 'in_progress', 'complete', 'error')),\n completed_at TEXT,\n messages_extracted INTEGER DEFAULT 0,\n error_message TEXT,\n file_mtime TEXT,\n file_size INTEGER\n);\nCREATE INDEX IF NOT EXISTS idx_extraction_session_path ON extraction_state(session_path);\nCREATE INDEX IF NOT EXISTS idx_extraction_status ON extraction_state(status);\n";
|
|
43
|
+
/**
|
|
44
|
+
* Entities table - stores extracted metadata (concepts, files, decisions, terms)
|
|
45
|
+
*/
|
|
46
|
+
export declare const ENTITIES_TABLE = "\nCREATE TABLE IF NOT EXISTS entities (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n type TEXT NOT NULL CHECK (type IN ('concept', 'file', 'decision', 'term')),\n name TEXT NOT NULL,\n metadata TEXT,\n confidence REAL DEFAULT 1.0 CHECK (confidence >= 0 AND confidence <= 1),\n created_at TEXT DEFAULT (datetime('now')),\n UNIQUE(type, name)\n);\nCREATE INDEX IF NOT EXISTS idx_entities_type ON entities(type);\nCREATE INDEX IF NOT EXISTS idx_entities_name ON entities(name);\n";
|
|
47
|
+
/**
|
|
48
|
+
* Session-Entity links - many-to-many relationship with frequency tracking
|
|
49
|
+
*/
|
|
50
|
+
export declare const SESSION_ENTITIES_TABLE = "\nCREATE TABLE IF NOT EXISTS session_entities (\n session_id TEXT NOT NULL,\n entity_id INTEGER NOT NULL,\n frequency INTEGER DEFAULT 1,\n FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE,\n FOREIGN KEY (entity_id) REFERENCES entities(id) ON DELETE CASCADE,\n PRIMARY KEY (session_id, entity_id)\n);\n";
|
|
51
|
+
/**
|
|
52
|
+
* Entity-Entity links - cross-project relationships between entities
|
|
53
|
+
*/
|
|
54
|
+
export declare const ENTITY_LINKS_TABLE = "\nCREATE TABLE IF NOT EXISTS entity_links (\n source_id INTEGER NOT NULL,\n target_id INTEGER NOT NULL,\n relationship TEXT NOT NULL CHECK (relationship IN ('related', 'implies', 'contradicts')),\n weight REAL DEFAULT 1.0 CHECK (weight >= 0 AND weight <= 1),\n FOREIGN KEY (source_id) REFERENCES entities(id) ON DELETE CASCADE,\n FOREIGN KEY (target_id) REFERENCES entities(id) ON DELETE CASCADE,\n PRIMARY KEY (source_id, target_id, relationship)\n);\n";
|
|
55
|
+
/**
|
|
56
|
+
* Embedding state table - tracks which messages have been embedded
|
|
57
|
+
* and with which model, for incremental embedding and re-embedding detection.
|
|
58
|
+
*
|
|
59
|
+
* Always created regardless of sqlite-vec availability (regular SQL table).
|
|
60
|
+
*/
|
|
61
|
+
export declare const EMBEDDING_STATE_TABLE = "\nCREATE TABLE IF NOT EXISTS embedding_state (\n message_id INTEGER PRIMARY KEY,\n embedded_at TEXT NOT NULL,\n model_hash TEXT NOT NULL,\n FOREIGN KEY (message_id) REFERENCES messages_meta(rowid) ON DELETE CASCADE\n);\nCREATE INDEX IF NOT EXISTS idx_embedding_state_model ON embedding_state(model_hash);\n";
|
|
62
|
+
/**
|
|
63
|
+
* Message embeddings vec0 virtual table - stores vector embeddings for messages.
|
|
64
|
+
*
|
|
65
|
+
* Only created when sqlite-vec extension is loaded (sqliteVecAvailable: true).
|
|
66
|
+
* Uses 384-dimensional float vectors matching all-MiniLM-L6-v2 default model.
|
|
67
|
+
*/
|
|
68
|
+
export declare const MESSAGE_EMBEDDINGS_TABLE = "\nCREATE VIRTUAL TABLE IF NOT EXISTS message_embeddings USING vec0(\n embedding float[384]\n);\n";
|
|
69
|
+
/**
|
|
70
|
+
* Migration: Add model_name column to embedding_state.
|
|
71
|
+
*
|
|
72
|
+
* The model_name stores the human-readable model identifier (e.g., "Xenova/all-MiniLM-L6-v2")
|
|
73
|
+
* alongside the model_hash. Required for user-facing prompts like "Model changed from X to Y"
|
|
74
|
+
* where X and Y must be readable model names, not opaque hex hashes.
|
|
75
|
+
*
|
|
76
|
+
* Uses ALTER TABLE with DEFAULT '' so existing rows (if any) get an empty string,
|
|
77
|
+
* and new rows always store the model name explicitly.
|
|
78
|
+
*/
|
|
79
|
+
export declare const EMBEDDING_STATE_ADD_MODEL_NAME = "\nALTER TABLE embedding_state ADD COLUMN model_name TEXT NOT NULL DEFAULT '';\n";
|
|
80
|
+
/**
|
|
81
|
+
* Memory files table - stores indexed legacy markdown sidecar files
|
|
82
|
+
*/
|
|
83
|
+
export declare const MEMORY_FILES_TABLE = "\nCREATE TABLE IF NOT EXISTS memory_files (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n file_path TEXT UNIQUE NOT NULL,\n file_type TEXT NOT NULL CHECK (file_type IN ('daily_log', 'decisions', 'learnings', 'user_prefs')),\n project_encoded TEXT,\n content TEXT NOT NULL,\n content_hash TEXT NOT NULL,\n last_indexed_at TEXT NOT NULL,\n created_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_memory_files_type ON memory_files(file_type);\nCREATE INDEX IF NOT EXISTS idx_memory_files_project ON memory_files(project_encoded);\n";
|
|
84
|
+
/**
|
|
85
|
+
* Memory files FTS5 virtual table - external content pattern
|
|
86
|
+
* References memory_files for content storage
|
|
87
|
+
*/
|
|
88
|
+
export declare const MEMORY_FILES_FTS_TABLE = "\nCREATE VIRTUAL TABLE IF NOT EXISTS memory_files_fts USING fts5(\n content,\n content=memory_files,\n content_rowid=id,\n tokenize='porter unicode61'\n);\n";
|
|
89
|
+
/**
|
|
90
|
+
* Memory files FTS5 synchronization triggers
|
|
91
|
+
* Keep memory_files_fts index in sync with memory_files content.
|
|
92
|
+
* Follows the same pattern as FTS_TRIGGERS for messages_fts.
|
|
93
|
+
*/
|
|
94
|
+
export declare const MEMORY_FILES_FTS_TRIGGERS = "\nCREATE TRIGGER IF NOT EXISTS memory_files_fts_insert AFTER INSERT ON memory_files BEGIN\n INSERT INTO memory_files_fts(rowid, content) VALUES (new.id, new.content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS memory_files_fts_delete AFTER DELETE ON memory_files BEGIN\n INSERT INTO memory_files_fts(memory_files_fts, rowid, content) VALUES('delete', old.id, old.content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS memory_files_fts_update AFTER UPDATE ON memory_files BEGIN\n INSERT INTO memory_files_fts(memory_files_fts, rowid, content) VALUES('delete', old.id, old.content);\n INSERT INTO memory_files_fts(rowid, content) VALUES (new.id, new.content);\nEND;\n";
|
|
95
|
+
/**
|
|
96
|
+
* Friction log table - stores friction entries for tool self-improvement
|
|
97
|
+
*/
|
|
98
|
+
export declare const FRICTION_LOG_TABLE = "\nCREATE TABLE IF NOT EXISTS friction_log (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n description TEXT NOT NULL,\n severity TEXT NOT NULL DEFAULT 'medium' CHECK (severity IN ('low', 'medium', 'high', 'critical')),\n category TEXT NOT NULL DEFAULT 'cli',\n tool TEXT NOT NULL DEFAULT 'memory',\n tags TEXT,\n status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'resolved', 'wont-fix')),\n context TEXT,\n source_project TEXT,\n logged_at TEXT NOT NULL,\n resolved_at TEXT,\n resolution TEXT,\n last_reviewed_at TEXT\n);\nCREATE INDEX IF NOT EXISTS idx_friction_status ON friction_log(status);\nCREATE INDEX IF NOT EXISTS idx_friction_severity ON friction_log(severity);\nCREATE INDEX IF NOT EXISTS idx_friction_category ON friction_log(category);\nCREATE INDEX IF NOT EXISTS idx_friction_tool ON friction_log(tool);\n";
|
|
99
|
+
/**
|
|
100
|
+
* Migration: Universalize friction_log table.
|
|
101
|
+
*
|
|
102
|
+
* Recreates friction_log with new columns (tool, tags, last_reviewed_at)
|
|
103
|
+
* and removes the category CHECK constraint. Preserves existing data
|
|
104
|
+
* with tool defaulting to 'memory'.
|
|
105
|
+
*/
|
|
106
|
+
export declare const FRICTION_LOG_UNIVERSALIZE_MIGRATION = "\nCREATE TABLE friction_log_new (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n description TEXT NOT NULL,\n severity TEXT NOT NULL DEFAULT 'medium' CHECK (severity IN ('low', 'medium', 'high', 'critical')),\n category TEXT NOT NULL DEFAULT 'cli',\n tool TEXT NOT NULL DEFAULT 'memory',\n tags TEXT,\n status TEXT NOT NULL DEFAULT 'open' CHECK (status IN ('open', 'resolved', 'wont-fix')),\n context TEXT,\n source_project TEXT,\n logged_at TEXT NOT NULL,\n resolved_at TEXT,\n resolution TEXT,\n last_reviewed_at TEXT\n);\nINSERT INTO friction_log_new (id, description, severity, category, tool, tags, status, context, source_project, logged_at, resolved_at, resolution, last_reviewed_at)\nSELECT id, description, severity, category, 'memory', NULL, status, context, source_project, logged_at, resolved_at, resolution, NULL\nFROM friction_log;\nDROP TABLE friction_log;\nALTER TABLE friction_log_new RENAME TO friction_log;\nCREATE INDEX IF NOT EXISTS idx_friction_status ON friction_log(status);\nCREATE INDEX IF NOT EXISTS idx_friction_severity ON friction_log(severity);\nCREATE INDEX IF NOT EXISTS idx_friction_category ON friction_log(category);\nCREATE INDEX IF NOT EXISTS idx_friction_tool ON friction_log(tool);\n";
|
|
107
|
+
/**
|
|
108
|
+
* Backfill state table - tracks which sessions have been backfilled
|
|
109
|
+
*
|
|
110
|
+
* Enables idempotent backfill: processed sessions are skipped on re-run.
|
|
111
|
+
* No foreign keys to sessions table (session_id is text reference only).
|
|
112
|
+
*/
|
|
113
|
+
export declare const BACKFILL_STATE_TABLE = "\nCREATE TABLE IF NOT EXISTS backfill_state (\n session_id TEXT PRIMARY KEY,\n backfilled_at TEXT NOT NULL,\n daily_log_path TEXT NOT NULL,\n success INTEGER DEFAULT 1,\n error_message TEXT\n);\n";
|
|
114
|
+
/**
|
|
115
|
+
* Facts table - derived projection of the plain-text event log.
|
|
116
|
+
*/
|
|
117
|
+
export declare const FACTS_TABLE = "\nCREATE TABLE IF NOT EXISTS facts (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n uuid TEXT UNIQUE NOT NULL,\n type TEXT NOT NULL CHECK (type IN ('decision', 'learning', 'preference', 'friction', 'observation', 'supersedence')),\n project TEXT NOT NULL,\n content TEXT NOT NULL,\n metadata TEXT,\n observed_at TEXT NOT NULL,\n superseded_at TEXT,\n superseded_by TEXT,\n created_at TEXT DEFAULT (datetime('now')),\n updated_at TEXT DEFAULT (datetime('now'))\n);\nCREATE INDEX IF NOT EXISTS idx_facts_uuid ON facts(uuid);\nCREATE INDEX IF NOT EXISTS idx_facts_project ON facts(project);\nCREATE INDEX IF NOT EXISTS idx_facts_type ON facts(type);\n";
|
|
118
|
+
/**
|
|
119
|
+
* Facts FTS5 virtual table - external content pattern.
|
|
120
|
+
* References facts table for content storage.
|
|
121
|
+
*/
|
|
122
|
+
export declare const FACTS_FTS_TABLE = "\nCREATE VIRTUAL TABLE IF NOT EXISTS facts_fts USING fts5(\n content,\n content=facts,\n content_rowid=id,\n tokenize='porter unicode61'\n);\n";
|
|
123
|
+
/**
|
|
124
|
+
* Facts FTS5 synchronization triggers.
|
|
125
|
+
*/
|
|
126
|
+
export declare const FACTS_FTS_TRIGGERS = "\nCREATE TRIGGER IF NOT EXISTS facts_fts_insert AFTER INSERT ON facts BEGIN\n INSERT INTO facts_fts(rowid, content) VALUES (new.id, new.content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS facts_fts_delete AFTER DELETE ON facts BEGIN\n INSERT INTO facts_fts(facts_fts, rowid, content) VALUES('delete', old.id, old.content);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS facts_fts_update AFTER UPDATE ON facts BEGIN\n INSERT INTO facts_fts(facts_fts, rowid, content) VALUES('delete', old.id, old.content);\n INSERT INTO facts_fts(rowid, content) VALUES (new.id, new.content);\nEND;\n";
|
|
127
|
+
/**
|
|
128
|
+
* Extraction log table - tracks run logs of LLM fact extraction.
|
|
129
|
+
*/
|
|
130
|
+
export declare const EXTRACTION_LOG_TABLE = "\nCREATE TABLE IF NOT EXISTS extraction_log (\n session_id TEXT PRIMARY KEY,\n mode TEXT NOT NULL,\n facts_added INTEGER DEFAULT 0,\n facts_updated INTEGER DEFAULT 0,\n facts_superseded INTEGER DEFAULT 0,\n facts_skipped INTEGER DEFAULT 0,\n provider TEXT NOT NULL,\n model TEXT NOT NULL,\n tokens_consumed INTEGER DEFAULT 0,\n extracted_at TEXT NOT NULL\n);\n";
|
|
131
|
+
/**
|
|
132
|
+
* Schema options for conditional table creation
|
|
133
|
+
*/
|
|
134
|
+
export interface SchemaOptions {
|
|
135
|
+
/** Whether sqlite-vec extension is loaded and vec0 tables can be created. Default: false */
|
|
136
|
+
sqliteVecAvailable?: boolean;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Sessions FTS5 virtual table - for summary full-text search
|
|
140
|
+
*
|
|
141
|
+
* Uses standalone FTS5 table (not external content) because summaries
|
|
142
|
+
* are only added/updated after session ends, and we want FTS5 to manage
|
|
143
|
+
* its own content for simplicity.
|
|
144
|
+
*/
|
|
145
|
+
export declare const SESSIONS_FTS_TABLE = "\nCREATE VIRTUAL TABLE IF NOT EXISTS sessions_fts USING fts5(\n session_id,\n summary,\n tokenize='porter unicode61'\n);\n";
|
|
146
|
+
/**
|
|
147
|
+
* Sessions FTS5 synchronization triggers
|
|
148
|
+
* Keep sessions_fts index in sync with sessions summary updates
|
|
149
|
+
*
|
|
150
|
+
* Note: INSERT trigger does not index since summary is NULL on insert.
|
|
151
|
+
* Only UPDATE trigger handles FTS indexing when summary is set.
|
|
152
|
+
*/
|
|
153
|
+
export declare const SESSIONS_FTS_TRIGGERS = "\nCREATE TRIGGER IF NOT EXISTS sessions_fts_update AFTER UPDATE OF summary ON sessions\nWHEN new.summary IS NOT NULL AND new.summary != ''\nBEGIN\n DELETE FROM sessions_fts WHERE session_id = old.id;\n INSERT INTO sessions_fts(session_id, summary) VALUES (new.id, new.summary);\nEND;\n\nCREATE TRIGGER IF NOT EXISTS sessions_fts_delete AFTER DELETE ON sessions BEGIN\n DELETE FROM sessions_fts WHERE session_id = old.id;\nEND;\n";
|
|
154
|
+
/**
|
|
155
|
+
* Complete schema SQL statements in dependency order
|
|
156
|
+
*
|
|
157
|
+
* Order matters:
|
|
158
|
+
* 1. sessions (no dependencies)
|
|
159
|
+
* 2. messages_meta (depends on sessions)
|
|
160
|
+
* 3. messages_fts (depends on messages_meta)
|
|
161
|
+
* 4. FTS triggers (depend on both messages tables)
|
|
162
|
+
* 5. tool_uses (depends on sessions)
|
|
163
|
+
* 6. links (no foreign keys)
|
|
164
|
+
* 7. topics (no dependencies)
|
|
165
|
+
* 8. extraction_state (no dependencies)
|
|
166
|
+
* 9. entities (no dependencies)
|
|
167
|
+
* 10. session_entities (depends on sessions, entities)
|
|
168
|
+
* 11. entity_links (depends on entities)
|
|
169
|
+
* 12. sessions_fts (depends on sessions)
|
|
170
|
+
* 13. sessions_fts triggers (depends on sessions, sessions_fts)
|
|
171
|
+
* 14. embedding_state (depends on messages_meta) -- always created
|
|
172
|
+
* 15. memory_files (no dependencies)
|
|
173
|
+
* 16. memory_files_fts (depends on memory_files)
|
|
174
|
+
* 17. memory_files FTS triggers (depend on both memory_files tables)
|
|
175
|
+
* 18. friction_log (no dependencies)
|
|
176
|
+
* 19. backfill_state (no dependencies)
|
|
177
|
+
*
|
|
178
|
+
* Note: message_embeddings (vec0) is NOT in this array.
|
|
179
|
+
* It is conditionally created in createSchema() when sqliteVecAvailable is true.
|
|
180
|
+
*/
|
|
181
|
+
export declare const SCHEMA_SQL: readonly string[];
|
|
182
|
+
/**
|
|
183
|
+
* Check if FTS5 extension is available in the database
|
|
184
|
+
*
|
|
185
|
+
* @param db - SQLite database instance
|
|
186
|
+
* @returns true if FTS5 is supported, false otherwise
|
|
187
|
+
*/
|
|
188
|
+
export declare function checkFts5Support(db: Database): boolean;
|
|
189
|
+
/**
|
|
190
|
+
* Create all schema tables in the database
|
|
191
|
+
*
|
|
192
|
+
* Executes all DDL statements in dependency order.
|
|
193
|
+
* Safe to call multiple times (uses IF NOT EXISTS).
|
|
194
|
+
*
|
|
195
|
+
* When sqliteVecAvailable is true, also creates the message_embeddings
|
|
196
|
+
* vec0 virtual table for vector similarity search. The embedding_state
|
|
197
|
+
* tracking table is always created regardless of sqlite-vec availability.
|
|
198
|
+
*
|
|
199
|
+
* @param db - SQLite database instance
|
|
200
|
+
* @param options - Schema creation options (defaults to sqliteVecAvailable: false)
|
|
201
|
+
* @throws Error if FTS5 is not supported or SQL execution fails
|
|
202
|
+
*/
|
|
203
|
+
export declare function createSchema(db: Database, options?: SchemaOptions): void;
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Context Service Implementation
|
|
3
|
+
*
|
|
4
|
+
* Implements project context aggregation using SQLite queries.
|
|
5
|
+
* Provides session counts, message breakdown, tool usage, and topics
|
|
6
|
+
* for a specific project.
|
|
7
|
+
*/
|
|
8
|
+
import type { Database } from "bun:sqlite";
|
|
9
|
+
import type { IProjectResolver } from "../../../application/services/smart-context-service.js";
|
|
10
|
+
/**
|
|
11
|
+
* Tool usage summary with name and count.
|
|
12
|
+
*/
|
|
13
|
+
export interface ToolUsage {
|
|
14
|
+
name: string;
|
|
15
|
+
count: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Aggregated context for a project.
|
|
19
|
+
*/
|
|
20
|
+
export interface ProjectContext {
|
|
21
|
+
projectName: string;
|
|
22
|
+
projectPathDecoded: string;
|
|
23
|
+
sessionCount: number;
|
|
24
|
+
totalMessages: number;
|
|
25
|
+
userMessages: number;
|
|
26
|
+
assistantMessages: number;
|
|
27
|
+
recentTopics: string[];
|
|
28
|
+
recentToolUses: ToolUsage[];
|
|
29
|
+
lastActivity: Date | null;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Options for context retrieval.
|
|
33
|
+
*/
|
|
34
|
+
export interface ContextOptions {
|
|
35
|
+
/** Filter to last N days (includes today) */
|
|
36
|
+
days?: number | undefined;
|
|
37
|
+
/** Maximum topics to return (default 10) */
|
|
38
|
+
topicsLimit?: number | undefined;
|
|
39
|
+
/** Maximum tools to return (default 10) */
|
|
40
|
+
toolsLimit?: number | undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* SQLite implementation of context service.
|
|
44
|
+
*
|
|
45
|
+
* Features:
|
|
46
|
+
* - LIKE match for project name substring search
|
|
47
|
+
* - Aggregation queries for counts
|
|
48
|
+
* - Time-based filtering with --days option
|
|
49
|
+
* - Tool usage breakdown sorted by count
|
|
50
|
+
* - Topics from links table (graceful empty handling)
|
|
51
|
+
*/
|
|
52
|
+
export declare class SqliteContextService {
|
|
53
|
+
private readonly db;
|
|
54
|
+
/**
|
|
55
|
+
* Create a new SqliteContextService.
|
|
56
|
+
*
|
|
57
|
+
* @param db - Initialized SQLite database with schema applied
|
|
58
|
+
*/
|
|
59
|
+
constructor(db: Database);
|
|
60
|
+
/**
|
|
61
|
+
* Get aggregated context for a project.
|
|
62
|
+
*
|
|
63
|
+
* @param projectFilter Project name or substring to filter by
|
|
64
|
+
* @param options Context retrieval options
|
|
65
|
+
* @returns Project context or null if not found
|
|
66
|
+
*/
|
|
67
|
+
getProjectContext(projectFilter: string, options?: ContextOptions): Promise<ProjectContext | null>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* SQLite implementation of IProjectResolver.
|
|
71
|
+
*
|
|
72
|
+
* Resolves project names to encoded paths and display names
|
|
73
|
+
* using the sessions table. Supports exact (case-insensitive)
|
|
74
|
+
* and substring matching, ranked by session count.
|
|
75
|
+
*/
|
|
76
|
+
export declare class SqliteProjectResolver implements IProjectResolver {
|
|
77
|
+
private readonly db;
|
|
78
|
+
constructor(db: Database);
|
|
79
|
+
/**
|
|
80
|
+
* Resolve a project name or filter to its encoded path.
|
|
81
|
+
*
|
|
82
|
+
* @param projectFilter Project name or substring
|
|
83
|
+
* @returns Encoded path or null if not found
|
|
84
|
+
*/
|
|
85
|
+
resolveProjectEncoded(projectFilter: string): string | null;
|
|
86
|
+
/**
|
|
87
|
+
* Resolve a project name or filter to its display name.
|
|
88
|
+
*
|
|
89
|
+
* @param projectFilter Project name or substring
|
|
90
|
+
* @returns Display name or null if not found
|
|
91
|
+
*/
|
|
92
|
+
resolveProjectName(projectFilter: string): string | null;
|
|
93
|
+
}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HybridSearchService
|
|
3
|
+
*
|
|
4
|
+
* Composes Fts5SearchService, EmbeddingRepository, and EmbeddingProviderFactory
|
|
5
|
+
* into a unified search interface supporting four modes: auto, fts, vector, hybrid.
|
|
6
|
+
*
|
|
7
|
+
* Implements ISearchService from the domain ports layer so it can be a drop-in
|
|
8
|
+
* replacement for the FTS-only search service.
|
|
9
|
+
*
|
|
10
|
+
* Mode resolution: explicit CLI mode > config search.defaultMode > 'auto'
|
|
11
|
+
*
|
|
12
|
+
* Degradation:
|
|
13
|
+
* - auto mode: silently uses FTS when vector unavailable
|
|
14
|
+
* - hybrid mode: degrades to FTS when vector fails
|
|
15
|
+
* - vector mode: throws VECTOR_UNAVAILABLE (explicit user intent)
|
|
16
|
+
* - fts mode: never touches vector infrastructure
|
|
17
|
+
*/
|
|
18
|
+
import type { Database } from "bun:sqlite";
|
|
19
|
+
import type { ISearchService, SearchMode, HybridSearchOptions } from "../../../domain/ports/services.js";
|
|
20
|
+
import type { SearchQuery } from "../../../domain/value-objects/search-query.js";
|
|
21
|
+
import { SearchResult } from "../../../domain/value-objects/search-result.js";
|
|
22
|
+
import type { Fts5SearchService } from "./search-service.js";
|
|
23
|
+
import type { EmbeddingRepository } from "../repositories/embedding-repository.js";
|
|
24
|
+
import type { EmbeddingProviderFactory } from "../../embedding/embedding-provider-factory.js";
|
|
25
|
+
import type { MemoryConfig } from "../../hooks/config-manager.js";
|
|
26
|
+
/**
|
|
27
|
+
* Dependencies injected via constructor.
|
|
28
|
+
*/
|
|
29
|
+
export interface HybridSearchDeps {
|
|
30
|
+
db: Database;
|
|
31
|
+
fts5Service: Fts5SearchService;
|
|
32
|
+
embeddingRepo: EmbeddingRepository;
|
|
33
|
+
providerFactory: EmbeddingProviderFactory;
|
|
34
|
+
config: MemoryConfig;
|
|
35
|
+
sqliteVecAvailable: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Metadata about the last search operation.
|
|
39
|
+
*/
|
|
40
|
+
export interface SearchMeta {
|
|
41
|
+
/** The effective search mode used */
|
|
42
|
+
mode: SearchMode;
|
|
43
|
+
/** Reason for the mode selection */
|
|
44
|
+
modeReason: string;
|
|
45
|
+
/** Whether the search degraded from requested mode */
|
|
46
|
+
degraded: boolean;
|
|
47
|
+
/** Reason for degradation, if any */
|
|
48
|
+
degradationReason?: string | undefined;
|
|
49
|
+
/** Fraction of messages with embeddings (0-1) */
|
|
50
|
+
embeddingCoverage: number;
|
|
51
|
+
/** System capabilities for this search */
|
|
52
|
+
capabilities: {
|
|
53
|
+
fts: boolean;
|
|
54
|
+
vector: boolean;
|
|
55
|
+
hybrid: boolean;
|
|
56
|
+
};
|
|
57
|
+
/** Total search time in milliseconds */
|
|
58
|
+
timingMs: number;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* HybridSearchService composes FTS5 and vector search with RRF fusion.
|
|
62
|
+
*
|
|
63
|
+
* Implements ISearchService for drop-in compatibility.
|
|
64
|
+
*/
|
|
65
|
+
export declare class HybridSearchService implements ISearchService {
|
|
66
|
+
private readonly db;
|
|
67
|
+
private readonly fts5Service;
|
|
68
|
+
private readonly embeddingRepo;
|
|
69
|
+
private readonly providerFactory;
|
|
70
|
+
private readonly config;
|
|
71
|
+
private readonly sqliteVecAvailable;
|
|
72
|
+
private lastSearchMeta;
|
|
73
|
+
constructor(deps: HybridSearchDeps);
|
|
74
|
+
/**
|
|
75
|
+
* Get metadata from the last search operation.
|
|
76
|
+
*/
|
|
77
|
+
getLastSearchMeta(): SearchMeta | null;
|
|
78
|
+
/**
|
|
79
|
+
* Search for content using the configured mode.
|
|
80
|
+
*
|
|
81
|
+
* Supports FTS, vector, hybrid, and auto modes.
|
|
82
|
+
* Degrades gracefully when vector components are unavailable.
|
|
83
|
+
*/
|
|
84
|
+
search(query: SearchQuery, options?: HybridSearchOptions): Promise<SearchResult[]>;
|
|
85
|
+
/**
|
|
86
|
+
* Resolve the effective search mode from requested mode, config, and capabilities.
|
|
87
|
+
*/
|
|
88
|
+
private resolveMode;
|
|
89
|
+
/**
|
|
90
|
+
* Apply temporal decay to search results using their embedded timestamps.
|
|
91
|
+
*
|
|
92
|
+
* Builds decay by computing age from each result's timestamp,
|
|
93
|
+
* applying the standard half-life formula, and re-sorting by
|
|
94
|
+
* decayed score. This is the single point where temporal decay
|
|
95
|
+
* is applied, regardless of search mode (FTS, vector, hybrid).
|
|
96
|
+
*/
|
|
97
|
+
private applyDecayToResults;
|
|
98
|
+
/**
|
|
99
|
+
* FTS-only search path. Delegates directly to Fts5SearchService.
|
|
100
|
+
*/
|
|
101
|
+
private ftsSearch;
|
|
102
|
+
/**
|
|
103
|
+
* Get or initialize the embedding provider.
|
|
104
|
+
*
|
|
105
|
+
* For auto/hybrid mode: returns null on failure (allows degradation).
|
|
106
|
+
* For vector mode: throws on failure (user explicitly requested).
|
|
107
|
+
*/
|
|
108
|
+
private getProvider;
|
|
109
|
+
/**
|
|
110
|
+
* Embed the query text using the configured provider.
|
|
111
|
+
*/
|
|
112
|
+
private embedQuery;
|
|
113
|
+
/**
|
|
114
|
+
* Check for dimension mismatch between stored embeddings and current provider.
|
|
115
|
+
*
|
|
116
|
+
* The vec0 table was created with a specific dimension. If the provider
|
|
117
|
+
* produces embeddings of a different dimension, KNN queries will fail.
|
|
118
|
+
* We detect this by comparing the provider's dimensions against the
|
|
119
|
+
* schema's stored dimension (derived from the embedding table definition).
|
|
120
|
+
*
|
|
121
|
+
* Returns the mismatch reason string if mismatch found, null otherwise.
|
|
122
|
+
*/
|
|
123
|
+
private checkDimensionMismatch;
|
|
124
|
+
/**
|
|
125
|
+
* Get the dimension count of stored embeddings.
|
|
126
|
+
* Queries the first embedding to determine its dimension.
|
|
127
|
+
*/
|
|
128
|
+
private getStoredEmbeddingDimensions;
|
|
129
|
+
/**
|
|
130
|
+
* Vector-only search path.
|
|
131
|
+
* Embeds query, runs KNN, hydrates results.
|
|
132
|
+
*/
|
|
133
|
+
private vectorSearch;
|
|
134
|
+
/**
|
|
135
|
+
* Hybrid search path.
|
|
136
|
+
* Runs FTS and vector searches, combines with RRF, applies temporal decay.
|
|
137
|
+
* Returns results plus degradation status.
|
|
138
|
+
*/
|
|
139
|
+
private hybridSearch;
|
|
140
|
+
/**
|
|
141
|
+
* Build a map from message ID to rowid for FTS results.
|
|
142
|
+
*/
|
|
143
|
+
private buildFtsRowidMap;
|
|
144
|
+
/**
|
|
145
|
+
* Hydrate message metadata by rowids.
|
|
146
|
+
*/
|
|
147
|
+
private hydrateByRowids;
|
|
148
|
+
/**
|
|
149
|
+
* Generate a snippet for vector-only results (first 200 chars).
|
|
150
|
+
*/
|
|
151
|
+
private vectorSnippet;
|
|
152
|
+
/**
|
|
153
|
+
* Check if a message passes the search filters.
|
|
154
|
+
*/
|
|
155
|
+
private passesFilters;
|
|
156
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Services
|
|
3
|
+
*
|
|
4
|
+
* Service implementations for search and other database operations.
|
|
5
|
+
*/
|
|
6
|
+
export { Fts5SearchService } from "./search-service.js";
|
|
7
|
+
export { HybridSearchService } from "./hybrid-search-service.js";
|
|
8
|
+
export type { HybridSearchDeps, SearchMeta } from "./hybrid-search-service.js";
|
|
9
|
+
export { SqliteStatsService } from "./stats-service.js";
|
|
10
|
+
export { SqliteContextService, SqliteProjectResolver, type ProjectContext, type ContextOptions, type ToolUsage, } from "./context-service.js";
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FTS5 Search Service Implementation
|
|
3
|
+
*
|
|
4
|
+
* Implements ISearchService using SQLite FTS5 full-text search.
|
|
5
|
+
* Uses BM25 ranking algorithm for relevance scoring and snippet extraction.
|
|
6
|
+
*/
|
|
7
|
+
import type { Database } from "bun:sqlite";
|
|
8
|
+
import type { ISearchService, SearchOptions } from "../../../domain/ports/services.js";
|
|
9
|
+
import type { SearchQuery } from "../../../domain/value-objects/search-query.js";
|
|
10
|
+
import { SearchResult } from "../../../domain/value-objects/search-result.js";
|
|
11
|
+
/**
|
|
12
|
+
* FTS5-based implementation of ISearchService
|
|
13
|
+
*
|
|
14
|
+
* Features:
|
|
15
|
+
* - Full-text search using FTS5 MATCH operator
|
|
16
|
+
* - BM25 relevance ranking normalized to 0-1 range
|
|
17
|
+
* - Snippet extraction with match highlighting
|
|
18
|
+
* - Filtering by project, role, and date range
|
|
19
|
+
*
|
|
20
|
+
* CRITICAL: Always uses MATCH operator for FTS5 queries (never =).
|
|
21
|
+
* Using = would cause a full table scan defeating the purpose of FTS5.
|
|
22
|
+
*/
|
|
23
|
+
export declare class Fts5SearchService implements ISearchService {
|
|
24
|
+
private readonly db;
|
|
25
|
+
/**
|
|
26
|
+
* Create a new Fts5SearchService
|
|
27
|
+
*
|
|
28
|
+
* @param db - Initialized SQLite database with FTS5 schema applied
|
|
29
|
+
*/
|
|
30
|
+
constructor(db: Database);
|
|
31
|
+
/**
|
|
32
|
+
* Search for content matching the query.
|
|
33
|
+
*
|
|
34
|
+
* Uses FTS5 MATCH operator with BM25 ranking. Results are normalized
|
|
35
|
+
* to 0-1 score range (higher = more relevant) and mapped to SearchResult
|
|
36
|
+
* value objects.
|
|
37
|
+
*
|
|
38
|
+
* @param query - Validated search query
|
|
39
|
+
* @param options - Optional filters and limits
|
|
40
|
+
* @returns Array of search results, ranked by relevance
|
|
41
|
+
*/
|
|
42
|
+
search(query: SearchQuery, options?: SearchOptions): Promise<SearchResult[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Build the search SQL query with optional filters
|
|
45
|
+
*/
|
|
46
|
+
private buildSearchQuery;
|
|
47
|
+
/**
|
|
48
|
+
* Normalize BM25 scores to 0-1 range
|
|
49
|
+
*
|
|
50
|
+
* BM25 returns negative values where more negative = better match.
|
|
51
|
+
* We normalize so that:
|
|
52
|
+
* - Best match (most negative) gets score 1.0
|
|
53
|
+
* - Worst match (least negative) gets score based on relative ranking
|
|
54
|
+
* - Single result gets score 1.0
|
|
55
|
+
*/
|
|
56
|
+
private normalizeBm25Scores;
|
|
57
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SQLite Stats Service Implementation
|
|
3
|
+
*
|
|
4
|
+
* Implements IStatsService using SQLite queries for database statistics.
|
|
5
|
+
* Provides total counts, database size, and per-project breakdown.
|
|
6
|
+
*/
|
|
7
|
+
import type { Database } from "bun:sqlite";
|
|
8
|
+
import type { IStatsService, StatsResult } from "../../../domain/ports/services.js";
|
|
9
|
+
/**
|
|
10
|
+
* SQLite implementation of IStatsService.
|
|
11
|
+
*
|
|
12
|
+
* Features:
|
|
13
|
+
* - Single query with subqueries for totals (efficient)
|
|
14
|
+
* - Table-valued PRAGMA for database size
|
|
15
|
+
* - GROUP BY with proper COUNT for project breakdown
|
|
16
|
+
*/
|
|
17
|
+
export declare class SqliteStatsService implements IStatsService {
|
|
18
|
+
private readonly db;
|
|
19
|
+
/**
|
|
20
|
+
* Create a new SqliteStatsService.
|
|
21
|
+
*
|
|
22
|
+
* @param db - Initialized SQLite database with schema applied
|
|
23
|
+
*/
|
|
24
|
+
constructor(db: Database);
|
|
25
|
+
/**
|
|
26
|
+
* Get database-wide statistics with per-project breakdown.
|
|
27
|
+
*
|
|
28
|
+
* When projectLimit is applied, totals (sessions and messages) are computed
|
|
29
|
+
* from the filtered project breakdown, so they match what's displayed.
|
|
30
|
+
* Database size and tool uses remain as database-wide totals.
|
|
31
|
+
*
|
|
32
|
+
* @param projectLimit Maximum projects to include in breakdown (default 10)
|
|
33
|
+
* @returns Statistics including totals and per-project breakdown
|
|
34
|
+
*/
|
|
35
|
+
getStats(projectLimit?: number): Promise<StatsResult>;
|
|
36
|
+
}
|