sessionmem 1.6.0 → 1.8.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +122 -61
  3. package/dist/adapters/claudeMdInjector.js +45 -67
  4. package/dist/adapters/diagnostics.js +29 -4
  5. package/dist/adapters/generic.js +31 -5
  6. package/dist/adapters/global/claudeCode.js +6 -3
  7. package/dist/adapters/ide/cline.js +2 -1
  8. package/dist/adapters/ide/cursor.js +3 -3
  9. package/dist/adapters/ide/installer.js +1 -0
  10. package/dist/adapters/installedHosts.js +4 -1
  11. package/dist/cli/autostart/index.js +246 -0
  12. package/dist/cli/commands/autostart.js +24 -0
  13. package/dist/cli/commands/config.js +8 -0
  14. package/dist/cli/commands/doctor.js +45 -2
  15. package/dist/cli/commands/install.js +14 -3
  16. package/dist/cli/commands/promptSubmit.js +58 -0
  17. package/dist/cli/commands/sessionStart.js +14 -2
  18. package/dist/cli/commands/uninstall.js +4 -0
  19. package/dist/cli/commands/watch.js +14 -2
  20. package/dist/cli/index.js +12 -3
  21. package/dist/cli/projectId.js +17 -2
  22. package/dist/cli/watchCheckpoint.js +35 -0
  23. package/dist/cli/watchLog.js +23 -0
  24. package/dist/core/api/contracts.js +19 -0
  25. package/dist/core/api/memoryCoreService.js +84 -21
  26. package/dist/core/config/policyConfig.js +13 -0
  27. package/dist/core/embed/localSemanticEmbedder.js +62 -0
  28. package/dist/core/retrieve/memoryIndex.js +6 -0
  29. package/dist/core/retrieve/retrieveMemories.js +57 -9
  30. package/dist/core/retrieve/signalFusion.js +21 -0
  31. package/dist/core/retrieve/temporalIntent.js +59 -0
  32. package/dist/core/schema/migrations/016_semantic_embeddings.sql +12 -0
  33. package/dist/core/storage/entityLinkRepo.js +47 -0
  34. package/dist/core/storage/memorySearchRepo.js +16 -3
  35. package/dist/core/storage/semanticSearchRepo.js +56 -0
  36. package/dist/core/storage/temporalRepo.js +13 -0
  37. package/dist/core/storage/timelineRepo.js +27 -0
  38. package/docs/architecture.md +13 -1
  39. package/docs/automatic-memory.md +86 -0
  40. package/docs/benchmark.md +16 -0
  41. package/docs/local-semantic.md +58 -0
  42. package/docs/research/automatic-capture.md +62 -0
  43. package/docs/retrieval-tools.md +144 -0
  44. package/docs/troubleshooting.md +5 -0
  45. package/package.json +21 -2
@@ -0,0 +1,144 @@
1
+ # Compact retrieval and optional ranking
2
+
3
+ ## Search, inspect nearby context, then fetch details
4
+
5
+ The MCP server exposes these tools alongside the existing tools. Project scope
6
+ comes from the server, so callers do not supply `projectId` over MCP.
7
+
8
+ | Tool | Input | Output |
9
+ | --- | --- | --- |
10
+ | `searchMemoryIndex` | `query`, optional `limit`, `includeHistory`, `tags` | IDs, one-line summaries, kind, capture date, numeric score, `hasMore` |
11
+ | `memoryTimeline` | `memoryId`, or both `fromDate` and `toDate`; optional `limit`, `includeHistory` | Compact rows in capture order; scores are null |
12
+ | `getMemory` | `memoryId` | One complete stored memory, including content and metadata |
13
+
14
+ Start with `searchMemoryIndex({"query":"database migration","limit":5})`.
15
+ Inspect the surrounding records with
16
+ `memoryTimeline({"memoryId":"selected-id","limit":5})` when chronology matters.
17
+ Fetch only the records needed with `getMemory({"memoryId":"selected-id"})`.
18
+ The existing get-by-ID tool already returns full bodies, so no duplicate tool is
19
+ needed. Existing `retrieveMemories` remains available.
20
+
21
+ Index and timeline limits default to 10 and accept integers from 1 to 50. Summaries
22
+ are extractive previews of stored text, with whitespace collapsed and at most 160
23
+ characters. They can omit qualifiers from longer memories; read the full body
24
+ before relying on a fact. No summaries or inference are generated for these tools.
25
+ Search scores are rounded to four decimal places. Search uses the same ranker as
26
+ `retrieveMemories`, without its startup formatting or access-counter updates.
27
+
28
+ Index `hasMore` describes the bounded retrieval candidate pool, not an exhaustive
29
+ store count. Timeline `hasMore` means more visible records exist outside the
30
+ returned window. Around an ID, it balances earlier and later records and fills
31
+ remaining slots from the available side. Timestamp ties use ID ordering. Ranges
32
+ are inclusive UTC ISO timestamps, for example:
33
+
34
+ ```json
35
+ {"fromDate":"2026-01-01T00:00:00Z","toDate":"2026-01-31T23:59:59.999Z","limit":10}
36
+ ```
37
+
38
+ Timeline dates are **capture dates**, not dates mentioned inside prose. Timeline
39
+ includes superseded records by default so it can explain changes; set
40
+ `includeHistory:false` for current records only. Index excludes fully superseded
41
+ records by default. All three tools enforce project scope and expiry. Compact
42
+ search and timeline do not update access counters. Optional local semantic search
43
+ can still backfill its derived vector index, as with ordinary retrieval.
44
+
45
+ ## Optional temporal retrieval
46
+
47
+ `temporalRetrieval` defaults off. It did not improve the pinned-clock LoCoMo run.
48
+ Enable it for stores with meaningful observation times:
49
+
50
+ ```bash
51
+ sessionmem config set temporalRetrieval true
52
+ ```
53
+
54
+ A deterministic English cue detector recognizes current state (`current`,
55
+ `currently`, `now`, `latest`, `today`, `at present`) and historical questions
56
+ (`before`, `previously`, `formerly`, `prior`, `used to`, `no longer`, `when did`,
57
+ `when was`, `when were`, `in the past`, `historical`, `history`). Dated clauses take
58
+ precedence over current-state cues. With no recognized cue, the previous retrieval
59
+ behavior and scores stay unchanged, even when enabled.
60
+
61
+ Supported ranges are `YYYY-MM-DD`, `YYYY-MM`, `in YYYY`, `during YYYY`, `yesterday`,
62
+ `last/previous week/month/year`, and numeric day/week offsets such as `2 days ago`.
63
+ Relative dates use the injected retrieval clock in UTC; weeks start on Monday and
64
+ months are calendar months. The detector does not interpret arbitrary natural
65
+ language dates, future plans, locale-specific dates or conversational reference
66
+ times. An invalid date supplies no date signal.
67
+
68
+ Historical intent includes superseded candidates automatically unless the caller
69
+ explicitly sets `includeHistory:false`. That decision applies to both lexical and
70
+ optional semantic candidates. Explicit `true` also works for current-state queries.
71
+ Existing supersession rules still determine which facts have changed; no new
72
+ contradiction inference is added.
73
+
74
+ Within relevance, temporal scoring uses a fixed 90% existing relevance and 10%
75
+ time signal. Current-state signals average the non-superseded claim fraction and
76
+ freshness, `1 / (1 + ageDays / 30)`. Historical ranges use the distance from the
77
+ range with the same 30-day scale. `before` and similar previous-state cues favor
78
+ the superseded fraction. Undated historical questions have a neutral time signal.
79
+ The time is the latest extracted claim observation timestamp, falling back to
80
+ original capture time. Editing a row does not invent a new event date.
81
+
82
+ Past queries neutralize ordinary recency and inactivity-based importance decay,
83
+ so age alone does not suppress historical evidence. Stored importance and access
84
+ boosts still apply. Dates rerank candidates; they are not hard date filters and do
85
+ not guarantee that a relevant memory outside the candidate pool will be found.
86
+ For exact capture-date browsing, use `memoryTimeline`.
87
+
88
+ ## Optional entity-link boost
89
+
90
+ Entity coverage is enabled by default when retrieval uses BM25, including when
91
+ optional inference is unavailable. It improves all three primary LoCoMo metrics
92
+ in that mode. With active MiniLM it defaults off because hit rate and recall
93
+ regressed. An explicit `entityLinkBoost` value overrides that mode-specific
94
+ choice. To enable it explicitly:
95
+
96
+ ```bash
97
+ sessionmem config set entityLinkBoost true
98
+ ```
99
+
100
+ The query links literal normalized name spans against the existing
101
+ `memory_entities` tables. Explicit aliases cover `postgres`/`postgresql`,
102
+ `node`/`node.js` and `k8s`/`kubernetes`. There is no fuzzy name matching, pronoun
103
+ resolution, entity embedding, or graph traversal. Extraction rules stay unchanged.
104
+ Project, expiry and requested history visibility apply before link scoring.
105
+
106
+ Each linked `(kind, name)` receives weight
107
+ `1 + log((visibleMemoryCount + 1) / (matchingMemoryCount + 1))`. A memory's entity
108
+ score is its matched weight divided by the total linked weight. Up to 50 highest
109
+ entity-score IDs are admitted to the candidate union, with ID tie breaks. This
110
+ channel can admit rows that were absent from the BM25 or semantic pool.
111
+
112
+ The fixed fusion is 80% base relevance and 20% linked-entity score. With semantic
113
+ search enabled, base relevance retains the existing 2:1 BM25/positive-cosine blend.
114
+ When no entity is linked, the prior scoring path is retained. The existing 10%
115
+ entity-overlap signal remains in use when coverage is off. Temporal
116
+ fusion, when enabled too, follows entity fusion. Outer relevance, recency and
117
+ importance weights remain 60%, 25% and 15%.
118
+
119
+ Disable coverage with `sessionmem config set entityLinkBoost false` and temporal
120
+ retrieval with `sessionmem config set temporalRetrieval false`.
121
+
122
+ ## Source-informed fusion alternatives
123
+
124
+ The optional `retrievalRanking` setting accepts `legacy`, `adaptive-bm25`,
125
+ `hub-additive` and `adaptive-hub-additive`. `legacy` means the existing BM25/dense
126
+ fusion, with the mode-specific entity-coverage default above. Other modes default
127
+ to their stated experiment without coverage, unless explicitly overridden.
128
+
129
+ `adaptive-bm25` uses a query-length adaptive sigmoid on raw positive FTS5 BM25.
130
+ The additive modes use a hub-damped maximum entity boost from at most eight names,
131
+ plus lexical and optional dense signals, divided by the maximum score of active
132
+ channels. A 0.2 semantic gate applies before additive fusion. The adaptive additive
133
+ variant also enables the sigmoid. These hypotheses did not pass the three-metric
134
+ regression gate and remain opt-in. See the
135
+ [source notes](../benchmarks/retrieval-source-notes.md) for exact parameters,
136
+ algorithm differences and licensing scope. No competitor source or prompt was
137
+ adapted. The current defaults select entity coverage for BM25 and the existing
138
+ fusion for MiniLM; there are no per-query-label or per-category exceptions.
139
+
140
+ The temporal and entity settings work alongside the existing `semanticSearch`
141
+ setting. Results,
142
+ per-category losses and token measurements are in the
143
+ [retrieval evaluation](../benchmarks/retrieval-gaps.md). They do not establish
144
+ accuracy for generated answers or gains on coding workloads.
@@ -13,6 +13,8 @@ Doctor prints PASS or FAIL and a fix hint for each problem. Any failed check
13
13
  returns a nonzero exit status. It checks:
14
14
 
15
15
  - **Memory store:** the selected database exists, opens, and passes SQLite's quick integrity check. It does not create a missing database.
16
+ - **Auto-start:** this OS's per-user login registration is present and enabled; the registered Node executable and sessionmem entry point still exist. Run `sessionmem autostart enable` after moving the package or changing Node versions.
17
+ - **Watcher capture:** a recent completed sweep checkpoint has no capture errors and transcript checkpoints exist when source files were found. Check `logs/watch.log` beside the database. Unchanged transcripts do not require new imports. Missing or stale checkpoints fail even if an OS service is registered.
16
18
  - **Schema:** all bundled migrations have been applied. It reports pending or unrecognized migrations without changing the schema.
17
19
  - **Hooks, per host:** Claude Code's SessionStart, SessionEnd, and PostToolUse commands, types, matchers, and enabled state match the current version's definitions. Other hosts report that lifecycle hooks are not required.
18
20
  - **Adapter wiring, per host:** the installed MCP entry matches the installer, its local command starts, the server version matches, and the expected tools and stats response work. This tests the configured server process without starting the coding agent itself.
@@ -21,6 +23,8 @@ returns a nonzero exit status. It checks:
21
23
  For Codex, the wiring check supports the installer-generated TOML command and
22
24
  args. Custom Codex launch settings require manual verification.
23
25
 
26
+ Codex and Cursor transcript capture uses the login watcher; install does not wire lifecycle capture hooks for those hosts. Claude Code also has its installed hooks.
27
+
24
28
  All checks work offline, including when cloud summarization is enabled. Doctor
25
29
  does not summarize sessions or sync shared memories. It honors `SESSIONMEM_DB_PATH`
26
30
  and the same host overrides as install. Keep those environment settings when
@@ -29,6 +33,7 @@ running a suggested repair.
29
33
  Safe repair commands printed by doctor include:
30
34
 
31
35
  ```bash
36
+ sessionmem autostart enable # update paths and restart login capture
32
37
  sessionmem ping # initialize a missing store / apply pending migrations
33
38
  sessionmem install --adapter claude-code # repair MCP registration and hook definitions
34
39
  ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sessionmem",
3
- "version": "1.6.0",
3
+ "version": "1.8.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Local-first MCP memory layer for coding agents across Claude Code, Codex, Cursor, Cline, Windsurf, and other MCP-compatible hosts.",
@@ -46,9 +46,12 @@
46
46
  },
47
47
  "devDependencies": {
48
48
  "@eslint/js": "^10.0.1",
49
+ "@huggingface/tokenizers": "0.2.0",
49
50
  "@types/better-sqlite3": "^9.6.0",
51
+ "@xcidos/genesis-memory-model": "0.1.0-alpha.1",
50
52
  "eslint": "^10.12.0",
51
53
  "globals": "^17.13.0",
54
+ "onnxruntime-node": "1.30.0",
52
55
  "typescript": "^6.0.3",
53
56
  "typescript-eslint": "^8.71.2",
54
57
  "vitest": "^4.1.8"
@@ -59,5 +62,21 @@
59
62
  "bugs": {
60
63
  "url": "https://github.com/catfish-1234/sessionmem/issues"
61
64
  },
62
- "homepage": "https://github.com/catfish-1234/sessionmem#readme"
65
+ "homepage": "https://github.com/catfish-1234/sessionmem#readme",
66
+ "peerDependencies": {
67
+ "@huggingface/tokenizers": "0.2.0",
68
+ "onnxruntime-node": "1.30.0",
69
+ "@xcidos/genesis-memory-model": "0.1.0-alpha.1"
70
+ },
71
+ "peerDependenciesMeta": {
72
+ "@huggingface/tokenizers": {
73
+ "optional": true
74
+ },
75
+ "onnxruntime-node": {
76
+ "optional": true
77
+ },
78
+ "@xcidos/genesis-memory-model": {
79
+ "optional": true
80
+ }
81
+ }
63
82
  }