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/api/index.js
CHANGED
|
@@ -1039,6 +1039,28 @@ var SQLiteEventStore = class {
|
|
|
1039
1039
|
CREATE INDEX IF NOT EXISTS idx_consolidated_confidence ON consolidated_memories(confidence);
|
|
1040
1040
|
CREATE INDEX IF NOT EXISTS idx_continuity_created ON continuity_log(created_at);
|
|
1041
1041
|
CREATE INDEX IF NOT EXISTS idx_embedding_outbox_status ON embedding_outbox(status);
|
|
1042
|
+
|
|
1043
|
+
-- FTS5 Full-Text Search for fast keyword search
|
|
1044
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS events_fts USING fts5(
|
|
1045
|
+
content,
|
|
1046
|
+
event_id UNINDEXED,
|
|
1047
|
+
content='events',
|
|
1048
|
+
content_rowid='rowid'
|
|
1049
|
+
);
|
|
1050
|
+
|
|
1051
|
+
-- Triggers to keep FTS in sync with events table
|
|
1052
|
+
CREATE TRIGGER IF NOT EXISTS events_fts_insert AFTER INSERT ON events BEGIN
|
|
1053
|
+
INSERT INTO events_fts(rowid, content, event_id) VALUES (NEW.rowid, NEW.content, NEW.id);
|
|
1054
|
+
END;
|
|
1055
|
+
|
|
1056
|
+
CREATE TRIGGER IF NOT EXISTS events_fts_delete AFTER DELETE ON events BEGIN
|
|
1057
|
+
INSERT INTO events_fts(events_fts, rowid, content, event_id) VALUES('delete', OLD.rowid, OLD.content, OLD.id);
|
|
1058
|
+
END;
|
|
1059
|
+
|
|
1060
|
+
CREATE TRIGGER IF NOT EXISTS events_fts_update AFTER UPDATE ON events BEGIN
|
|
1061
|
+
INSERT INTO events_fts(events_fts, rowid, content, event_id) VALUES('delete', OLD.rowid, OLD.content, OLD.id);
|
|
1062
|
+
INSERT INTO events_fts(rowid, content, event_id) VALUES (NEW.rowid, NEW.content, NEW.id);
|
|
1063
|
+
END;
|
|
1042
1064
|
`);
|
|
1043
1065
|
const tableInfo = sqliteAll(this.db, "PRAGMA table_info(events)", []);
|
|
1044
1066
|
const columnNames = tableInfo.map((col) => col.name);
|
|
@@ -1479,6 +1501,62 @@ var SQLiteEventStore = class {
|
|
|
1479
1501
|
);
|
|
1480
1502
|
return rows.map((row) => this.rowToEvent(row));
|
|
1481
1503
|
}
|
|
1504
|
+
/**
|
|
1505
|
+
* Fast keyword search using FTS5
|
|
1506
|
+
* Returns events matching the search query, ranked by relevance
|
|
1507
|
+
*/
|
|
1508
|
+
async keywordSearch(query, limit = 10) {
|
|
1509
|
+
await this.initialize();
|
|
1510
|
+
const searchTerms = query.replace(/['"(){}[\]^~*?:\\/-]/g, " ").split(/\s+/).filter((term) => term.length > 1).map((term) => `"${term}"*`).join(" OR ");
|
|
1511
|
+
if (!searchTerms) {
|
|
1512
|
+
return [];
|
|
1513
|
+
}
|
|
1514
|
+
try {
|
|
1515
|
+
const rows = sqliteAll(
|
|
1516
|
+
this.db,
|
|
1517
|
+
`SELECT e.*, fts.rank
|
|
1518
|
+
FROM events_fts fts
|
|
1519
|
+
JOIN events e ON e.id = fts.event_id
|
|
1520
|
+
WHERE events_fts MATCH ?
|
|
1521
|
+
ORDER BY fts.rank
|
|
1522
|
+
LIMIT ?`,
|
|
1523
|
+
[searchTerms, limit]
|
|
1524
|
+
);
|
|
1525
|
+
return rows.map((row) => ({
|
|
1526
|
+
event: this.rowToEvent(row),
|
|
1527
|
+
rank: row.rank
|
|
1528
|
+
}));
|
|
1529
|
+
} catch (error) {
|
|
1530
|
+
const likePattern = `%${query}%`;
|
|
1531
|
+
const rows = sqliteAll(
|
|
1532
|
+
this.db,
|
|
1533
|
+
`SELECT *, 0 as rank FROM events
|
|
1534
|
+
WHERE content LIKE ?
|
|
1535
|
+
ORDER BY timestamp DESC
|
|
1536
|
+
LIMIT ?`,
|
|
1537
|
+
[likePattern, limit]
|
|
1538
|
+
);
|
|
1539
|
+
return rows.map((row) => ({
|
|
1540
|
+
event: this.rowToEvent(row),
|
|
1541
|
+
rank: 0
|
|
1542
|
+
}));
|
|
1543
|
+
}
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* Rebuild FTS index from existing events
|
|
1547
|
+
* Call this once after upgrading to FTS5
|
|
1548
|
+
*/
|
|
1549
|
+
async rebuildFtsIndex() {
|
|
1550
|
+
await this.initialize();
|
|
1551
|
+
const countRow = sqliteGet(this.db, "SELECT COUNT(*) as count FROM events", []);
|
|
1552
|
+
const totalEvents = countRow?.count ?? 0;
|
|
1553
|
+
sqliteExec(this.db, `
|
|
1554
|
+
DELETE FROM events_fts;
|
|
1555
|
+
INSERT INTO events_fts(rowid, content, event_id)
|
|
1556
|
+
SELECT rowid, content, id FROM events;
|
|
1557
|
+
`);
|
|
1558
|
+
return totalEvents;
|
|
1559
|
+
}
|
|
1482
1560
|
/**
|
|
1483
1561
|
* Get database instance for direct access
|
|
1484
1562
|
*/
|
|
@@ -4537,9 +4615,11 @@ var MemoryService = class {
|
|
|
4537
4615
|
sharedStoreConfig = null;
|
|
4538
4616
|
projectHash = null;
|
|
4539
4617
|
readOnly;
|
|
4618
|
+
lightweightMode;
|
|
4540
4619
|
constructor(config) {
|
|
4541
4620
|
const storagePath = this.expandPath(config.storagePath);
|
|
4542
4621
|
this.readOnly = config.readOnly ?? false;
|
|
4622
|
+
this.lightweightMode = config.lightweightMode ?? false;
|
|
4543
4623
|
if (!this.readOnly && !fs.existsSync(storagePath)) {
|
|
4544
4624
|
fs.mkdirSync(storagePath, { recursive: true });
|
|
4545
4625
|
}
|
|
@@ -4586,6 +4666,10 @@ var MemoryService = class {
|
|
|
4586
4666
|
if (this.initialized)
|
|
4587
4667
|
return;
|
|
4588
4668
|
await this.sqliteStore.initialize();
|
|
4669
|
+
if (this.lightweightMode) {
|
|
4670
|
+
this.initialized = true;
|
|
4671
|
+
return;
|
|
4672
|
+
}
|
|
4589
4673
|
if (this.analyticsStore) {
|
|
4590
4674
|
try {
|
|
4591
4675
|
await this.analyticsStore.initialize();
|
|
@@ -4755,9 +4839,6 @@ var MemoryService = class {
|
|
|
4755
4839
|
*/
|
|
4756
4840
|
async retrieveMemories(query, options) {
|
|
4757
4841
|
await this.initialize();
|
|
4758
|
-
if (this.vectorWorker) {
|
|
4759
|
-
await this.vectorWorker.processAll();
|
|
4760
|
-
}
|
|
4761
4842
|
if (options?.includeShared && this.sharedStore) {
|
|
4762
4843
|
return this.retriever.retrieveUnified(query, {
|
|
4763
4844
|
...options,
|
|
@@ -4767,6 +4848,29 @@ var MemoryService = class {
|
|
|
4767
4848
|
}
|
|
4768
4849
|
return this.retriever.retrieve(query, options);
|
|
4769
4850
|
}
|
|
4851
|
+
/**
|
|
4852
|
+
* Fast keyword search using SQLite FTS5
|
|
4853
|
+
* Much faster than vector search - no embedding model needed
|
|
4854
|
+
*/
|
|
4855
|
+
async keywordSearch(query, options) {
|
|
4856
|
+
await this.initialize();
|
|
4857
|
+
const results = await this.sqliteStore.keywordSearch(query, options?.topK ?? 10);
|
|
4858
|
+
const maxRank = Math.min(...results.map((r) => r.rank), -1e-3);
|
|
4859
|
+
const minRank = Math.max(...results.map((r) => r.rank), -1e3);
|
|
4860
|
+
const rankRange = maxRank - minRank || 1;
|
|
4861
|
+
return results.map((r) => ({
|
|
4862
|
+
event: r.event,
|
|
4863
|
+
score: 1 - (r.rank - minRank) / rankRange
|
|
4864
|
+
// Normalize to 0-1
|
|
4865
|
+
})).filter((r) => !options?.minScore || r.score >= options.minScore);
|
|
4866
|
+
}
|
|
4867
|
+
/**
|
|
4868
|
+
* Rebuild FTS index (call after database upgrade)
|
|
4869
|
+
*/
|
|
4870
|
+
async rebuildFtsIndex() {
|
|
4871
|
+
await this.initialize();
|
|
4872
|
+
return this.sqliteStore.rebuildFtsIndex();
|
|
4873
|
+
}
|
|
4770
4874
|
/**
|
|
4771
4875
|
* Get session history
|
|
4772
4876
|
*/
|