clawmem 0.1.8 → 0.2.1

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/AGENTS.md CHANGED
@@ -96,6 +96,7 @@ curl http://host:8090/v1/models
96
96
  | `CLAWMEM_ENABLE_AMEM` | enabled | A-MEM note construction + link generation during indexing. |
97
97
  | `CLAWMEM_ENABLE_CONSOLIDATION` | disabled | Background worker backfills unenriched docs. Needs long-lived MCP process. |
98
98
  | `CLAWMEM_CONSOLIDATION_INTERVAL` | 300000 | Worker interval in ms (min 15000). |
99
+ | `CLAWMEM_NUDGE_INTERVAL` | `15` | Prompts between lifecycle tool use before `<vault-nudge>` injection. 0 to disable. |
99
100
 
100
101
  **Note:** The `bin/clawmem` wrapper sets all endpoint defaults. Always use the wrapper — never `bun run src/clawmem.ts` directly. For remote GPU setups, add the same env vars to the watcher service via a systemd drop-in.
101
102
 
@@ -415,6 +416,8 @@ Note: intent disables BM25 strong-signal bypass, forcing full expansion+rerankin
415
416
 
416
417
  ## Composite Scoring (automatic, applied to all search tools)
417
418
 
419
+ **Observation invalidation (v0.2.0):** Documents with `invalidated_at` set are excluded from search results. Soft invalidation uses `invalidated_at`, `invalidated_by`, and `superseded_by` columns. When `decision-extractor` detects a contradiction that drops confidence ≤ 0.2, the observation is marked invalidated. Invalidated docs can be restored via lifecycle tools.
420
+
418
421
  ```
419
422
  compositeScore = (0.50 × searchScore + 0.25 × recencyScore + 0.25 × confidenceScore) × qualityMultiplier × coActivationBoost
420
423
  ```
@@ -482,11 +485,15 @@ The `memory_relations` table is populated by multiple independent sources:
482
485
  | Beads `syncBeadsIssues()` | causal, supporting, semantic | `beads_sync` MCP tool or watcher (.beads/ change) | Queries `bd` CLI (Dolt backend). Maps beads deps: blocks→causal, discovered-from→supporting, relates-to→semantic, plus conditional-blocks→causal, caused-by→causal, supersedes→supporting. Metadata: `{origin: "beads"}`. |
483
486
  | `buildTemporalBackbone()` | temporal | `build_graphs` MCP tool (manual) | Creation-order edges between all active docs. |
484
487
  | `buildSemanticGraph()` | semantic | `build_graphs` MCP tool (manual) | Pure cosine similarity. PK collision: `INSERT OR IGNORE` means A-MEM semantic edges take precedence if they exist first. |
488
+ | Entity co-occurrence graph | entity | A-MEM enrichment (indexing) | LLM entity extraction → canonical normalization (FTS5 + Levenshtein) → `entity_mentions` + `entity_cooccurrences` tables. Feeds ENTITY intent queries and MPFP `[entity, semantic]` patterns. |
489
+ | `consolidated_observations` | supporting | Consolidation worker (background) | 3-tier consolidation: facts → observations → mental models. Observations track `proof_count`, `trend` (STABLE/STRENGTHENING/WEAKENING/STALE), and source links. |
485
490
 
486
491
  **Edge collision:** Both `generateMemoryLinks()` and `buildSemanticGraph()` insert `relation_type='semantic'`. PK is `(source_id, target_id, relation_type)` — first writer wins.
487
492
 
488
493
  **Graph traversal asymmetry:** `adaptiveTraversal()` traverses all edge types outbound (source→target) but only `semantic` and `entity` edges inbound (target→source). Temporal and causal edges are directional only.
489
494
 
495
+ **MPFP graph retrieval (v0.2.0):** Multi-Path Fact Propagation runs predefined meta-path patterns in parallel (`[semantic, semantic]`, `[entity, temporal]`, `[semantic, causal]`, etc.), fuses via RRF. Hop-synchronized edge cache batches DB queries per hop instead of per pattern. Forward Push with α=0.15 teleport probability bounds active nodes sublinearly. Tier 3 only (`query`/`intent_search`), not hooks. Patterns selected per MAGMA intent: WHY → `[semantic, causal]`, ENTITY → `[entity, semantic]`, WHEN → `[temporal, semantic]`.
496
+
490
497
  ### When to Run `build_graphs`
491
498
 
492
499
  - After **bulk ingestion** (many new docs at once) — adds temporal backbone and fills semantic gaps where A-MEM links are sparse.
@@ -505,11 +512,14 @@ The `memory_relations` table is populated by multiple independent sources:
505
512
 
506
513
  ```
507
514
  User Query + optional intent hint
515
+ → Temporal Extraction (regex date range from query: "last week", "March 2026" → WHERE modified_at BETWEEN filters)
508
516
  → BM25 Probe → Strong Signal Check (skip expansion if top hit ≥ 0.85 with gap ≥ 0.15; disabled when intent provided)
509
517
  → Query Expansion (LLM generates text variants; intent steers expansion prompt)
510
518
  → Parallel: BM25(original) + Vector(original) + BM25(each expanded) + Vector(each expanded)
519
+ + Temporal Proximity (date-range filtered, if temporal constraint extracted)
520
+ + Entity Graph (conditional 1-hop entity walk from top seeds, if entity signals present)
511
521
  → Original query lists get positional 2× weight in RRF; expanded get 1×
512
- → Reciprocal Rank Fusion (k=60, top candidateLimit)
522
+ → Reciprocal Rank Fusion (k=60, top candidateLimit, up to 4-way parallel legs)
513
523
  → Intent-Aware Chunk Selection (intent terms at 0.5× weight alongside query terms at 1.0×)
514
524
  → Cross-Encoder Reranking (4000 char context; intent prepended to rerank query; chunk dedup; batch cap=4)
515
525
  → Position-Aware Blending (α=0.75 top3, 0.60 mid, 0.40 tail)
@@ -624,9 +634,20 @@ Symptom: embed --force with new model produces 3 docs stuck as "Unembedded" but
624
634
  → Fix: Delete partial content_vectors + vectors_vec for the stuck hashes, then re-run embed (no --force).
625
635
  The vec0 DELETE try-catch prevents cascading failures during the re-embed.
626
636
 
637
+ Symptom: reindex --force after v0.2.0 upgrade shows no entity extraction
638
+ → `reindex --force` treats existing docs as updates (isNew=false). The A-MEM pipeline
639
+ skips entity extraction, link generation, and evolution for updates to avoid churn.
640
+ → Fix: Use `clawmem reindex --enrich` instead. The `--enrich` flag forces the full
641
+ enrichment pipeline (entity extraction + links + evolution) on all documents.
642
+ → `--force` alone only refreshes A-MEM notes (keywords, tags, context). `--enrich`
643
+ is needed after major upgrades that add new enrichment stages.
644
+
627
645
  Symptom: CLI reindex/update falls back to node-llama-cpp Vulkan (not GPU server)
628
646
  → GPU env vars only in systemd drop-in, not in wrapper script. CLI invocations missed them.
629
647
  → Fixed 2026-02-12: bin/clawmem wrapper exports CLAWMEM_EMBED_URL/LLM_URL/RERANK_URL defaults.
648
+ → Always run ClawMem via the `bin/clawmem` wrapper, not `bun run src/clawmem.ts` directly.
649
+ The wrapper sets CLAWMEM_EMBED_URL/LLM_URL/RERANK_URL defaults. Scripts or inline bun
650
+ commands that bypass the wrapper will fall back to in-process node-llama-cpp (slow, CPU).
630
651
 
631
652
  Symptom: "UserPromptSubmit hook error" on context-surfacing hook (intermittent)
632
653
  → SQLite contention between the watcher and the hook. The watcher processes filesystem events
@@ -662,6 +683,8 @@ clawmem consolidate [--dry-run] # Find and archive duplicate low-confidence docu
662
683
 
663
684
  ## Integration Notes
664
685
 
686
+ - **Memory nudge (v0.2.0):** Every N prompts (default 15) without a lifecycle MCP tool call (`memory_pin`/`memory_forget`/`memory_snooze`), context-surfacing appends `<vault-nudge>` prompting proactive memory management. Counter resets on lifecycle tool use. Configure via `CLAWMEM_NUDGE_INTERVAL` (0 to disable).
687
+ - **Entity resolution (v0.2.0):** A-MEM enrichment now extracts named entities via LLM, resolves to canonical forms using `entities_fts` + Levenshtein fuzzy matching, and tracks co-occurrence. Entity graph traversal available for ENTITY intent queries via `intent_search`.
665
688
  - QMD retrieval (BM25, vector, RRF, rerank, query expansion) is forked into ClawMem. Do not call standalone QMD tools.
666
689
  - SAME (composite scoring), MAGMA (intent + graph), A-MEM (self-evolving notes) layer on top of QMD substrate.
667
690
  - Three `llama-server` instances (embedding, LLM, reranker) on local or remote GPU. Wrapper defaults to `localhost:8088/8089/8090`.
package/CLAUDE.md CHANGED
@@ -96,6 +96,7 @@ curl http://host:8090/v1/models
96
96
  | `CLAWMEM_ENABLE_AMEM` | enabled | A-MEM note construction + link generation during indexing. |
97
97
  | `CLAWMEM_ENABLE_CONSOLIDATION` | disabled | Background worker backfills unenriched docs. Needs long-lived MCP process. |
98
98
  | `CLAWMEM_CONSOLIDATION_INTERVAL` | 300000 | Worker interval in ms (min 15000). |
99
+ | `CLAWMEM_NUDGE_INTERVAL` | `15` | Prompts between lifecycle tool use before `<vault-nudge>` injection. 0 to disable. |
99
100
 
100
101
  **Note:** The `bin/clawmem` wrapper sets all endpoint defaults. Always use the wrapper — never `bun run src/clawmem.ts` directly. For remote GPU setups, add the same env vars to the watcher service via a systemd drop-in.
101
102
 
@@ -415,6 +416,8 @@ Note: intent disables BM25 strong-signal bypass, forcing full expansion+rerankin
415
416
 
416
417
  ## Composite Scoring (automatic, applied to all search tools)
417
418
 
419
+ **Observation invalidation (v0.2.0):** Documents with `invalidated_at` set are excluded from search results. Soft invalidation uses `invalidated_at`, `invalidated_by`, and `superseded_by` columns. When `decision-extractor` detects a contradiction that drops confidence ≤ 0.2, the observation is marked invalidated. Invalidated docs can be restored via lifecycle tools.
420
+
418
421
  ```
419
422
  compositeScore = (0.50 × searchScore + 0.25 × recencyScore + 0.25 × confidenceScore) × qualityMultiplier × coActivationBoost
420
423
  ```
@@ -482,11 +485,15 @@ The `memory_relations` table is populated by multiple independent sources:
482
485
  | Beads `syncBeadsIssues()` | causal, supporting, semantic | `beads_sync` MCP tool or watcher (.beads/ change) | Queries `bd` CLI (Dolt backend). Maps beads deps: blocks→causal, discovered-from→supporting, relates-to→semantic, plus conditional-blocks→causal, caused-by→causal, supersedes→supporting. Metadata: `{origin: "beads"}`. |
483
486
  | `buildTemporalBackbone()` | temporal | `build_graphs` MCP tool (manual) | Creation-order edges between all active docs. |
484
487
  | `buildSemanticGraph()` | semantic | `build_graphs` MCP tool (manual) | Pure cosine similarity. PK collision: `INSERT OR IGNORE` means A-MEM semantic edges take precedence if they exist first. |
488
+ | Entity co-occurrence graph | entity | A-MEM enrichment (indexing) | LLM entity extraction → canonical normalization (FTS5 + Levenshtein) → `entity_mentions` + `entity_cooccurrences` tables. Feeds ENTITY intent queries and MPFP `[entity, semantic]` patterns. |
489
+ | `consolidated_observations` | supporting | Consolidation worker (background) | 3-tier consolidation: facts → observations → mental models. Observations track `proof_count`, `trend` (STABLE/STRENGTHENING/WEAKENING/STALE), and source links. |
485
490
 
486
491
  **Edge collision:** Both `generateMemoryLinks()` and `buildSemanticGraph()` insert `relation_type='semantic'`. PK is `(source_id, target_id, relation_type)` — first writer wins.
487
492
 
488
493
  **Graph traversal asymmetry:** `adaptiveTraversal()` traverses all edge types outbound (source→target) but only `semantic` and `entity` edges inbound (target→source). Temporal and causal edges are directional only.
489
494
 
495
+ **MPFP graph retrieval (v0.2.0):** Multi-Path Fact Propagation runs predefined meta-path patterns in parallel (`[semantic, semantic]`, `[entity, temporal]`, `[semantic, causal]`, etc.), fuses via RRF. Hop-synchronized edge cache batches DB queries per hop instead of per pattern. Forward Push with α=0.15 teleport probability bounds active nodes sublinearly. Tier 3 only (`query`/`intent_search`), not hooks. Patterns selected per MAGMA intent: WHY → `[semantic, causal]`, ENTITY → `[entity, semantic]`, WHEN → `[temporal, semantic]`.
496
+
490
497
  ### When to Run `build_graphs`
491
498
 
492
499
  - After **bulk ingestion** (many new docs at once) — adds temporal backbone and fills semantic gaps where A-MEM links are sparse.
@@ -505,11 +512,14 @@ The `memory_relations` table is populated by multiple independent sources:
505
512
 
506
513
  ```
507
514
  User Query + optional intent hint
515
+ → Temporal Extraction (regex date range from query: "last week", "March 2026" → WHERE modified_at BETWEEN filters)
508
516
  → BM25 Probe → Strong Signal Check (skip expansion if top hit ≥ 0.85 with gap ≥ 0.15; disabled when intent provided)
509
517
  → Query Expansion (LLM generates text variants; intent steers expansion prompt)
510
518
  → Parallel: BM25(original) + Vector(original) + BM25(each expanded) + Vector(each expanded)
519
+ + Temporal Proximity (date-range filtered, if temporal constraint extracted)
520
+ + Entity Graph (conditional 1-hop entity walk from top seeds, if entity signals present)
511
521
  → Original query lists get positional 2× weight in RRF; expanded get 1×
512
- → Reciprocal Rank Fusion (k=60, top candidateLimit)
522
+ → Reciprocal Rank Fusion (k=60, top candidateLimit, up to 4-way parallel legs)
513
523
  → Intent-Aware Chunk Selection (intent terms at 0.5× weight alongside query terms at 1.0×)
514
524
  → Cross-Encoder Reranking (4000 char context; intent prepended to rerank query; chunk dedup; batch cap=4)
515
525
  → Position-Aware Blending (α=0.75 top3, 0.60 mid, 0.40 tail)
@@ -624,9 +634,20 @@ Symptom: embed --force with new model produces 3 docs stuck as "Unembedded" but
624
634
  → Fix: Delete partial content_vectors + vectors_vec for the stuck hashes, then re-run embed (no --force).
625
635
  The vec0 DELETE try-catch prevents cascading failures during the re-embed.
626
636
 
637
+ Symptom: reindex --force after v0.2.0 upgrade shows no entity extraction
638
+ → `reindex --force` treats existing docs as updates (isNew=false). The A-MEM pipeline
639
+ skips entity extraction, link generation, and evolution for updates to avoid churn.
640
+ → Fix: Use `clawmem reindex --enrich` instead. The `--enrich` flag forces the full
641
+ enrichment pipeline (entity extraction + links + evolution) on all documents.
642
+ → `--force` alone only refreshes A-MEM notes (keywords, tags, context). `--enrich`
643
+ is needed after major upgrades that add new enrichment stages.
644
+
627
645
  Symptom: CLI reindex/update falls back to node-llama-cpp Vulkan (not GPU server)
628
646
  → GPU env vars only in systemd drop-in, not in wrapper script. CLI invocations missed them.
629
647
  → Fixed 2026-02-12: bin/clawmem wrapper exports CLAWMEM_EMBED_URL/LLM_URL/RERANK_URL defaults.
648
+ → Always run ClawMem via the `bin/clawmem` wrapper, not `bun run src/clawmem.ts` directly.
649
+ The wrapper sets CLAWMEM_EMBED_URL/LLM_URL/RERANK_URL defaults. Scripts or inline bun
650
+ commands that bypass the wrapper will fall back to in-process node-llama-cpp (slow, CPU).
630
651
 
631
652
  Symptom: "UserPromptSubmit hook error" on context-surfacing hook (intermittent)
632
653
  → SQLite contention between the watcher and the hook. The watcher processes filesystem events
@@ -662,6 +683,8 @@ clawmem consolidate [--dry-run] # Find and archive duplicate low-confidence docu
662
683
 
663
684
  ## Integration Notes
664
685
 
686
+ - **Memory nudge (v0.2.0):** Every N prompts (default 15) without a lifecycle MCP tool call (`memory_pin`/`memory_forget`/`memory_snooze`), context-surfacing appends `<vault-nudge>` prompting proactive memory management. Counter resets on lifecycle tool use. Configure via `CLAWMEM_NUDGE_INTERVAL` (0 to disable).
687
+ - **Entity resolution (v0.2.0):** A-MEM enrichment now extracts named entities via LLM, resolves to canonical forms using `entities_fts` + Levenshtein fuzzy matching, and tracks co-occurrence. Entity graph traversal available for ENTITY intent queries via `intent_search`.
665
688
  - QMD retrieval (BM25, vector, RRF, rerank, query expansion) is forked into ClawMem. Do not call standalone QMD tools.
666
689
  - SAME (composite scoring), MAGMA (intent + graph), A-MEM (self-evolving notes) layer on top of QMD substrate.
667
690
  - Three `llama-server` instances (embedding, LLM, reranker) on local or remote GPU. Wrapper defaults to `localhost:8088/8089/8090`.
package/README.md CHANGED
@@ -42,6 +42,18 @@ ClawMem turns your markdown notes, project docs, and research dumps into persist
42
42
 
43
43
  Runs fully local with no API keys and no cloud services. Integrates via Claude Code hooks and MCP tools, or as an OpenClaw ContextEngine plugin. Both modes share the same vault for cross-runtime memory. Works with any MCP-compatible client.
44
44
 
45
+ ### v0.2.0 Enhancements
46
+
47
+ Seven patterns extracted from competitor analysis ([Hindsight](https://github.com/vectorize-io/hindsight), [Hermes Agent](https://github.com/NousResearch/hermes-agent), [claude-mem](https://github.com/thedotmack/claude-mem)):
48
+
49
+ - **Entity resolution + co-occurrence graph** — LLM entity extraction during A-MEM enrichment, canonical normalization via FTS5 + Levenshtein fuzzy matching, co-occurrence tracking, entity graph traversal for ENTITY intent queries
50
+ - **MPFP graph retrieval** — Multi-Path Fact Propagation with meta-path patterns per intent, hop-synchronized edge cache, Forward Push with α=0.15 teleport probability. Replaces single-beam traversal for causal/entity/temporal queries.
51
+ - **Temporal query extraction** — regex-based date range extraction from natural language queries ("last week", "March 2026"), wired as WHERE filters into BM25 and vector search
52
+ - **4-way parallel retrieval** — temporal proximity and entity graph channels added as parallel RRF legs in `query` tool (Tier 3 only), alongside existing BM25 + vector channels
53
+ - **3-tier consolidation** — facts to observations (auto-generated, with proof_count and trend enum) to mental models. Background worker synthesizes clusters of related observations into consolidated patterns.
54
+ - **Observation invalidation** — soft invalidation (invalidated_at/invalidated_by/superseded_by columns). Observations with confidence ≤ 0.2 after contradiction are filtered from search results.
55
+ - **Memory nudge** — periodic ephemeral `<vault-nudge>` injection prompting lifecycle tool use after N turns of inactivity. Configurable via `CLAWMEM_NUDGE_INTERVAL`.
56
+
45
57
  ## Architecture
46
58
 
47
59
  <p align="center">
@@ -137,6 +149,25 @@ clawmem update --embed
137
149
  clawmem doctor
138
150
  ```
139
151
 
152
+ ### Upgrading
153
+
154
+ ```bash
155
+ bun update -g clawmem # or: npm update -g clawmem
156
+ ```
157
+
158
+ Database schema migrates automatically on next startup (new tables and columns are added via `CREATE IF NOT EXISTS` / `ALTER TABLE ADD COLUMN`).
159
+
160
+ After **major version updates** (e.g. 0.1.x → 0.2.0) that add new enrichment pipelines, run a full enrichment pass to backfill existing documents:
161
+
162
+ ```bash
163
+ clawmem reindex --enrich # Full enrichment: entity extraction + links + evolution for all docs
164
+ clawmem embed # Re-embed if upgrading embedding models (not needed for most updates)
165
+ ```
166
+
167
+ `--enrich` forces the complete A-MEM pipeline (entity extraction, link generation, memory evolution) on all documents, not just new ones. Without it, reindex only refreshes metadata for existing docs.
168
+
169
+ Routine patch updates (e.g. 0.2.0 → 0.2.1) do not require reindexing.
170
+
140
171
  ### Integration
141
172
 
142
173
  #### Claude Code
package/SKILL.md CHANGED
@@ -272,7 +272,7 @@ Once escalated, route by query type:
272
272
  | `beads_sync` | Sync Beads issues from Dolt backend into memory. |
273
273
  | `index_stats` | Doc counts, embedding coverage, content type distribution. |
274
274
  | `status` | Quick index health. |
275
- | `reindex` | Force re-index (BM25 only, does NOT embed). |
275
+ | `reindex` | Force re-index (BM25 only, does NOT embed). Use `--enrich` after major upgrades to backfill entity extraction + links on existing docs. |
276
276
  | `memory_evolution_status` | Track how a doc's A-MEM metadata evolved over time. |
277
277
  | `timeline` | Temporal neighborhood around a document — what was modified before/after. Progressive disclosure: search → timeline → get. Supports same-collection scoping and session correlation. |
278
278
  | `list_vaults` | Show configured vault names and paths. Empty in single-vault mode. |
@@ -660,6 +660,14 @@ echo "user query" | clawmem surface --context --stdin
660
660
  echo "session-id" | clawmem surface --bootstrap --stdin
661
661
  ```
662
662
 
663
+ ### Enrichment Commands
664
+
665
+ ```bash
666
+ clawmem reindex --enrich # Full A-MEM pipeline on ALL docs (entity extraction,
667
+ # link generation, memory evolution). Use after major upgrades.
668
+ # Without --enrich, reindex only refreshes metadata for changed docs.
669
+ ```
670
+
663
671
  ### Analysis Commands
664
672
 
665
673
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clawmem",
3
- "version": "0.1.8",
3
+ "version": "0.2.1",
4
4
  "description": "On-device context engine and memory for AI agents. Claude Code and OpenClaw. Hooks + MCP server + hybrid RAG search.",
5
5
  "type": "module",
6
6
  "bin": {
package/src/amem.ts CHANGED
@@ -8,6 +8,7 @@
8
8
  import type { Database } from "bun:sqlite";
9
9
  import type { LlamaCpp } from "./llm.ts";
10
10
  import type { Store } from "./store.ts";
11
+ import { enrichDocumentEntities } from "./entity.ts";
11
12
 
12
13
  export interface MemoryNote {
13
14
  keywords: string[];
@@ -612,11 +613,21 @@ export async function postIndexEnrich(
612
613
  return;
613
614
  }
614
615
 
615
- // Step 2: Generate memory links (new documents only)
616
+ // Step 2: Entity extraction + resolution + co-occurrence (new documents only)
617
+ try {
618
+ const entityCount = await enrichDocumentEntities(store.db, llm, docId);
619
+ if (entityCount > 0) {
620
+ console.log(`[amem] Resolved ${entityCount} entities for docId ${docId}`);
621
+ }
622
+ } catch (err) {
623
+ console.log(`[amem] Entity enrichment failed for docId ${docId}:`, err);
624
+ }
625
+
626
+ // Step 3: Generate memory links (new documents only)
616
627
  const linksCreated = await generateMemoryLinks(store, llm, docId);
617
628
  console.log(`[amem] Created ${linksCreated} links for docId ${docId}`);
618
629
 
619
- // Step 3: Evolve memories based on new evidence (new documents only)
630
+ // Step 4: Evolve memories based on new evidence (new documents only)
620
631
  // The new document triggers evolution of its linked neighbors
621
632
  if (linksCreated > 0) {
622
633
  // Get neighbors this new document links to (outbound links from generateMemoryLinks)
package/src/clawmem.ts CHANGED
@@ -1269,6 +1269,7 @@ async function cmdWatch() {
1269
1269
 
1270
1270
  async function cmdReindex(args: string[]) {
1271
1271
  const force = args.includes("--force") || args.includes("-f");
1272
+ const enrich = args.includes("--enrich");
1272
1273
  const collections = collectionsList();
1273
1274
 
1274
1275
  if (collections.length === 0) {
@@ -1283,9 +1284,13 @@ async function cmdReindex(args: string[]) {
1283
1284
  console.log(`${c.yellow}Force reindex: deactivated all documents${c.reset}`);
1284
1285
  }
1285
1286
 
1287
+ if (enrich) {
1288
+ console.log(`${c.cyan}Full enrichment: entity extraction + links + evolution for all documents${c.reset}`);
1289
+ }
1290
+
1286
1291
  for (const col of collections) {
1287
1292
  console.log(`Indexing ${c.bold}${col.name}${c.reset} (${col.path})...`);
1288
- const stats = await indexCollection(s, col.name, col.path, col.pattern);
1293
+ const stats = await indexCollection(s, col.name, col.path, col.pattern, { forceEnrich: enrich });
1289
1294
  console.log(` +${stats.added} added, ~${stats.updated} updated, =${stats.unchanged} unchanged, -${stats.removed} removed`);
1290
1295
  }
1291
1296
  }
@@ -2202,7 +2207,7 @@ ${c.bold}Setup:${c.reset}
2202
2207
  ${c.bold}Indexing:${c.reset}
2203
2208
  clawmem update [--pull] [--embed] Re-scan collections (--embed auto-embeds)
2204
2209
  clawmem embed [-f] Generate fragment embeddings
2205
- clawmem reindex [--force] Full re-index
2210
+ clawmem reindex [--force] [--enrich] Full re-index (--enrich: run entity extraction + links on all docs)
2206
2211
  clawmem watch File watcher daemon
2207
2212
  clawmem status Show index status
2208
2213