claude-memory-layer 1.0.9 → 1.0.10
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/.history/package_20260202121115.json +49 -0
- package/dist/cli/index.js +107 -3
- package/dist/cli/index.js.map +2 -2
- package/dist/core/index.js +78 -0
- package/dist/core/index.js.map +2 -2
- package/dist/hooks/post-tool-use.js +107 -3
- package/dist/hooks/post-tool-use.js.map +2 -2
- package/dist/hooks/session-end.js +107 -3
- package/dist/hooks/session-end.js.map +2 -2
- package/dist/hooks/session-start.js +107 -3
- package/dist/hooks/session-start.js.map +2 -2
- package/dist/hooks/stop.js +107 -3
- package/dist/hooks/stop.js.map +2 -2
- package/dist/hooks/user-prompt-submit.js +140 -70
- package/dist/hooks/user-prompt-submit.js.map +2 -2
- package/dist/server/api/index.js +107 -3
- package/dist/server/api/index.js.map +2 -2
- package/dist/server/index.js +107 -3
- package/dist/server/index.js.map +2 -2
- package/dist/services/memory-service.js +124 -3
- package/dist/services/memory-service.js.map +2 -2
- package/package.json +1 -1
- package/src/core/sqlite-event-store.ts +98 -0
- package/src/hooks/user-prompt-submit.ts +34 -60
- package/src/services/memory-service.ts +71 -4
package/dist/server/index.js
CHANGED
|
@@ -1048,6 +1048,28 @@ var SQLiteEventStore = class {
|
|
|
1048
1048
|
CREATE INDEX IF NOT EXISTS idx_consolidated_confidence ON consolidated_memories(confidence);
|
|
1049
1049
|
CREATE INDEX IF NOT EXISTS idx_continuity_created ON continuity_log(created_at);
|
|
1050
1050
|
CREATE INDEX IF NOT EXISTS idx_embedding_outbox_status ON embedding_outbox(status);
|
|
1051
|
+
|
|
1052
|
+
-- FTS5 Full-Text Search for fast keyword search
|
|
1053
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS events_fts USING fts5(
|
|
1054
|
+
content,
|
|
1055
|
+
event_id UNINDEXED,
|
|
1056
|
+
content='events',
|
|
1057
|
+
content_rowid='rowid'
|
|
1058
|
+
);
|
|
1059
|
+
|
|
1060
|
+
-- Triggers to keep FTS in sync with events table
|
|
1061
|
+
CREATE TRIGGER IF NOT EXISTS events_fts_insert AFTER INSERT ON events BEGIN
|
|
1062
|
+
INSERT INTO events_fts(rowid, content, event_id) VALUES (NEW.rowid, NEW.content, NEW.id);
|
|
1063
|
+
END;
|
|
1064
|
+
|
|
1065
|
+
CREATE TRIGGER IF NOT EXISTS events_fts_delete AFTER DELETE ON events BEGIN
|
|
1066
|
+
INSERT INTO events_fts(events_fts, rowid, content, event_id) VALUES('delete', OLD.rowid, OLD.content, OLD.id);
|
|
1067
|
+
END;
|
|
1068
|
+
|
|
1069
|
+
CREATE TRIGGER IF NOT EXISTS events_fts_update AFTER UPDATE ON events BEGIN
|
|
1070
|
+
INSERT INTO events_fts(events_fts, rowid, content, event_id) VALUES('delete', OLD.rowid, OLD.content, OLD.id);
|
|
1071
|
+
INSERT INTO events_fts(rowid, content, event_id) VALUES (NEW.rowid, NEW.content, NEW.id);
|
|
1072
|
+
END;
|
|
1051
1073
|
`);
|
|
1052
1074
|
const tableInfo = sqliteAll(this.db, "PRAGMA table_info(events)", []);
|
|
1053
1075
|
const columnNames = tableInfo.map((col) => col.name);
|
|
@@ -1488,6 +1510,62 @@ var SQLiteEventStore = class {
|
|
|
1488
1510
|
);
|
|
1489
1511
|
return rows.map((row) => this.rowToEvent(row));
|
|
1490
1512
|
}
|
|
1513
|
+
/**
|
|
1514
|
+
* Fast keyword search using FTS5
|
|
1515
|
+
* Returns events matching the search query, ranked by relevance
|
|
1516
|
+
*/
|
|
1517
|
+
async keywordSearch(query, limit = 10) {
|
|
1518
|
+
await this.initialize();
|
|
1519
|
+
const searchTerms = query.replace(/['"(){}[\]^~*?:\\/-]/g, " ").split(/\s+/).filter((term) => term.length > 1).map((term) => `"${term}"*`).join(" OR ");
|
|
1520
|
+
if (!searchTerms) {
|
|
1521
|
+
return [];
|
|
1522
|
+
}
|
|
1523
|
+
try {
|
|
1524
|
+
const rows = sqliteAll(
|
|
1525
|
+
this.db,
|
|
1526
|
+
`SELECT e.*, fts.rank
|
|
1527
|
+
FROM events_fts fts
|
|
1528
|
+
JOIN events e ON e.id = fts.event_id
|
|
1529
|
+
WHERE events_fts MATCH ?
|
|
1530
|
+
ORDER BY fts.rank
|
|
1531
|
+
LIMIT ?`,
|
|
1532
|
+
[searchTerms, limit]
|
|
1533
|
+
);
|
|
1534
|
+
return rows.map((row) => ({
|
|
1535
|
+
event: this.rowToEvent(row),
|
|
1536
|
+
rank: row.rank
|
|
1537
|
+
}));
|
|
1538
|
+
} catch (error) {
|
|
1539
|
+
const likePattern = `%${query}%`;
|
|
1540
|
+
const rows = sqliteAll(
|
|
1541
|
+
this.db,
|
|
1542
|
+
`SELECT *, 0 as rank FROM events
|
|
1543
|
+
WHERE content LIKE ?
|
|
1544
|
+
ORDER BY timestamp DESC
|
|
1545
|
+
LIMIT ?`,
|
|
1546
|
+
[likePattern, limit]
|
|
1547
|
+
);
|
|
1548
|
+
return rows.map((row) => ({
|
|
1549
|
+
event: this.rowToEvent(row),
|
|
1550
|
+
rank: 0
|
|
1551
|
+
}));
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
/**
|
|
1555
|
+
* Rebuild FTS index from existing events
|
|
1556
|
+
* Call this once after upgrading to FTS5
|
|
1557
|
+
*/
|
|
1558
|
+
async rebuildFtsIndex() {
|
|
1559
|
+
await this.initialize();
|
|
1560
|
+
const countRow = sqliteGet(this.db, "SELECT COUNT(*) as count FROM events", []);
|
|
1561
|
+
const totalEvents = countRow?.count ?? 0;
|
|
1562
|
+
sqliteExec(this.db, `
|
|
1563
|
+
DELETE FROM events_fts;
|
|
1564
|
+
INSERT INTO events_fts(rowid, content, event_id)
|
|
1565
|
+
SELECT rowid, content, id FROM events;
|
|
1566
|
+
`);
|
|
1567
|
+
return totalEvents;
|
|
1568
|
+
}
|
|
1491
1569
|
/**
|
|
1492
1570
|
* Get database instance for direct access
|
|
1493
1571
|
*/
|
|
@@ -4546,9 +4624,11 @@ var MemoryService = class {
|
|
|
4546
4624
|
sharedStoreConfig = null;
|
|
4547
4625
|
projectHash = null;
|
|
4548
4626
|
readOnly;
|
|
4627
|
+
lightweightMode;
|
|
4549
4628
|
constructor(config) {
|
|
4550
4629
|
const storagePath = this.expandPath(config.storagePath);
|
|
4551
4630
|
this.readOnly = config.readOnly ?? false;
|
|
4631
|
+
this.lightweightMode = config.lightweightMode ?? false;
|
|
4552
4632
|
if (!this.readOnly && !fs.existsSync(storagePath)) {
|
|
4553
4633
|
fs.mkdirSync(storagePath, { recursive: true });
|
|
4554
4634
|
}
|
|
@@ -4595,6 +4675,10 @@ var MemoryService = class {
|
|
|
4595
4675
|
if (this.initialized)
|
|
4596
4676
|
return;
|
|
4597
4677
|
await this.sqliteStore.initialize();
|
|
4678
|
+
if (this.lightweightMode) {
|
|
4679
|
+
this.initialized = true;
|
|
4680
|
+
return;
|
|
4681
|
+
}
|
|
4598
4682
|
if (this.analyticsStore) {
|
|
4599
4683
|
try {
|
|
4600
4684
|
await this.analyticsStore.initialize();
|
|
@@ -4764,9 +4848,6 @@ var MemoryService = class {
|
|
|
4764
4848
|
*/
|
|
4765
4849
|
async retrieveMemories(query, options) {
|
|
4766
4850
|
await this.initialize();
|
|
4767
|
-
if (this.vectorWorker) {
|
|
4768
|
-
await this.vectorWorker.processAll();
|
|
4769
|
-
}
|
|
4770
4851
|
if (options?.includeShared && this.sharedStore) {
|
|
4771
4852
|
return this.retriever.retrieveUnified(query, {
|
|
4772
4853
|
...options,
|
|
@@ -4776,6 +4857,29 @@ var MemoryService = class {
|
|
|
4776
4857
|
}
|
|
4777
4858
|
return this.retriever.retrieve(query, options);
|
|
4778
4859
|
}
|
|
4860
|
+
/**
|
|
4861
|
+
* Fast keyword search using SQLite FTS5
|
|
4862
|
+
* Much faster than vector search - no embedding model needed
|
|
4863
|
+
*/
|
|
4864
|
+
async keywordSearch(query, options) {
|
|
4865
|
+
await this.initialize();
|
|
4866
|
+
const results = await this.sqliteStore.keywordSearch(query, options?.topK ?? 10);
|
|
4867
|
+
const maxRank = Math.min(...results.map((r) => r.rank), -1e-3);
|
|
4868
|
+
const minRank = Math.max(...results.map((r) => r.rank), -1e3);
|
|
4869
|
+
const rankRange = maxRank - minRank || 1;
|
|
4870
|
+
return results.map((r) => ({
|
|
4871
|
+
event: r.event,
|
|
4872
|
+
score: 1 - (r.rank - minRank) / rankRange
|
|
4873
|
+
// Normalize to 0-1
|
|
4874
|
+
})).filter((r) => !options?.minScore || r.score >= options.minScore);
|
|
4875
|
+
}
|
|
4876
|
+
/**
|
|
4877
|
+
* Rebuild FTS index (call after database upgrade)
|
|
4878
|
+
*/
|
|
4879
|
+
async rebuildFtsIndex() {
|
|
4880
|
+
await this.initialize();
|
|
4881
|
+
return this.sqliteStore.rebuildFtsIndex();
|
|
4882
|
+
}
|
|
4779
4883
|
/**
|
|
4780
4884
|
* Get session history
|
|
4781
4885
|
*/
|