@danielsimonjr/memoryjs 2.4.0 → 2.6.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 CHANGED
@@ -1,1152 +1,1048 @@
1
- # MemoryJS
2
-
3
- [![Version](https://img.shields.io/badge/version-2.4.0-blue.svg)](https://github.com/danielsimonjr/memoryjs)
4
- [![NPM](https://img.shields.io/npm/v/@danielsimonjr/memoryjs.svg)](https://www.npmjs.com/package/@danielsimonjr/memoryjs)
5
- [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
6
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
7
- [![Tests](https://img.shields.io/badge/tests-7127%20passing-brightgreen.svg)](https://github.com/danielsimonjr/memoryjs)
8
-
9
- A **TypeScript knowledge graph library** for managing entities, relations, and observations with **advanced search**, **hierarchical organization**, **bitemporal versioning**, **causal reasoning**, **role-based access control**, **multi-agent collaboration**, **memory-mapped I/O**, **segment-sharded JSONL**, **tiered indexing**, and **multiple storage backends**.
10
-
11
- > Core library powering [@danielsimonjr/memory-mcp](https://www.npmjs.com/package/@danielsimonjr/memory-mcp). **235 TypeScript files**, **79,378 lines of code**, **7127+ passing tests**, dual storage backends (JSONL/SQLite + pluggable `IMemoryBackend`), comprehensive search (BM25 with incremental indexing, TF-IDF, fuzzy with N-gram pre-filter, semantic, hybrid, temporal, LLM-planned, active iterative retrieval, minimal SPARQL subset), and a complete **Agent Memory System** for AI agents — role profiles, entropy filtering, recursive consolidation, collaborative synthesis with conflict resolution, failure distillation, cognitive load analysis, visibility hierarchies, RBAC, optimistic concurrency, audit attribution, procedural memory, causal reasoning, world-model orchestrator, and the Phase 2 catalog-aligned memory-type slots: **prospective** (intentions-to-act), **failure** (structured pre-task lookup), **plan** (hierarchical goal trees), **reflection** (derived pattern + trajectory summary) + a discriminated `TrustLevel` provenance mixin.
12
-
13
- ## Table of Contents
14
-
15
- - [Features](#features)
16
- - [Installation](#installation)
17
- - [Quick Start](#quick-start)
18
- - [Core Concepts](#core-concepts)
19
- - [Storage Options](#storage-options)
20
- - [Search Capabilities](#search-capabilities)
21
- - [Graph Algorithms](#graph-algorithms)
22
- - [Agent Memory System](#agent-memory-system)
23
- - [API Reference](#api-reference)
24
- - [Configuration](#configuration)
25
- - [Development](#development)
26
- - [Documentation](#documentation)
27
- - [License](#license)
28
-
29
- ## Features
30
-
31
- ### Core Capabilities
32
-
33
- - **Knowledge Graph Storage**: Entity-Relation-Observation model for structured data
34
- - **Dual Storage Backends**: JSONL (human-readable) or SQLite (FTS5, 3-10x faster)
35
- - **Full CRUD Operations**: Create, read, update, delete entities and relations
36
- - **Hierarchical Nesting**: Parent-child relationships for tree structures
37
- - **Timestamps**: Automatic createdAt and lastModified tracking
38
-
39
- ### Advanced Features
40
-
41
- | Category | Description |
42
- |----------|-------------|
43
- | **Search Algorithms** | Basic, TF-IDF ranked, BM25, Boolean (AND/OR/NOT), Fuzzy (Levenshtein + N-gram pre-filter), Semantic (embeddings), Hybrid |
44
- | **Graph Algorithms** | Shortest path (BFS), all paths, centrality metrics (degree, betweenness, PageRank), connected components |
45
- | **Hierarchical Nesting** | Parent-child relationships, ancestor/descendant traversal, subtree operations |
46
- | **Duplicate Detection** | Intelligent compression with similarity scoring |
47
- | **Tag Management** | Tags, aliases, bulk operations, importance scores (0-10) |
48
- | **Import/Export** | JSON, CSV, GraphML, GEXF, DOT, Markdown, Mermaid formats with Brotli compression |
49
- | **Analytics** | Graph statistics, validation, integrity checks |
50
- | **Temporal Queries** | Natural language time parsing ("last hour", "10 minutes ago") via `searchByTime()` and `ManagerContext.temporalSearch` |
51
- | **Memory Distillation** | Post-retrieval policy filter (relevance + freshness + dedup) wired into `ContextWindowManager` |
52
- | **Freshness Auditing** | `Entity.ttl` / `Entity.confidence`, `FreshnessManager` reports, TTL-aware decay and salience weighting |
53
- | **N-gram Search** | Trigram index with Jaccard pre-filtering reduces Levenshtein candidate set in `FuzzySearch` |
54
- | **LLM Query Planner** | Optional natural language → `StructuredQuery` decomposition via `LLMProvider`; `ManagerContext.queryNaturalLanguage()` |
55
- | **Governance & Audit** | `AuditLog` (JSONL), `GovernanceManager` (transactions/rollback), `GovernancePolicy` (canCreate/canUpdate/canDelete) |
56
-
57
- ### Module Statistics
58
-
59
- | Module | Files | Key Components |
60
- |--------|-------|----------------|
61
- | `agent/` | 65 | AgentMemoryManager, SessionManager, DecayEngine, WorkingMemoryManager, ArtifactManager, DistillationPipeline, RoleProfiles, EntropyFilter, ConsolidationScheduler, MemoryFormatter, CollaborativeSynthesis, FailureDistillation, CognitiveLoadAnalyzer, VisibilityResolver, **MemoryEngine**, **MemoryValidator**, **TrajectoryCompressor**, **ExperienceExtractor**, **CausalReasoner**, **ProcedureManager**, **WorldModelManager**, **ActiveRetrievalController**, **CollaborationAuditEnforcer**, **RbacMiddleware**, **InMemoryBackend** / **SQLiteBackend**, **ProspectiveMemoryManager**, **FailureManager**, **PlanManager**, **ReflectionManager** (Phase 2 memory-type slots), **ReflectionStage** + **ProspectivePromotionStage** (pipeline stages) |
62
- | `core/` | 25 | ManagerContext, EntityManager (with OCC), RelationManager (with temporal validity), ObservationManager (with bitemporal axis), HierarchyManager, GraphStorage, SQLiteStorage, GraphTraversal, TransactionManager, RefIndex, **FileSegmentStorage**, **WriteAheadLog** + **EntityProxy**, **JsonlColumnStore**, **TieredIndex** (`LRUHotTier`/`DiskWarmTier`/`BrotliColdTier`), **IMmapBackend** / **BufferMmapBackend** / **FsReadMmapBackend** |
63
- | `search/` | 55 | SearchManager, RankedSearch (TF-IDF), BM25Search (incremental), BooleanSearch, FuzzySearch, SemanticSearch, HybridSearchManager, NGramIndex, TemporalQueryParser, TemporalSearch, LLMQueryPlanner, LLMSearchExecutor, EmbeddingService, VectorStore, **SparqlExecutor** (minimal subset), **PartialIndexAdvisor** |
64
- | `features/` | 20 | IOManager (with RDF/Turtle/JSON-LD export), **BackupManager**, ArchiveManager, CompressionManager, StreamingExporter, FreshnessManager, AuditLog, GovernanceManager, ContradictionDetector, SemanticForget, AutoLinker, **CRDT**, **AnomalyDetector** |
65
- | `utils/` | 34 | BatchProcessor, CompressedCache, WorkerPoolManager, MemoryMonitor, schemas (Zod), **ICompressionAdapter** / **BrotliCompressionAdapter** / **ZlibCompressionAdapter** / **IdentityCompressionAdapter** / **CompressedMap**, structured `logger`, scheduler/explainPlan/indexHealth diagnostics |
66
- | `types/` | 7 | Entity, Relation, AgentEntity, SessionEntity, ArtifactEntity, Procedure, **ProspectiveEntity** / **FailureEntity** / **PlanEntity** / **ReflectionEntity** (Phase 2 per-type entities), **TrustLevel** mixin on `MemorySource` |
67
- | `security/` | 5 | **PiiRedactor** + bundled patterns (email/SSN/CC/phone/IP), **ABAC + RLS + API keys** |
68
- | `cli/` | 16 | `memory` / `memoryjs` binary commands (entity, relation, search, observation, tag, hierarchy, graph, io, maintenance) + pipe support |
69
- | `adapters/` | 4 | `IDatabaseAdapter` / `IVectorDBAdapter` interfaces, `LangChainMemoryAdapter`, `RestRouter` |
70
- | `workers/` | 2 | Levenshtein distance calculations |
71
-
72
- **Total:** 235 TypeScript files | 79,378 lines of code | 7127+ passing tests | 11 modules | 1 runtime + 3 type-only circular dependencies (see `docs/architecture/DEPENDENCY_GRAPH.md`)
73
-
74
- ### Agent Memory
75
-
76
- | Capability | Entry point |
77
- |-----------|-------------|
78
- | Sessions, working memory, episodic memory | `ctx.agentMemory()` — `startSession` / `addWorkingMemory` / `retrieveForContext` |
79
- | Turn-aware conversation memory with 4-tier dedup (exact / prefix / Jaccard / semantic) | `ctx.memoryEngine.addTurn()` / `getSessionTurns()` |
80
- | Time-based decay, salience scoring, freshness | `DecayEngine`, `SalienceEngine`, `ctx.freshnessManager` |
81
- | Role profiles (`researcher` / `planner` / `executor` / `reviewer` / `coordinator`) | `MEMORY_AGENT_ROLE` / `RoleProfileManager.apply(role)` |
82
- | Memory consolidation, summarization, pattern detection | `ConsolidationPipeline`, `ConsolidationScheduler` |
83
- | Collaborative synthesis across agents with conflict resolution | `CollaborativeSynthesis.synthesize()` / `resolveConflicts()` |
84
- | Failure-driven distillation, cognitive load analysis | `FailureDistillation`, `CognitiveLoadAnalyzer` |
85
- | Procedural memory (executable procedures with feedback refinement) | `ctx.procedureManager.addProcedure()` / `matchProcedure()` / `refineProcedure()` |
86
- | Active retrieval (iterative query rewriting) | `ctx.activeRetrieval.adaptiveRetrieve()` |
87
- | Causal reasoning (causes / effects / counterfactuals / cycle detection) | `ctx.causalReasoner.findCauses()` / `findEffects()` / `counterfactual()` |
88
- | World-state orchestrator | `ctx.worldModelManager.getCurrentState()` / `predictOutcome()` |
89
- | Per-agent persistent journal | `AgentMemoryManager.writeDiary()` / `readDiary()` |
90
- | Prospective memory (intentions-to-act with discriminated lifecycle) | `ctx.prospectiveMemory.schedule()` / `fire()` / `cancel()` |
91
- | Failure memory (pre-task `applicability_hint` lookup) | `ctx.failureManager.record()` / `lookupForTask()` / `markResolved()` |
92
- | Plan memory (hierarchical goal trees with invariant validation) | `ctx.plan.createPlan()` / `pushSubGoal()` / `transitionNode()` / `getCurrentPath()` |
93
- | Reflection memory (additive derived insights with content-hash dedup) | `ctx.reflectionManager.create()` / `getRelevantForSession()` / `archive()` |
94
- | Trust hierarchy (`ground-truth` / `verified` / `inferred` / `unverified`) | `MemorySource.trustLevel?:` + `'trust_level'` `ConflictStrategy` + `inferTrustLevel()` backfill |
95
-
96
- ### Search & Retrieval
97
-
98
- | Capability | Entry point |
99
- |-----------|-------------|
100
- | Auto-selecting search with method explanation | `ctx.searchManager.autoSearch(query)` |
101
- | TF-IDF + BM25 ranked search (incremental indexing) | `ctx.rankedSearch`, `BM25Search` |
102
- | Boolean (AND / OR / NOT) with AST parser | `ctx.searchManager.booleanSearch()` |
103
- | Fuzzy matching (Levenshtein, N-gram pre-filtered) | `ctx.searchManager.fuzzySearch()` |
104
- | Semantic search with pluggable embedding provider | `ctx.semanticSearch` (set `MEMORY_EMBEDDING_PROVIDER`) |
105
- | Hybrid (semantic + lexical + symbolic) | `ctx.hybridSearch` |
106
- | Temporal range queries with natural-language parsing | `ctx.searchManager.searchByTime("last hour")` |
107
- | LLM-planned natural-language queries | `ctx.queryNaturalLanguage(query, llmProvider?)` |
108
- | Minimal SPARQL subset (BGP / FILTER / OPTIONAL / UNION) | `ctx.sparqlExecutor.query()` |
109
- | Query diagnostics (`explainPlan`, index health) | `ctx.diagnostics` |
110
-
111
- ### Knowledge Graph
112
-
113
- | Capability | Entry point |
114
- |-----------|-------------|
115
- | Entity / relation / observation CRUD | `ctx.entityManager`, `ctx.relationManager`, `ctx.observationManager` |
116
- | Optimistic concurrency control on updates | `entityManager.updateEntity(name, updates, { expectedVersion })` |
117
- | Bitemporal versioning (entities + observations) | `invalidateEntity()` / `entityAsOf()` / `entityTimeline()` |
118
- | Temporal relations (validity windows) | `relationManager.invalidateRelation()` / `queryAsOf()` / `timeline()` |
119
- | Memory versioning with contradiction-driven supersession | `Entity.version` / `parentEntityName` / `rootEntityName` / `supersededBy` |
120
- | Project scoping | `Entity.projectId` + `MEMORY_DEFAULT_PROJECT_ID` |
121
- | Two-tier deletion (exact match → 0.85 semantic fallback) | `ctx.semanticForget` |
122
- | Hierarchical nesting + traversal (ancestors / descendants / subtrees) | `ctx.hierarchyManager` |
123
- | Graph algorithms — shortest path, all paths, BFS / DFS | `ctx.graphTraversal.findShortestPath()` |
124
- | Centrality — degree, betweenness, PageRank, HITS hub/authority | `ctx.graphTraversal.pageRank()` / `hits()` |
125
- | Community detection (Louvain), clique enumeration | `ctx.graphTraversal.louvainCommunities()` / `findMaximalCliques()` |
126
- | Stable named references for entity name changes | `ctx.refIndex.register()` / `resolve()` |
127
- | Tag aliases, importance scores (0–10) | `ctx.tagManager`, `Entity.importance` |
128
- | Multi-format import / export JSON, CSV, GraphML, GEXF, DOT, Markdown, Mermaid | `ctx.ioManager.exportGraph(format)` |
129
- | W3C Linked Data export Turtle, RDF/XML, JSON-LD | `ctx.ioManager.exportGraph('turtle' \| 'rdf-xml' \| 'json-ld')` |
130
- | Conversation ingestion (format-agnostic) | `ctx.ioManager.ingest(input, options)` |
131
-
132
- ### Storage & Performance
133
-
134
- | Capability | Entry point |
135
- |-----------|-------------|
136
- | JSONL or SQLite backend (FTS5, BM25, WAL mode) | `MEMORY_STORAGE_TYPE=jsonl\|sqlite` |
137
- | Pluggable Memory Engine backend | `MEMORY_BACKEND=sqlite\|in-memory` |
138
- | Memory-mapped file loading for stores > 100 MB | `MEMORY_USE_MMAP=true`, `MEMORY_MMAP_THRESHOLD_BYTES` |
139
- | Segment-sharded JSONL (FNV-routed N-way shards) | `MEMORY_STORAGE_SEGMENT_COUNT=1..1024` |
140
- | Columnar observation storage | `JsonlColumnStore`, `ObservationColumn` |
141
- | Tiered index LRU hot / disk warm / Brotli cold | `LRUHotTier` `DiskWarmTier` `BrotliColdTier` via `TieredIndex` |
142
- | In-memory entity-cache compression (Zlib / Brotli / Identity) | `ctx.compressedEntityCache`, `CompressedMap` |
143
- | Write-ahead log + entity proxy for durable mutations | `WriteAheadLog`, `EntityProxy` |
144
- | Backup lifecycle (create / list / restore / delete / cleanOld) with symlink-attack guards | `ctx.ioManager` (delegates to `BackupManager`) |
145
- | Streaming export with Brotli compression | `ctx.streamingExporter` |
146
- | Entity archival to compressed storage | `ctx.archiveManager` |
147
- | Duplicate detection + entity merging | `ctx.compressionManager` |
148
- | LSH-based anomaly detection | `ctx.anomalyDetector` |
149
-
150
- ### Governance, Security, Multi-Agent
151
-
152
- | Capability | Entry point |
153
- |-----------|-------------|
154
- | Policy enforcement + transactional rollback | `ctx.governanceManager.withTransaction()` / `GovernancePolicy` |
155
- | Immutable JSONL audit trail | `ctx.auditLog` |
156
- | Strict-mode attribution enforcer | `CollaborationAuditEnforcer` (requires `agentId` on every mutation) |
157
- | RBAC — role / permission / matrix / middleware | `ctx.rbacMiddleware.checkPermission()` / `ctx.roleAssignmentStore` |
158
- | ABAC + row-level security + API-key scoping | `src/security/abac.ts`, `rls.ts`, `apiKeys.ts` |
159
- | PII redactor (email / SSN / CC / phone / IP) with per-pattern stats | `new PiiRedactor().redactGraph()` / `redactWithStats()` |
160
- | Visibility hierarchies 5-level (`private` / `team` / `org` / `shared` / `public`) | `VisibilityResolver.canAccess()` |
161
- | Time-window + role-gated visibility | `AgentEntity.visibleFrom` / `visibleUntil` / `allowedRoles[]` |
162
- | CRDT primitives for multi-writer scenarios | `src/features/CRDT.ts` |
163
- | Path-traversal protection (defense-in-depth) | `validateFilePath(path, baseDir?, confineToBase=true)` |
164
-
165
- ## What's New
166
-
167
- **Unreleased (Phase 2 memory-types expansion, 2026-05)** — Four catalog-aligned `MemoryType` slots and one provenance mixin land on top of v1.15:
168
- - **Sprint 4 — Failure Memory**: `FailureManager` + `MemoryType: 'failure'` + `ctx.failureManager`. Structured `FailureRecord` with `applicability_hint` retrieval key; pre-task `lookupForTask(taskContext)` scoring; discriminated `MarkResolvedResult`.
169
- - **Sprint 5 — Plan / Goal Stack**: `PlanManager` + `MemoryType: 'plan'` + `ctx.plan`. Recursive `GoalNode` tree with discriminated `PlanLifecycle` / `GoalNodeLifecycle`, branded `PlanId` / `GoalNodeId`, `validatePlanInvariants` after every mutation, cycle-protected DFS.
170
- - **Sprint 6 Trust Hierarchy formalization (partial)**: `TrustLevel` discriminated mixin on `MemorySource` (`'ground-truth' | 'verified' | 'inferred' | 'unverified'`) with `inferTrustLevel` backfill and `'trust_level'` `ConflictStrategy`. `CollaborativeSynthesis.resolveConflicts` ordering integration deferred.
171
- - **Sprint 8 — Reflection Log scheduled pass**: `ReflectionManager` + `MemoryType: 'reflection'` + `ReflectionStage` pipeline stage + `ctx.reflectionManager` (publicly aliased as `ReflectionMemoryManager`). Additive (no supersession); content-hash dedup at create; session-end scheduling via `runOnSessionEnd(sessionId)` helper.
172
-
173
- **v1.15.0** Twelve-phase performance & scale track adding mmap-backed I/O, segment-sharded JSONL, columnar observation storage, tiered indexing, pluggable in-memory compression, a minimal SPARQL subset, write-ahead log, extracted `BackupManager`, CRDT primitives, ABAC + RLS + API keys, HITS / clique / Louvain graph algorithms, and a hardened security baseline (`crypto.randomBytes` for IDs, ReDoS-resistant regex escapes, bounded `TaskQueue`).
174
-
175
- See [CHANGELOG.md](CHANGELOG.md) for the full per-version history. The roadmap and remaining items live in [`docs/roadmap/ROADMAP.md`](docs/roadmap/ROADMAP.md) and [`docs/roadmap/MEMORY_TYPES_EXPANSION_PHASE_2.md`](docs/roadmap/MEMORY_TYPES_EXPANSION_PHASE_2.md).
176
-
177
- ## Installation
178
-
179
- ```bash
180
- npm install @danielsimonjr/memoryjs
181
- ```
182
-
183
- ### Requirements
184
-
185
- - Node.js >= 18.0.0
186
- - TypeScript >= 5.0 (for development)
187
-
188
- ## Quick Start
189
-
190
- ### 1. Initialize Storage
191
-
192
- ```typescript
193
- import { ManagerContext } from '@danielsimonjr/memoryjs';
194
-
195
- // JSONL storage (default, human-readable)
196
- const ctx = new ManagerContext('./memory.jsonl');
197
-
198
- // Or SQLite storage (set MEMORY_STORAGE_TYPE=sqlite env var)
199
- const ctx = new ManagerContext('./memory.db');
200
- ```
201
-
202
- ### 2. Create Entities
203
-
204
- ```typescript
205
- await ctx.entityManager.createEntities([
206
- {
207
- name: 'TypeScript',
208
- entityType: 'language',
209
- observations: ['A typed superset of JavaScript'],
210
- tags: ['programming', 'frontend'],
211
- importance: 8
212
- },
213
- {
214
- name: 'Node.js',
215
- entityType: 'runtime',
216
- observations: ['JavaScript runtime built on V8'],
217
- tags: ['backend', 'server']
218
- }
219
- ]);
220
- ```
221
-
222
- ### 3. Create Relations
223
-
224
- ```typescript
225
- await ctx.relationManager.createRelations([
226
- { from: 'TypeScript', to: 'Node.js', relationType: 'runs_on' }
227
- ]);
228
- ```
229
-
230
- ### 4. Search
231
-
232
- ```typescript
233
- // Basic search
234
- const results = await ctx.searchManager.search('JavaScript');
235
-
236
- // Ranked search (TF-IDF scoring)
237
- const ranked = await ctx.searchManager.searchRanked('runtime environment', { limit: 10 });
238
-
239
- // Boolean search
240
- const filtered = await ctx.searchManager.booleanSearch('TypeScript AND runtime');
241
-
242
- // Fuzzy search (typo-tolerant; N-gram pre-filtered)
243
- const fuzzy = await ctx.searchManager.fuzzySearch('Typscript', { threshold: 0.7 });
244
-
245
- // Active retrieval iterative query rewriting until coverage threshold
246
- const adaptive = await ctx.activeRetrieval.adaptiveRetrieve({ query: 'memory leak' });
247
- console.log(adaptive.bestResults, adaptive.bestCoverage, adaptive.rounds);
248
- ```
249
-
250
- ### 5. Multi-agent collaboration
251
-
252
- ```typescript
253
- // Optimistic concurrency control — fail loudly on stale writes
254
- try {
255
- await ctx.entityManager.updateEntity('Alice',
256
- { importance: 9 },
257
- { expectedVersion: 3 });
258
- } catch (e) {
259
- if (e.name === 'VersionConflictError') {
260
- // Refetch + retry
261
- }
262
- }
263
-
264
- // Detect cross-agent conflicts after collaborative synthesis
265
- const synth = await ctx.agentMemory().collaborativeSynthesis.synthesize('Alice');
266
- const winners = ctx.agentMemory().collaborativeSynthesis.resolveConflicts(synth, {
267
- strategy: 'highest_confidence',
268
- });
269
-
270
- // Enforce attribution on every mutation
271
- import { CollaborationAuditEnforcer, AuditLog } from '@danielsimonjr/memoryjs';
272
- const enforcer = new CollaborationAuditEnforcer(
273
- ctx.entityManager,
274
- new AuditLog('./audit.jsonl'),
275
- );
276
- await enforcer.createEntities([{ name: 'X', entityType: 't', observations: ['fact'] }],
277
- 'agent-alice'); // throws AttributionRequiredError if agentId is missing
278
- ```
279
-
280
- ### 6. Bitemporal versioning
281
-
282
- ```typescript
283
- // Mark an entity as no longer valid at a specific time
284
- await ctx.entityManager.invalidateEntity('OldFact', '2025-12-31T00:00:00Z');
285
-
286
- // Time-travel query
287
- const past = await ctx.entityManager.entityAsOf('Alice', '2024-06-15T00:00:00Z');
288
-
289
- // Per-observation validity windows
290
- await ctx.observationManager.invalidateObservation(
291
- 'Alice', 'works at Acme', '2024-12-31T00:00:00Z',
292
- );
293
- const obsAtTime = await ctx.observationManager.observationsAsOf(
294
- 'Alice', '2024-06-15T00:00:00Z',
295
- );
296
- ```
297
-
298
- ### 7. Causal reasoning and world model
299
-
300
- ```typescript
301
- // Forward inference — "what does X cause?"
302
- const effects = await ctx.causalReasoner.findEffects('rain', ['flooding', 'erosion']);
303
- // Counterfactual — "what if we remove this edge?"
304
- const surviving = await ctx.causalReasoner.counterfactual({
305
- seed: 'rain', removeFrom: 'rain', removeTo: 'flooding', predict: 'flooding',
306
- });
307
-
308
- // World model snapshot + diff
309
- const before = await ctx.worldModelManager.getCurrentState();
310
- // ... mutations ...
311
- const after = await ctx.worldModelManager.getCurrentState();
312
- const change = ctx.worldModelManager.detectStateChange(before, after);
313
- ```
314
-
315
- ### 8. RBAC and PII redaction
316
-
317
- ```typescript
318
- // Grant a role
319
- await ctx.roleAssignmentStore.assign({
320
- agentId: 'alice', role: 'writer', resourceType: 'entity',
321
- });
322
- ctx.rbacMiddleware.checkPermission('alice', 'write', 'entity'); // true
323
-
324
- // Redact PII from any export
325
- import { PiiRedactor } from '@danielsimonjr/memoryjs';
326
- const redactor = new PiiRedactor();
327
- const cleanGraph = redactor.redactGraph(graph);
328
- const { text, stats } = redactor.redactWithStats(observation);
329
- ```
330
-
331
- ## Core Concepts
332
-
333
- ### Entities
334
-
335
- Primary nodes in the knowledge graph.
336
-
337
- ```typescript
338
- interface Entity {
339
- name: string; // Unique identifier
340
- entityType: string; // Classification (person, project, concept)
341
- observations: string[]; // Facts about the entity
342
- parentId?: string; // Parent entity for hierarchical nesting
343
- tags?: string[]; // Lowercase tags for categorization
344
- importance?: number; // 0-10 scale for prioritization
345
- createdAt?: string; // ISO 8601 timestamp
346
- lastModified?: string; // ISO 8601 timestamp
347
-
348
- // Freshness
349
- ttl?: number; // Seconds until stale
350
- confidence?: number; // [0, 1] belief strength
351
-
352
- // Project scoping + supersession
353
- projectId?: string; // Multi-project isolation
354
- version?: number; // Supersession chain version (also drives η.5.5.c OCC)
355
- parentEntityName?: string;
356
- rootEntityName?: string;
357
- isLatest?: boolean;
358
- supersededBy?: string;
359
-
360
- // Memory Engine dedup
361
- contentHash?: string; // SHA-256 for O(1) Tier-1 dedup
362
-
363
- // η.4.4 — Bitemporal validity (orthogonal to supersession)
364
- validFrom?: string; // Entity valid from this instant
365
- validUntil?: string; // Entity valid until this instant
366
- observationMeta?: Array<{ // Per-observation validity windows
367
- content: string;
368
- validFrom?: string;
369
- validUntil?: string;
370
- recordedAt?: string; // Bitemporal axis
371
- }>;
372
- }
373
- ```
374
-
375
- ### Relations
376
-
377
- Directed connections between entities.
378
-
379
- ```typescript
380
- interface Relation {
381
- from: string; // Source entity name
382
- to: string; // Target entity name
383
- relationType: string; // Relationship type (active voice)
384
- }
385
- ```
386
-
387
- ### Observations
388
-
389
- Discrete facts about entities. Each observation should be atomic and independently manageable. Use `addObservations()` to append new facts without overwriting existing ones.
390
-
391
- ### ManagerContext
392
-
393
- Central access point for all managers with lazy initialization:
394
-
395
- ```typescript
396
- // Core
397
- ctx.entityManager // Entity CRUD + hierarchy + temporal validity + OCC
398
- ctx.relationManager // Relation management + temporal invalidation
399
- ctx.observationManager // Observation CRUD + bitemporal axis
400
- ctx.hierarchyManager // Entity tree (parents, children, ancestors)
401
- ctx.searchManager // All search operations (incl. searchByTime)
402
- ctx.rankedSearch // TF-IDF / BM25 ranked search
403
- ctx.graphTraversal // BFS / DFS / shortest path / centrality
404
- ctx.tagManager // Tag aliases + bulk operations
405
- ctx.refIndex // Stable name entity O(1) lookup
406
-
407
- // Storage + I/O
408
- ctx.ioManager // Import / export (incl. RDF/Turtle/JSON-LD) / backup / ingest
409
- ctx.archiveManager // Entity archival
410
- ctx.compressionManager // Duplicate detection, entity merging
411
- ctx.analyticsManager // Graph statistics + validation
412
- ctx.semanticForget // Two-tier deletion with audit
413
- ctx.governanceManager // Transactions + policy enforcement (canCreate/Update/Delete)
414
- ctx.freshnessManager // TTL/confidence freshness reports
415
-
416
- // Search extensions
417
- ctx.semanticSearch // Vector similarity (lazy; needs embedding provider)
418
- ctx.temporalSearch // Natural language time-range search
419
- ctx.activeRetrieval // 3B.5 iterative query rewriting (no LLM)
420
- ctx.llmQueryPlanner() // NL StructuredQuery decomposition (optional LLM)
421
- ctx.queryNaturalLanguage // Convenience wrapper around the planner
422
-
423
- // Memory + agent
424
- ctx.memoryEngine // Turn-aware conversation memory (4-tier dedup)
425
- ctx.memoryBackend // Pluggable IMemoryBackend (in-memory / sqlite)
426
- ctx.contextWindowManager // 4-layer wake-up stack + token budgeting
427
- ctx.agentMemory() // Full Agent Memory System facade
428
-
429
- // Memory intelligence
430
- ctx.memoryValidator // Validate consistency / contradictions / temporal order
431
- ctx.trajectoryCompressor // Distill / abstract / merge redundant trajectories
432
- ctx.experienceExtractor // Cluster trajectories → reusable experience patterns
433
- ctx.patternDetector // Trigger / sequence / outcome pattern mining
434
-
435
- // Memory theory
436
- ctx.procedureManager // 3B.4 — executable procedure memory + EWMA refinement
437
- ctx.causalReasoner // 3B.6 — findCauses / findEffects / counterfactual
438
- ctx.worldModelManager // 3B.7 — snapshot orchestrator + state-change diff
439
-
440
- // Access control + audit
441
- ctx.roleAssignmentStore // η.6.1 — role grants registry
442
- ctx.rbacMiddleware // η.6.1 RbacPolicy.checkPermission()
443
- ctx.accessTracker // Per-entity access metrics
444
- ```
445
-
446
- ## Storage Options
447
-
448
- ### Comparison
449
-
450
- | Feature | JSONL (Default) | SQLite (better-sqlite3) |
451
- |---------|-----------------|-------------------------|
452
- | Format | Human-readable text | Native binary database |
453
- | Transactions | Basic | Full ACID with WAL mode |
454
- | Full-Text Search | Basic | FTS5 with BM25 ranking |
455
- | Performance | Good | 3-10x faster |
456
- | Concurrency | Single-threaded | Thread-safe with async-mutex |
457
- | Best For | Small graphs, debugging | Large graphs (10k+ entities) |
458
-
459
- ### JSONL Storage
460
-
461
- ```typescript
462
- const ctx = new ManagerContext('./memory.jsonl');
463
- ```
464
-
465
- Features:
466
- - Human-readable line-delimited JSON
467
- - In-memory caching with write-through invalidation
468
- - Atomic writes via temp file + rename
469
- - Backward compatibility for legacy formats
470
-
471
- ### SQLite Storage
472
-
473
- ```typescript
474
- // Set MEMORY_STORAGE_TYPE=sqlite environment variable
475
- const ctx = new ManagerContext('./memory.db');
476
- ```
477
-
478
- Features:
479
- - FTS5 full-text search with BM25 ranking
480
- - WAL mode for better concurrency
481
- - Referential integrity with ON DELETE CASCADE
482
- - ACID transactions
483
-
484
- ### Storage Files
485
-
486
- When using JSONL, related files are automatically created:
487
-
488
- ```
489
- /your/data/directory/
490
- ├── memory.jsonl # Main knowledge graph
491
- ├── memory-saved-searches.jsonl # Saved search queries
492
- ├── memory-tag-aliases.jsonl # Tag synonym mappings
493
- └── .backups/ # Timestamped backups
494
- ```
495
-
496
- ## Search Capabilities
497
-
498
- ### Search Methods
499
-
500
- | Method | Description | Use Case |
501
- |--------|-------------|----------|
502
- | `searchManager.search()` | Basic substring matching | Simple queries |
503
- | `searchManager.searchRanked()` | TF-IDF relevance scoring | Finding most relevant results |
504
- | `searchManager.booleanSearch()` | AND/OR/NOT operators with AST | Complex filtering |
505
- | `searchManager.fuzzySearch()` | Levenshtein + N-gram pre-filter | Typo tolerance |
506
- | `searchManager.hybridSearch()` | Semantic + lexical + symbolic | Multi-signal ranking |
507
- | `searchManager.searchByTime()` | Natural-language time ranges | "last hour", "10 minutes ago" |
508
- | `activeRetrieval.adaptiveRetrieve()` | Iterative rewrite + retrieve | Adaptive coverage refinement |
509
- | `queryNaturalLanguage()` | LLM-planned decomposition | Free-text queries (optional LLM provider) |
510
- | `causalReasoner.findEffects()` | Causal subgraph traversal | Inference over `causes`/`enables`/`prevents` edges |
511
-
512
- ### Basic Search
513
-
514
- ```typescript
515
- const results = await ctx.searchManager.search('TypeScript');
516
- ```
517
-
518
- ### Ranked Search (TF-IDF)
519
-
520
- ```typescript
521
- const ranked = await ctx.searchManager.searchRanked('JavaScript runtime', {
522
- limit: 10,
523
- minScore: 0.1
524
- });
525
- ```
526
-
527
- ### Boolean Search
528
-
529
- ```typescript
530
- // AND - both terms must match
531
- const results = await ctx.searchManager.booleanSearch('TypeScript AND runtime');
532
-
533
- // OR - either term matches
534
- const results = await ctx.searchManager.booleanSearch('frontend OR backend');
535
-
536
- // NOT - exclude term
537
- const results = await ctx.searchManager.booleanSearch('JavaScript NOT browser');
538
-
539
- // Parentheses for grouping
540
- const results = await ctx.searchManager.booleanSearch('(TypeScript OR JavaScript) AND server');
541
- ```
542
-
543
- ### Fuzzy Search
544
-
545
- ```typescript
546
- // Typo-tolerant search with threshold (0-1, higher = stricter)
547
- const results = await ctx.searchManager.fuzzySearch('Typscript', {
548
- threshold: 0.7
549
- });
550
- ```
551
-
552
- ### Hybrid Search
553
-
554
- Combines three signal layers for sophisticated ranking:
555
-
556
- ```typescript
557
- const results = await ctx.searchManager.hybridSearch('programming concepts', {
558
- weights: {
559
- semantic: 0.5, // Vector similarity (requires embeddings)
560
- lexical: 0.3, // TF-IDF text matching
561
- symbolic: 0.2 // Metadata (tags, importance, type)
562
- },
563
- filters: {
564
- entityTypes: ['concept'],
565
- minImportance: 5,
566
- tags: ['programming']
567
- }
568
- });
569
- ```
570
-
571
- ## Graph Algorithms
572
-
573
- ### Path Finding
574
-
575
- ```typescript
576
- // Shortest path between entities (BFS)
577
- const path = await ctx.graphTraversal.findShortestPath('A', 'Z');
578
- // Returns: ['A', 'B', 'C', 'Z']
579
-
580
- // All paths with max depth
581
- const paths = await ctx.graphTraversal.findAllPaths('A', 'Z', { maxDepth: 5 });
582
- // Returns: [['A', 'B', 'Z'], ['A', 'C', 'D', 'Z'], ...]
583
- ```
584
-
585
- ### Centrality Analysis
586
-
587
- ```typescript
588
- // Calculate importance metrics
589
- const centrality = await ctx.graphTraversal.getCentrality({
590
- algorithm: 'pagerank' // or 'degree', 'betweenness'
591
- });
592
- // Returns: Map<string, number> with entity scores
593
- ```
594
-
595
- ### Connected Components
596
-
597
- ```typescript
598
- // Find isolated subgraphs
599
- const components = await ctx.graphTraversal.getConnectedComponents();
600
- // Returns: [['A', 'B', 'C'], ['X', 'Y'], ...]
601
- ```
602
-
603
- ### Traversal
604
-
605
- ```typescript
606
- // Breadth-first traversal
607
- await ctx.graphTraversal.bfs('startNode', (node) => {
608
- console.log('Visited:', node.name);
609
- });
610
-
611
- // Depth-first traversal
612
- await ctx.graphTraversal.dfs('startNode', (node) => {
613
- console.log('Visited:', node.name);
614
- });
615
- ```
616
-
617
- ## Agent Memory System
618
-
619
- A complete memory system for AI agents with working memory, episodic memory, decay mechanisms, and multi-agent support.
620
-
621
- ### Key Components
622
-
623
- | Component | Description |
624
- |-----------|-------------|
625
- | **AgentMemoryManager** | Unified facade for all agent memory operations |
626
- | **SessionManager** | Session lifecycle management |
627
- | **WorkingMemoryManager** | Short-term memory with promotion to long-term |
628
- | **EpisodicMemoryManager** | Timeline-based episodic memory |
629
- | **DecayEngine** | Time-based memory importance decay |
630
- | **SalienceEngine** | Context-aware memory scoring |
631
- | **MultiAgentMemoryManager** | Shared memory with visibility controls |
632
- | **ConflictResolver** | Resolution strategies for concurrent updates |
633
-
634
- ### Quick Start
635
-
636
- ```typescript
637
- import { ManagerContext } from '@danielsimonjr/memoryjs';
638
-
639
- const ctx = new ManagerContext('./memory.jsonl');
640
- const agent = ctx.agentMemory();
641
-
642
- // Start a session
643
- const session = await agent.startSession({ agentId: 'my-agent' });
644
-
645
- // Add working memory
646
- await agent.addWorkingMemory({
647
- sessionId: session.name,
648
- content: 'User prefers dark mode',
649
- importance: 7
650
- });
651
-
652
- // Create episodic memory
653
- await agent.createEpisode('Completed onboarding flow', {
654
- sessionId: session.name,
655
- importance: 8
656
- });
657
-
658
- // Retrieve context for LLM prompt
659
- const context = await agent.retrieveForContext({
660
- maxTokens: 2000,
661
- includeEpisodic: true
662
- });
663
-
664
- // End session
665
- await agent.endSession(session.name);
666
- ```
667
-
668
- ### Memory Types
669
-
670
- ```typescript
671
- type MemoryType =
672
- | 'working' // Short-term, session-scoped memories that may be promoted
673
- | 'episodic' // Timeline-based event memories with temporal ordering
674
- | 'semantic' // Long-term factual knowledge
675
- | 'procedural' // Learned behaviors and patterns (3B.4)
676
- | 'prospective' // (Phase 1) Intentions-to-act at a future time / event / condition
677
- | 'failure' // (Phase 2 Sprint 4) Pre-task failure lookup with applicability_hint
678
- | 'plan' // (Phase 2 Sprint 5) Hierarchical goal trees with sub-tasks + acceptance criteria
679
- | 'reflection'; // (Phase 2 Sprint 8) Additive derived insights with content-hash dedup
680
- ```
681
-
682
- - **Working Memory**: Short-term, session-scoped memories that may be promoted
683
- - **Episodic Memory**: Timeline-based event memories with temporal ordering
684
- - **Semantic Memory**: Long-term factual knowledge
685
- - **Procedural Memory**: Learned behaviors and patterns (`ctx.procedureManager`)
686
- - **Prospective Memory**: Forward-looking intentions with discriminated `ProspectiveLifecycle` (`pending` / `fired` / `cancelled` / `expired`); `ctx.prospectiveMemory`. Catalog Type 4
687
- - **Failure Memory**: Structured `FailureRecord` with `applicability_hint` as the retrieval key; `markResolved` returns discriminated `MarkResolvedResult`; `ctx.failureManager`. Catalog Type 9
688
- - **Plan Memory**: Recursive `GoalNode` tree with discriminated `PlanLifecycle` / `GoalNodeLifecycle`, branded `PlanId` / `GoalNodeId`, `validatePlanInvariants` after every mutation; `ctx.plan`. Catalog Type 6
689
- - **Reflection Memory**: Additive (no supersession of evidence entities) with `ReflectionScope` discriminator (`session` / `project` / `global`); content-hash dedup at `create`; `ctx.reflectionManager`. Catalog Type 10. Produced by `ReflectionStage` pipeline stage
690
-
691
- **Trust-hierarchy mixin** (Phase 2 Sprint 6, Catalog Type 12): every `MemorySource` may carry an optional categorical `trustLevel?: TrustLevel` (`'ground-truth' | 'verified' | 'inferred' | 'unverified'`) — backfilled from `method` + `reliability` via `inferTrustLevel(source)`. Powers the `'trust_level'` `ConflictStrategy` with recency tiebreak.
692
-
693
- ### Decay System
694
-
695
- Memories naturally decay over time unless reinforced:
696
-
697
- ```typescript
698
- // Configure decay behavior
699
- const agent = ctx.agentMemory({
700
- decay: {
701
- halfLifeHours: 168, // 1 week half-life
702
- minImportance: 0.1 // Never fully forget
703
- },
704
- enableAutoDecay: true
705
- });
706
-
707
- // Reinforce important memories
708
- await agent.confirmMemory('memory_name', 0.1); // Boost confidence
709
- await agent.promoteMemory('memory_name', 'episodic'); // Promote to long-term
710
- ```
711
-
712
- ### Multi-Agent Support
713
-
714
- ```typescript
715
- // Register agents
716
- agent.registerAgent('agent_1', {
717
- name: 'Research Agent',
718
- type: 'llm',
719
- trustLevel: 0.8,
720
- capabilities: ['read', 'write']
721
- });
722
-
723
- // Create memories with visibility controls
724
- await agent.addWorkingMemory({
725
- sessionId: session.name,
726
- content: 'Shared insight',
727
- visibility: 'shared', // 'private' | 'shared' | 'public'
728
- ownerAgentId: 'agent_1'
729
- });
730
-
731
- // Cross-agent search
732
- const results = await agent.searchCrossAgent('agent_2', 'query');
733
- ```
734
-
735
- ## API Reference
736
-
737
- ### EntityManager
738
-
739
- | Method | Description |
740
- |--------|-------------|
741
- | `createEntities(entities)` | Create multiple entities |
742
- | `deleteEntities(names)` | Delete entities by name |
743
- | `getEntity(name, options?)` | Get single entity (with optional access tracking) |
744
- | `updateEntity(name, updates, { expectedVersion? })` | Partial update; OCC if `expectedVersion` provided (η.5.5.c) |
745
- | `batchUpdate(updates[])` | Atomic multi-entity update |
746
- | `addTags(name, tags)` / `removeTags(name, tags)` | Tag management |
747
- | `setImportance(name, score)` | Set importance (0-10) |
748
- | `getVersionChain(name)` / `getLatestVersion(name)` | supersession chains |
749
- | `invalidateEntity(name, ended?)` | η.4.4 set `validUntil` |
750
- | `entityAsOf(name, asOf)` | η.4.4 time-travel query |
751
- | `entityTimeline(name)` | η.4.4 versions sorted by `validFrom` |
752
-
753
- ### RelationManager
754
-
755
- | Method | Description |
756
- |--------|-------------|
757
- | `createRelations(relations)` | Create multiple relations |
758
- | `getRelations(entityName)` | Get incoming/outgoing relations |
759
- | `deleteRelations(relations)` | Delete specific relations |
760
- | `invalidateRelation(from, type, to, ended?)` | set `validUntil` on a relation |
761
- | `queryAsOf(entity, asOf, { direction? })` | relations valid at time T |
762
- | `timeline(entity, { direction? })` | chronological history |
763
-
764
- ### ObservationManager
765
-
766
- | Method | Description |
767
- |--------|-------------|
768
- | `addObservations(adds, dedupOptions?)` | Add observations (with optional dedup) |
769
- | `deleteObservations(deletions)` | Remove specific observations |
770
- | `invalidateObservation(entity, content, ended?)` | η.4.4 set per-observation `validUntil` |
771
- | `observationsAsOf(entity, asOf)` | η.4.4 — observations valid at time T |
772
-
773
- ### SearchManager
774
-
775
- | Method | Description |
776
- |--------|-------------|
777
- | `search(query, options)` | Basic substring search |
778
- | `searchRanked(query, options)` | TF-IDF ranked search |
779
- | `booleanSearch(query, options)` | Boolean operators (AND/OR/NOT) |
780
- | `fuzzySearch(query, options)` | Levenshtein-based typo tolerance |
781
- | `hybridSearch(query, options)` | Multi-signal search |
782
- | `autoSearch(query, limit?)` | Auto-select best search method |
783
-
784
- ### IOManager
785
-
786
- | Method | Description |
787
- |--------|-------------|
788
- | `exportGraph(graph, format)` | Export to `json` / `csv` / `graphml` / `gexf` / `dot` / `markdown` / `mermaid` / `turtle` / `rdf-xml` / `json-ld` |
789
- | `exportGraphWithCompression(graph, format, options?)` | Brotli-compressed export |
790
- | `importGraph(format, data, options)` | Import with merge strategies (`replace` / `skip` / `merge` / `fail`) |
791
- | `ingest({ messages }, options?)` | conversation ingestion pipeline |
792
- | `splitSessions(content, options?)` | split multi-session transcripts |
793
- | `visualizeGraph(options?)` | interactive HTML visualization |
794
- | `createBackup(options)` / `restoreBackup(path)` | Backup management |
795
-
796
- ### GraphTraversal
797
-
798
- | Method | Description |
799
- |--------|-------------|
800
- | `findShortestPath(from, to)` | BFS shortest path |
801
- | `findAllPaths(from, to, maxDepth, options?)` | All paths with max depth |
802
- | `getCentrality(options)` | Centrality metrics (degree / betweenness / pagerank) |
803
- | `getConnectedComponents()` | Find isolated subgraphs |
804
- | `bfs(start, options)` / `dfs(start, options)` | Traversal |
805
-
806
- ### CausalReasoner
807
-
808
- | Method | Description |
809
- |--------|-------------|
810
- | `findEffects(cause, candidates, maxDepth?)` | Forward causal inference; sorted by `Π causalStrength` |
811
- | `findCauses(effect, candidates, maxDepth?)` | Backward inference (symmetric inverse) |
812
- | `counterfactual({ seed, removeFrom, removeTo, predict })` | Chains surviving edge removal (pure; no graph mutation) |
813
- | `detectCycles(seed, maxDepth?)` | Depth-bounded DFS over causal subgraph |
814
-
815
- ### ProcedureManager
816
-
817
- | Method | Description |
818
- |--------|-------------|
819
- | `addProcedure({ steps, ... })` | Persist a procedure; auto-generates id |
820
- | `getProcedure(id)` / `getStep(id, order)` / `getNextStep(id, order)` | Access |
821
- | `openSequencer(id)` | Stateful execution cursor with fallback support |
822
- | `matchProcedure(context, candidates, threshold?)` | Token-overlap match |
823
- | `refineProcedure(id, { succeeded, notes? })` | EWMA success-rate update |
824
-
825
- ### WorldModelManager
826
-
827
- | Method | Description |
828
- |--------|-------------|
829
- | `getCurrentState()` | `WorldStateSnapshot` from live graph (capped at `maxSnapshotSize`) |
830
- | `validateFact(observation, entityName)` | Delegates to `MemoryValidator` if wired |
831
- | `predictOutcome(action, candidates)` | Delegates to `CausalReasoner.findEffects` |
832
- | `detectStateChange(before, after)` | Pure snapshot diff |
833
-
834
- ### ActiveRetrievalController
835
-
836
- | Method | Description |
837
- |--------|-------------|
838
- | `shouldRetrieve(context)` | Cost heuristic; rejects empty / over-budget |
839
- | `adaptiveRetrieve(context)` | Iterative rewrite + retrieve until coverage threshold |
840
-
841
- ### CollaborativeSynthesis
842
-
843
- | Method | Description |
844
- |--------|-------------|
845
- | `synthesize(seedEntity, context?)` | BFS + salience scoring; surfaces multi-agent `conflicts[]` |
846
- | `resolveConflicts(result, policy)` | Pick winners per `most_recent` / `highest_confidence` / `highest_score` / `trusted_agent` |
847
-
848
- ### MemoryValidator
849
-
850
- | Method | Description |
851
- |--------|-------------|
852
- | `validateConsistency(newObs, existing)` | Composite duplicate / semantic / low-confidence check |
853
- | `detectContradictions(entity)` | Delegates to `ContradictionDetector` |
854
- | `repairWithResolver(entity, competing, resolver, contradiction?, options?)` | Apply `ConflictResolver` strategies |
855
- | `validateTemporalOrder(observations)` | Sync `[T=ISO]` ordering check |
856
- | `calculateReliability(entity)` | Confidence × confirmation × age penalty |
857
-
858
- ### RbacMiddleware
859
-
860
- | Method | Description |
861
- |--------|-------------|
862
- | `checkPermission(agentId, action, resourceType, resourceName?, now?)` | Returns `true` / `false`; falls back to `defaultRole` (default `reader`) |
863
- | `roleAssignmentStore.assign({ agentId, role, resourceType?, scope?, validFrom?, validUntil? })` | Grant a role |
864
- | `roleAssignmentStore.revoke(agentId, role, resourceType?)` | Remove a grant |
865
- | `roleAssignmentStore.listActive(agentId, now?)` | Active grants at a point in time |
866
-
867
- ### PiiRedactor
868
-
869
- | Method | Description |
870
- |--------|-------------|
871
- | `redact(text)` | Apply patterns; returns redacted string |
872
- | `redactWithStats(text)` | Returns `{ text, stats: { totalRedactedBytes, countsByPattern } }` |
873
- | `redactGraph(graph)` | Apply to every observation in a graph-shaped object |
874
-
875
- ### ProspectiveMemoryManager (`ctx.prospectiveMemory`)
876
-
877
- | Method | Description |
878
- |--------|-------------|
879
- | `schedule(intention, options?)` | Persist a `ProspectiveEntity`; trigger kind `time-based` / `time-window` / `event` / `conditional` |
880
- | `fire(id, result?)` | Transition `pending fired`; returns discriminated `MarkResolvedResult` |
881
- | `cancel(id, reason?)` | Transition `pending cancelled`; returns `CancelResult` |
882
- | `expireDueIntentions()` | Bulk-expire past-due pending intentions; returns count |
883
- | `getPending(filter?)` / `getFired(filter?)` | Query by `sessionId` / `agentId` |
884
-
885
- ### FailureManager (`ctx.failureManager`)
886
-
887
- | Method | Description |
888
- |--------|-------------|
889
- | `record(input, options?)` | Persist a structured `FailureRecord`; validates five required non-empty fields |
890
- | `lookupForTask(taskContext, options?)` | Pre-task substring-match scoring (`applicability_hint` / `context` / `attempted` 1×) |
891
- | `markResolved(id, reason?)` | Returns discriminated `MarkResolvedResult` (`resolved` / `already-resolved` / `not-found` / `vanished-mid-update`) |
892
- | `getAll(options?)` | Filter by `status` and/or `sourceSessionId` |
893
-
894
- ### PlanManager (`ctx.plan`)
895
-
896
- | Method | Description |
897
- |--------|-------------|
898
- | `createPlan(rootDescription, options?)` | Create a single-node plan tree; mints branded `PlanId` |
899
- | `pushSubGoal(planId, parentNodeId, description, options?)` | Append a child `GoalNode`; throws on `persistPlan` failure |
900
- | `transitionNode(planId, nodeId, transition)` | Unified `GoalNodeLifecycle` state-machine entry point |
901
- | `markPlanComplete(planId, note?)` / `abandonPlan(planId, reason?)` | Plan-level lifecycle; returns `MarkResolvedResult` |
902
- | `findPlan` / `findNode` / `getCurrentPath` | `Readonly<>` reads (clone-free) |
903
- | `getActivePlan(sessionId)` / `listPlans(options?)` | Session-scoped + filtered queries |
904
-
905
- ### ReflectionManager (`ctx.reflectionManager`)
906
-
907
- | Method | Description |
908
- |--------|-------------|
909
- | `create(input, options?)` | Persist a `ReflectionRecord`; content-hash dedup on `sha256(scope\|sorted(evidence))` |
910
- | `list(options?)` | Filter by `scope` / `sourceSessionId` / `minConfidence` / `includeArchived` / `limit` |
911
- | `getRelevantForSession(sessionId, options?)` | Reflections matching `sourceSessionId` OR overlapping evidence; confidence-sorted |
912
- | `archive(id)` | Soft-delete; returns discriminated `ArchiveReflectionResult` |
913
- | `ReflectionStage.runOnSessionEnd(sessionId)` | Pipeline stage helper runs the reflection pass scoped to one session |
914
-
915
- ## Configuration
916
-
917
- ### Environment Variables
918
-
919
- The full env-var reference lives in [CLAUDE.md](CLAUDE.md). Most-used:
920
-
921
- | Variable | Description | Default |
922
- |----------|-------------|---------|
923
- | `MEMORY_STORAGE_TYPE` | Storage backend: `jsonl` or `sqlite` | `jsonl` |
924
- | `MEMORY_FILE_PATH` | Override storage file path | (per `ManagerContext` ctor) |
925
- | `MEMORY_BACKEND` | Pluggable Memory Engine backend: `sqlite` or `in-memory` | `sqlite` |
926
- | `MEMORY_EMBEDDING_PROVIDER` | Embedding provider: `openai`, `local`, or `none` | `local` |
927
- | `MEMORY_OPENAI_API_KEY` | OpenAI API key (required if provider is `openai`) | - |
928
- | `MEMORY_AUTO_INDEX_EMBEDDINGS` | Auto-build embedding index on entity create | `false` |
929
- | `MEMORY_AUTO_DECAY` | Enable background memory decay | `false` |
930
- | `MEMORY_DECAY_HALF_LIFE_HOURS` | Half-life for importance decay | `168` |
931
- | `MEMORY_GOVERNANCE_ENABLED` | Enable `GovernanceManager` policy enforcement | `false` |
932
- | `MEMORY_AUDIT_LOG_FILE` | Path for audit JSONL trail | - |
933
- | `MEMORY_AGENT_ROLE` | Apply built-in role profile (`researcher`/`planner`/`executor`/`reviewer`/`coordinator`) | - |
934
- | `MEMORY_VALIDATE_ON_STORE` | Run `MemoryValidator` before observation writes | `false` |
935
- | `MEMORY_AUDIT_ATTRIBUTION_REQUIRED` | `CollaborationAuditEnforcer` strict mode | `false` |
936
- | `MEMORY_RBAC_ENABLED` | Wire `RbacMiddleware` into `GovernancePolicy` | `false` |
937
- | `MEMORY_DEFAULT_VISIBILITY` | Default `AgentEntity.visibility` | `private` |
938
- | `MEMORY_USE_MMAP` | Use mmap (`FsReadMmapBackend`) for `GraphStorage.loadFromDisk` | `false` (strict `'true'` literal match) |
939
- | `MEMORY_MMAP_THRESHOLD_BYTES` | Minimum file size to trigger mmap path; `0` means always-on | `104857600` (100 MB) |
940
- | `MEMORY_STORAGE_SEGMENT_COUNT` | Number of FNV-routed JSONL shards in `FileSegmentStorage` (1–1024) | `1` (off) |
941
- | `MEMORY_SQLITE_READ_POOL_SIZE` | Read-connection pool size for `SQLiteStorage` | `4` |
942
- | `MEMORY_SQLITE_AUTO_INDEX` | Enable `PartialIndexAdvisor`-driven automatic partial-index DDL | `false` |
943
- | `SKIP_BENCHMARKS` | Skip perf benchmark tests | `false` |
944
- | `LOG_LEVEL` | `debug` / `info` / `warn` / `error` | (none) |
945
-
946
- See [CLAUDE.md](CLAUDE.md#environment-variables) for the complete list (~60 variables across decay/salience/context-window/freshness/RBAC/PRD scoring/MemoryEngine/mmap/segment/SQLite-pool/PartialIndex knobs).
947
-
948
- ## Development
949
-
950
- ### Prerequisites
951
-
952
- - Node.js 18+
953
- - npm 9+
954
- - TypeScript 5.0+
955
-
956
- ### Build Commands
957
-
958
- ```bash
959
- npm install # Install dependencies
960
- npm run build # Build TypeScript to dist/ (tsup; ESM + CJS dual output)
961
- npm run build:watch # Watch mode compilation
962
- npm run build:tsc # Bare tsc build (does NOT include workers — use tsup)
963
- npm test # Run all tests
964
- npm run test:watch # Watch mode testing
965
- npm run test:coverage # Run with coverage report
966
- npm run typecheck # Type checking without emit
967
- npm run benchmark # Standalone synthetic benchmarks
968
- npm run bench # Vitest performance suite
969
- SKIP_BENCHMARKS=true npm test # Skip perf tests in main suite
970
- ```
971
-
972
- ### Tooling
973
-
974
- ```bash
975
- npm run audit:plans # Detect plan-doc rot
976
- node tools/create-dependency-graph/create-dependency-graph.ts # Refresh DEPENDENCY_GRAPH.md
977
- node tools/chunking-for-files/chunking-for-files.ts split <file> # Split large files
978
- node tools/chunking-for-files/chunking-for-files.ts merge <manifest> # Merge back
979
- node tools/migrate-from-jsonl-to-sqlite/... # JSONL SQLite migration
980
- ```
981
-
982
- ### Architecture
983
-
984
- ```
985
- ┌──────────────────────────────────────────────────────────────────┐
986
- │ Layer 1: ManagerContext (Central Facade — lazy init) │
987
- └──────────────────────────┬───────────────────────────────────────┘
988
-
989
- ┌──────────────────────────┴───────────────────────────────────────┐
990
- Layer 2: Domain managers (40+ lazy getters)
991
- │ Core: Entity / Relation / Observation / Hierarchy / Search / │
992
- GraphTraversal / Tags / RefIndex │
993
- │ I/O: IOManager / Archive / Compression / Analytics / Audit /
994
- Governance / Freshness / SemanticForget │
995
- │ Search: Ranked / Hybrid / Semantic / Temporal / LLMQueryPlanner │
996
- / ActiveRetrievalController │
997
- │ Memory: MemoryEngine / MemoryBackend / ContextWindowManager / │
998
- │ AgentMemory(facade) │
999
- │ Intel: MemoryValidator / TrajectoryCompressor / │
1000
- │ ExperienceExtractor / PatternDetector │
1001
- │ Theory: ProcedureManager / CausalReasoner / WorldModelManager │
1002
- │ Auth: RbacMiddleware / RoleAssignmentStore / AccessTracker │
1003
- └──────────────────────────┬───────────────────────────────────────┘
1004
-
1005
- ┌──────────────────────────┴───────────────────────────────────────┐
1006
- │ Layer 3: Storage │
1007
- │ GraphStorage (JSONL) or SQLiteStorage (better-sqlite3, FTS5)
1008
- │ ─ Pluggable IMemoryBackend: in-memory or sqlite-backed engine │
1009
- └──────────────────────────────────────────────────────────────────┘
1010
- ```
1011
-
1012
- ### Project Structure
1013
-
1014
- ```
1015
- memoryjs/
1016
- ├── src/ # Source (183 TypeScript files, 62.7K LOC)
1017
- │ ├── index.ts # Entry point
1018
- │ ├── agent/ # Agent Memory System (61 files)
1019
- │ │ ├── AgentMemoryManager.ts # Unified facade
1020
- │ │ ├── SessionManager.ts # Session lifecycle
1021
- │ │ ├── WorkingMemoryManager.ts # Working memory + promotion
1022
- │ │ ├── EpisodicMemoryManager.ts # Timeline-based events
1023
- │ │ ├── DecayEngine.ts # Decay (legacy + PRD scales)
1024
- │ │ ├── SalienceEngine.ts # Context-aware scoring
1025
- │ │ ├── MultiAgentMemoryManager.ts # Multi-agent support
1026
- │ │ ├── ConflictResolver.ts # Concurrent-update resolution
1027
- │ │ ├── ArtifactManager.ts # Stable artifact entities
1028
- │ │ ├── DistillationPipeline.ts # Post-retrieval policy filter
1029
- │ │ ├── RoleProfiles.ts # 5 built-in roles + presets
1030
- │ │ ├── EntropyFilter.ts # Shannon entropy gate
1031
- │ │ ├── ConsolidationScheduler.ts # Background dedup+merge
1032
- │ │ ├── MemoryFormatter.ts # formatWithSalienceBudget()
1033
- │ │ ├── CollaborativeSynthesis.ts # Multi-agent merge + ConflictView
1034
- │ │ ├── FailureDistillation.ts # Causal-chain lesson extraction
1035
- │ │ ├── CognitiveLoadAnalyzer.ts # Density + redundancy + diversity
1036
- │ │ ├── VisibilityResolver.ts # 5-level + role + time-window
1037
- │ │ ├── ContextWindowManager.ts # 4-layer wake-up stack
1038
- │ │ ├── MemoryEngine.ts # Turn-aware + 4-tier dedup (v1.11)
1039
- │ │ ├── MemoryBackend.ts # IMemoryBackend interface (v1.12)
1040
- │ │ ├── InMemoryBackend.ts # Ephemeral adapter
1041
- │ │ ├── SQLiteBackend.ts # SQLite-backed adapter
1042
- │ │ ├── MemoryValidator.ts # Memory consistency / contradiction checks
1043
- │ │ ├── TrajectoryCompressor.ts # Distill / merge trajectory data
1044
- │ │ ├── ExperienceExtractor.ts # Pattern abstraction from contrastive pairs
1045
- │ │ ├── PatternDetector.ts # Sequence + outcome mining
1046
- │ │ ├── causal/ # 3B.6 — CausalReasoner
1047
- │ │ ├── procedural/ # 3B.4 — ProcedureManager + Sequencer
1048
- │ │ ├── retrieval/ # 3B.5 — ActiveRetrievalController
1049
- │ │ ├── world/ # 3B.7 — WorldModelManager + Snapshot
1050
- │ │ ├── rbac/ # η.6.1 — Role/Permission/Matrix/Middleware
1051
- │ │ ├── collaboration/ # η.5.5.d — CollaborationAuditEnforcer
1052
- │ │ └── ...
1053
- │ ├── core/ # Core managers (14 files)
1054
- │ │ ├── ManagerContext.ts # Central facade (lazy)
1055
- │ │ ├── EntityManager.ts # CRUD + hierarchy + OCC + temporal
1056
- │ │ ├── RelationManager.ts # CRUD + temporal validity
1057
- │ │ ├── ObservationManager.ts # CRUD + per-obs validity windows
1058
- │ │ ├── HierarchyManager.ts # Tree traversal
1059
- │ │ ├── GraphStorage.ts # JSONL I/O + atomic writes
1060
- │ │ ├── SQLiteStorage.ts # SQLite + FTS5 + BM25
1061
- │ │ ├── GraphTraversal.ts # BFS / DFS / paths / centrality
1062
- │ │ ├── TransactionManager.ts # ACID batch operations
1063
- │ │ ├── RefIndex.ts # O(1) name → entity sidecar
1064
- │ │ └── ...
1065
- │ ├── search/ # Search (37 files)
1066
- │ │ ├── SearchManager.ts # Orchestrator
1067
- │ │ ├── RankedSearch.ts # TF-IDF
1068
- │ │ ├── BM25Search.ts # Okapi BM25 with stopwords
1069
- │ │ ├── BooleanSearch.ts # AND/OR/NOT AST
1070
- │ │ ├── FuzzySearch.ts # Levenshtein + N-gram pre-filter
1071
- │ │ ├── SemanticSearch.ts # Embedding-based
1072
- │ │ ├── HybridSearchManager.ts # Multi-signal scoring
1073
- │ │ ├── NGramIndex.ts # Trigram + Jaccard
1074
- │ │ ├── TemporalSearch.ts # Time-range execution
1075
- │ │ ├── LLMQueryPlanner.ts # NL → StructuredQuery
1076
- │ │ └── ...
1077
- │ ├── features/ # Advanced capabilities (17 files)
1078
- │ │ ├── IOManager.ts # Import / export (incl. RDF/JSON-LD) / backup / ingest
1079
- │ │ ├── TagManager.ts # Tag aliases
1080
- │ │ ├── ArchiveManager.ts # Entity archival
1081
- │ │ ├── CompressionManager.ts # Duplicate detection
1082
- │ │ ├── FreshnessManager.ts # TTL/confidence
1083
- │ │ ├── AuditLog.ts # JSONL immutable trail
1084
- │ │ ├── GovernanceManager.ts # Transactions + policy
1085
- │ │ ├── ContradictionDetector.ts # Semantic-similarity supersession
1086
- │ │ ├── SemanticForget.ts # Two-tier deletion
1087
- │ │ └── ...
1088
- │ ├── cli/ # CLI binary (16 files)
1089
- │ ├── security/ # PII redaction (2 files; η.6.3)
1090
- │ ├── types/ # TypeScript definitions (7 files)
1091
- │ ├── utils/ # Shared utilities (26 files)
1092
- │ └── workers/ # Worker pool (2 files)
1093
- ├── tests/ # 6157 passing tests
1094
- │ ├── unit/ # Per-module unit tests
1095
- │ ├── integration/ # Cross-module workflows
1096
- │ ├── edge-cases/ # Boundary conditions
1097
- │ └── performance/ # Benchmarks (gated by SKIP_BENCHMARKS)
1098
- ├── docs/ # Documentation
1099
- │ ├── architecture/ # OVERVIEW, ARCHITECTURE, DEPENDENCY_GRAPH, etc.
1100
- │ ├── development/ # ADRs (incl. ADR-011 wrap-and-extend)
1101
- │ ├── guides/ # API reference, configuration, recipes
1102
- │ ├── roadmap/ # ROADMAP.md
1103
- │ └── superpowers/plans/ # Phase α–η implementation plans
1104
- ├── tools/ # Dev utilities
1105
- │ ├── chunking-for-files/ # File splitting / merging
1106
- │ ├── compress-for-context/ # LLM-context compression
1107
- │ ├── create-dependency-graph/ # Generates DEPENDENCY_GRAPH.md
1108
- │ ├── migrate-from-jsonl-to-sqlite/ # Storage migration
1109
- │ └── plan-doc-audit/ # Plan-doc rot detection (audit:plans)
1110
- ├── CLAUDE.md # Full env-var + architecture reference
1111
- ├── CHANGELOG.md # Version-by-version history
1112
- └── README.md # This file
1113
- ```
1114
-
1115
- ## Documentation
1116
-
1117
- Comprehensive architecture documentation in `docs/architecture/`:
1118
-
1119
- - [OVERVIEW.md](docs/architecture/OVERVIEW.md) - High-level project overview
1120
- - [ARCHITECTURE.md](docs/architecture/ARCHITECTURE.md) - Technical architecture and design
1121
- - [COMPONENTS.md](docs/architecture/COMPONENTS.md) - Component breakdown
1122
- - [DATAFLOW.md](docs/architecture/DATAFLOW.md) - Data flow patterns
1123
- - [API.md](docs/architecture/API.md) - Complete API documentation
1124
- - [DEPENDENCY_GRAPH.md](docs/architecture/DEPENDENCY_GRAPH.md) - Module dependencies (auto-generated by `tools/create-dependency-graph`)
1125
- - [unused-analysis.md](docs/architecture/unused-analysis.md) - Unused exports report
1126
- - [TEST_COVERAGE.md](docs/architecture/TEST_COVERAGE.md) - Test coverage analysis
1127
- - [AGENT_MEMORY.md](docs/architecture/AGENT_MEMORY.md) - Agent memory system design
1128
-
1129
- ADRs and roadmap:
1130
-
1131
- - [ARCHITECTURE_DECISIONS.md](docs/development/ARCHITECTURE_DECISIONS.md) - including ADR-011 (wrap-and-extend pattern for memory intelligence services)
1132
- - [ROADMAP.md](docs/roadmap/ROADMAP.md) - Feature roadmap with implementation details
1133
- - [docs/superpowers/plans/](docs/superpowers/plans/) - Phase α–η implementation plans
1134
-
1135
- Project-internal:
1136
-
1137
- - [CLAUDE.md](CLAUDE.md) - Full environment-variable reference + architecture map
1138
- - [CHANGELOG.md](CHANGELOG.md) - Version-by-version history
1139
-
1140
- ## License
1141
-
1142
- **MIT License** - see [LICENSE](LICENSE)
1143
-
1144
- ## Related
1145
-
1146
- - [@danielsimonjr/memory-mcp](https://github.com/danielsimonjr/memory-mcp) - MCP server built on this library
1147
-
1148
- ---
1149
-
1150
- **Repository:** https://github.com/danielsimonjr/memoryjs
1151
- **NPM:** https://www.npmjs.com/package/@danielsimonjr/memoryjs
1152
- **Issues:** https://github.com/danielsimonjr/memoryjs/issues
1
+ # MemoryJS
2
+
3
+ [![NPM](https://img.shields.io/npm/v/@danielsimonjr/memoryjs.svg)](https://www.npmjs.com/package/@danielsimonjr/memoryjs)
4
+ [![License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
5
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
6
+
7
+ A TypeScript knowledge-graph library for AI agents and applications that need
8
+ structured long-term memory. Entities, relations, and observations with
9
+ multiple storage backends (JSONL, SQLite, PostgreSQL), advanced search (BM25, TF-IDF,
10
+ fuzzy, semantic, hybrid, temporal, LLM-planned), graph algorithms, bitemporal
11
+ versioning, RBAC, and a complete Agent Memory System (session lifecycle,
12
+ working / episodic / semantic / procedural memory, decay, salience, consolidation,
13
+ causal reasoning, world-model orchestration).
14
+
15
+ > Powers [@danielsimonjr/memory-mcp](https://www.npmjs.com/package/@danielsimonjr/memory-mcp),
16
+ > a Model Context Protocol server for Claude and other MCP clients. The
17
+ > library and the MCP server share the same core; this package is published
18
+ > independently so non-MCP applications can use it directly.
19
+
20
+ For a runnable CLI: `npx -p @danielsimonjr/memoryjs memory --help`.
21
+
22
+ ## Table of Contents
23
+
24
+ - [Features](#features)
25
+ - [Installation](#installation)
26
+ - [Quick Start](#quick-start)
27
+ - [Core Concepts](#core-concepts)
28
+ - [Storage Options](#storage-options)
29
+ - [Search Capabilities](#search-capabilities)
30
+ - [Graph Algorithms](#graph-algorithms)
31
+ - [Agent Memory System](#agent-memory-system)
32
+ - [API Reference](#api-reference)
33
+ - [Configuration](#configuration)
34
+ - [Development](#development)
35
+ - [Documentation](#documentation)
36
+ - [License](#license)
37
+
38
+ ## Features
39
+
40
+ ### Knowledge graph
41
+
42
+ | Capability | Entry point |
43
+ |---|---|
44
+ | Entity / relation / observation CRUD | `ctx.entityManager`, `ctx.relationManager`, `ctx.observationManager` |
45
+ | Optimistic concurrency control on updates | `entityManager.updateEntity(name, updates, { expectedVersion })` |
46
+ | Bitemporal versioning (entities + observations) | `invalidateEntity()` / `entityAsOf()` / `entityTimeline()` |
47
+ | Temporal relations (validity windows) | `relationManager.invalidateRelation()` / `queryAsOf()` / `timeline()` |
48
+ | Memory versioning with contradiction-driven supersession | `Entity.version` / `parentEntityName` / `rootEntityName` / `supersededBy` |
49
+ | Project scoping | `Entity.projectId` + `MEMORY_DEFAULT_PROJECT_ID` |
50
+ | Two-tier deletion (exact match semantic fallback) | `ctx.semanticForget` |
51
+ | Hierarchical nesting + traversal | `ctx.hierarchyManager` (ancestors / descendants / subtrees) |
52
+ | Stable named references that survive entity renames | `ctx.refIndex.register()` / `resolve()` |
53
+ | Multi-format import / export | `ctx.ioManager.exportGraph(format)` JSON, CSV, GraphML, GEXF, DOT, Markdown, Mermaid |
54
+ | W3C Linked Data export | `ctx.ioManager.exportGraph('turtle' \| 'rdf-xml' \| 'json-ld')` |
55
+ | Conversation ingestion (format-agnostic) | `ctx.ioManager.ingest(input, options)` |
56
+
57
+ ### Search & retrieval
58
+
59
+ | Capability | Entry point |
60
+ |---|---|
61
+ | Auto-selecting search with method explanation | `ctx.searchManager.autoSearch(query)` |
62
+ | TF-IDF + BM25 ranked search (incremental indexing) | `ctx.rankedSearch`, `BM25Search` |
63
+ | Boolean (AND / OR / NOT) with AST parser | `ctx.searchManager.booleanSearch()` |
64
+ | Fuzzy matching (Levenshtein, N-gram pre-filtered) | `ctx.searchManager.fuzzySearch()` |
65
+ | Semantic search with pluggable embedding provider | `ctx.semanticSearch` (set `MEMORY_EMBEDDING_PROVIDER`) |
66
+ | Hybrid (semantic + lexical + symbolic) | `new HybridSearchManager(ctx.storage, …).search(query)` |
67
+ | Temporal range queries with natural-language parsing | `ctx.searchManager.searchByTime("last hour")` |
68
+ | LLM-planned natural-language queries | `ctx.queryNaturalLanguage(query, llmProvider?)` |
69
+ | Query diagnostics (`explainPlan`, index health) | `ctx.diagnostics` |
70
+
71
+ ### Graph algorithms
72
+
73
+ | Capability | Entry point |
74
+ |---|---|
75
+ | Shortest path + all paths | `ctx.graphTraversal.findShortestPath()` / `findAllPaths()` |
76
+ | Centrality — degree, betweenness, PageRank, HITS | `ctx.graphTraversal.calculatePageRank()` / `calculateHITS()` |
77
+ | Community detection (Louvain), clique enumeration | `ctx.graphTraversal.findCommunities()` / `findCliques()` |
78
+ | Connected components | `ctx.graphTraversal.findConnectedComponents()` |
79
+
80
+ ### Agent Memory System
81
+
82
+ | Capability | Entry point |
83
+ |---|---|
84
+ | Sessions, working memory, episodic memory | `ctx.agentMemory()` `startSession` / `addWorkingMemory` / `retrieveForContext` |
85
+ | Turn-aware conversation memory with 4-tier dedup (exact / prefix / Jaccard / semantic) | `ctx.memoryEngine.addTurn()` / `getSessionTurns()` |
86
+ | Decay, salience, freshness | `DecayEngine`, `SalienceEngine`, `ctx.freshnessManager` |
87
+ | Role profiles `researcher` / `planner` / `executor` / `reviewer` / `coordinator` | `MEMORY_AGENT_ROLE` or `RoleProfileManager.apply(role)` |
88
+ | Memory consolidation, summarization, pattern detection | `ConsolidationPipeline`, `ConsolidationScheduler` |
89
+ | Collaborative synthesis with conflict resolution | `CollaborativeSynthesis.synthesize()` / `resolveConflicts()` |
90
+ | Failure-driven distillation, cognitive load analysis | `FailureDistillation`, `CognitiveLoadAnalyzer` |
91
+ | Procedural memory (executable procedures with feedback refinement) | `ctx.procedureManager.addProcedure()` / `matchProcedure()` / `refineProcedure()` |
92
+ | Active retrieval (iterative query rewriting) | `ctx.activeRetrieval.adaptiveRetrieve()` |
93
+ | Causal reasoning causes / effects / counterfactuals / cycle detection | `ctx.causalReasoner.findCauses()` / `findEffects()` / `counterfactual()` |
94
+ | World-state orchestrator | `ctx.worldModelManager.getCurrentState()` / `predictOutcome()` |
95
+ | Per-agent persistent journal | `AgentMemoryManager.writeDiary()` / `readDiary()` |
96
+ | Prospective memory (intentions-to-act) | `ctx.prospectiveMemory.schedule()` / `fire()` / `cancel()` |
97
+ | Failure memory (pre-task `applicability_hint` lookup) | `ctx.failureManager.record()` / `lookupForTask()` |
98
+ | Plan memory (hierarchical goal trees) | `ctx.plan.createPlan()` / `pushSubGoal()` / `transitionNode()` |
99
+ | Reflection memory (additive insights with content-hash dedup) | `ctx.reflectionManager.create()` / `getRelevantForSession()` |
100
+ | Heuristic memory (condition action guidelines) | `ctx.heuristicManager.add()` / `match()` / `reinforce()` |
101
+ | Decision rationale (ADR-style records) | `ctx.decisionManager.propose()` / `accept()` / `supersede()` |
102
+ | Project context (facts / conventions / commands / glossary) | `ctx.projectContextManager.upsert()` / `forContext()` |
103
+ | Tool affordance (outcome-aware tool suggestions) | `ctx.toolAffordanceManager.recordOutcome()` / `suggestTool()` |
104
+ | Trust hierarchy `ground-truth` / `verified` / `inferred` / `unverified` | `MemorySource.trustLevel` + `inferTrustLevel()` |
105
+
106
+ ### Storage & performance
107
+
108
+ | Capability | Entry point |
109
+ |---|---|
110
+ | JSONL or SQLite backend (FTS5, BM25, WAL mode) | `MEMORY_STORAGE_TYPE=jsonl\|sqlite` |
111
+ | Pluggable Memory Engine backend | `MEMORY_BACKEND=sqlite\|in-memory` |
112
+ | Memory-mapped file loading for large stores | `MEMORY_USE_MMAP=true`, `MEMORY_MMAP_THRESHOLD_BYTES` |
113
+ | Segment-sharded JSONL (FNV-routed N-way shards) | `MEMORY_STORAGE_SEGMENT_COUNT=1..1024` |
114
+ | Columnar observation storage | `JsonlColumnStore` (env-gated) |
115
+ | Tiered index — LRU hot / disk warm / Brotli cold | `LRUHotTier` `DiskWarmTier` `BrotliColdTier` via `TieredIndex` |
116
+ | In-memory entity-cache compression | `ctx.compressedEntityCache`, `CompressedMap` |
117
+ | Backup lifecycle (create / list / restore / delete) with symlink-attack guards | `ctx.ioManager` (delegates to `BackupManager`) |
118
+ | Streaming export with Brotli compression | `ctx.streamingExporter` |
119
+ | Entity archival to compressed storage | `ctx.archiveManager` |
120
+ | Duplicate detection + entity merging | `ctx.compressionManager` |
121
+
122
+ ### Governance, security, multi-agent
123
+
124
+ | Capability | Entry point |
125
+ |---|---|
126
+ | Policy enforcement + transactional rollback | `ctx.governanceManager.withTransaction()` / `GovernancePolicy` |
127
+ | Immutable JSONL audit trail | `ctx.auditLog` |
128
+ | Strict-mode attribution enforcer | `CollaborationAuditEnforcer` (requires `agentId` on every mutation) |
129
+ | RBAC role / permission / matrix / middleware | `ctx.rbacMiddleware.checkPermission()` / `ctx.roleAssignmentStore` |
130
+ | ABAC + row-level security + API-key scoping | `src/security/abac.ts`, `rls.ts`, `apiKeys.ts` |
131
+ | PII redactor (email / SSN / CC / phone / IP) | `new PiiRedactor().redactGraph()` / `redactWithStats()` |
132
+ | Visibility hierarchies (5-level: `private` / `team` / `org` / `shared` / `public`) | `VisibilityResolver.canAccess()` |
133
+ | Time-window + role-gated visibility | `AgentEntity.visibleFrom` / `visibleUntil` / `allowedRoles[]` |
134
+ | Path-traversal protection | `validateFilePath(path, baseDir?, confineToBase=true)` |
135
+
136
+ ### Tooling
137
+
138
+ | Capability | Entry point |
139
+ |---|---|
140
+ | Command-line interface | `npx -p @danielsimonjr/memoryjs memory --help` |
141
+ | End-to-end smoke test against a fresh temp graph (~30 ops) | `memory smoke --keep --verbose` |
142
+ | Diagnostic snapshot + graph health checks | `memory diag` / `memory health` |
143
+ | Orphan + missing-parent + cycle detection with optional repair | `memory check [--apply]` |
144
+ | Rebuild ranked + spell indexes | `memory reindex [--ranked\|--spell]` |
145
+ | Inspect a single entity verbosely | `memory show <name>` |
146
+ | Hierarchy tree (JSON or `--ascii`) | `memory tree [root]` |
147
+ | Search-cache stats / clear | `memory cache stats \| clear` |
148
+ | Interactive REPL | `memory interactive` |
149
+
150
+
151
+ ## Installation
152
+
153
+ ```bash
154
+ npm install @danielsimonjr/memoryjs
155
+ ```
156
+
157
+ ### Requirements
158
+
159
+ - Node.js >= 18.0.0
160
+ - TypeScript >= 5.0 (for development)
161
+
162
+ ## Quick Start
163
+
164
+ ### 1. Initialize storage
165
+
166
+ ```typescript
167
+ import { ManagerContext } from '@danielsimonjr/memoryjs';
168
+
169
+ // JSONL storage (default, human-readable)
170
+ const ctx = new ManagerContext('./memory.jsonl');
171
+
172
+ // Or SQLite (set MEMORY_STORAGE_TYPE=sqlite in the environment)
173
+ const sqliteCtx = new ManagerContext('./memory.db');
174
+ ```
175
+
176
+ ### 2. Create entities
177
+
178
+ ```typescript
179
+ await ctx.entityManager.createEntities([
180
+ {
181
+ name: 'TypeScript',
182
+ entityType: 'language',
183
+ observations: ['A typed superset of JavaScript'],
184
+ tags: ['programming', 'frontend'],
185
+ importance: 8,
186
+ },
187
+ {
188
+ name: 'Node.js',
189
+ entityType: 'runtime',
190
+ observations: ['JavaScript runtime built on V8'],
191
+ tags: ['backend', 'server'],
192
+ },
193
+ ]);
194
+ ```
195
+
196
+ ### 3. Create relations
197
+
198
+ ```typescript
199
+ await ctx.relationManager.createRelations([
200
+ { from: 'TypeScript', to: 'Node.js', relationType: 'runs_on' },
201
+ ]);
202
+ ```
203
+
204
+ ### 4. Search
205
+
206
+ ```typescript
207
+ // Auto-select the best method
208
+ const auto = await ctx.searchManager.autoSearch('JavaScript');
209
+
210
+ // Substring + tag search
211
+ const nodes = await ctx.searchManager.searchNodes('JavaScript');
212
+
213
+ // Boolean (AND / OR / NOT) with an AST parser
214
+ const both = await ctx.searchManager.booleanSearch('TypeScript AND runtime');
215
+
216
+ // Fuzzy (typo-tolerant; N-gram pre-filtered)
217
+ const fuzzy = await ctx.searchManager.fuzzySearch('Typscript', { threshold: 0.7 });
218
+
219
+ // Ranked TF-IDF / BM25
220
+ const ranked = await ctx.rankedSearch.searchNodesRanked('runtime environment',
221
+ undefined, undefined, undefined, 10);
222
+
223
+ // Active retrieval — iterative query rewriting until coverage threshold
224
+ const adaptive = await ctx.activeRetrieval.adaptiveRetrieve({ query: 'memory leak' });
225
+ console.log(adaptive.bestResults, adaptive.bestCoverage, adaptive.rounds);
226
+ ```
227
+
228
+ ### 5. Multi-agent collaboration
229
+
230
+ ```typescript
231
+ // Optimistic concurrency control — fail loudly on stale writes
232
+ try {
233
+ await ctx.entityManager.updateEntity('Alice',
234
+ { importance: 9 },
235
+ { expectedVersion: 3 });
236
+ } catch (e) {
237
+ if (e instanceof Error && e.name === 'VersionConflictError') {
238
+ // Refetch + retry
239
+ }
240
+ }
241
+
242
+ // Synthesize a view across agents + resolve conflicts
243
+ const agent = ctx.agentMemory();
244
+ const synth = await agent.collaborativeSynthesis.synthesize('Alice');
245
+ const winners = agent.collaborativeSynthesis.resolveConflicts(synth, {
246
+ strategy: 'highest_confidence',
247
+ });
248
+
249
+ // Enforce attribution on every mutation
250
+ import { CollaborationAuditEnforcer, AuditLog } from '@danielsimonjr/memoryjs';
251
+ const enforcer = new CollaborationAuditEnforcer(
252
+ ctx.entityManager,
253
+ new AuditLog('./audit.jsonl'),
254
+ );
255
+ await enforcer.createEntities(
256
+ [{ name: 'X', entityType: 't', observations: ['fact'] }],
257
+ 'agent-alice', // throws AttributionRequiredError if agentId is missing
258
+ );
259
+ ```
260
+
261
+ ### 6. Bitemporal versioning
262
+
263
+ ```typescript
264
+ // Mark an entity as no longer valid at a specific time
265
+ await ctx.entityManager.invalidateEntity('OldFact', '2025-12-31T00:00:00Z');
266
+
267
+ // Time-travel query
268
+ const past = await ctx.entityManager.entityAsOf('Alice', '2024-06-15T00:00:00Z');
269
+
270
+ // Per-observation validity windows
271
+ await ctx.observationManager.invalidateObservation(
272
+ 'Alice', 'works at Acme', '2024-12-31T00:00:00Z',
273
+ );
274
+ const obsAtTime = await ctx.observationManager.observationsAsOf(
275
+ 'Alice', '2024-06-15T00:00:00Z',
276
+ );
277
+ ```
278
+
279
+ ### 7. Causal reasoning and world model
280
+
281
+ ```typescript
282
+ // Forward inference — "what does X cause?"
283
+ const effects = await ctx.causalReasoner.findEffects('rain', ['flooding', 'erosion']);
284
+
285
+ // Counterfactual — "what if we remove this edge?"
286
+ const surviving = await ctx.causalReasoner.counterfactual({
287
+ seed: 'rain', removeFrom: 'rain', removeTo: 'flooding', predict: 'flooding',
288
+ });
289
+
290
+ // World-state snapshot + diff
291
+ const before = await ctx.worldModelManager.getCurrentState();
292
+ // ... mutations ...
293
+ const after = await ctx.worldModelManager.getCurrentState();
294
+ const change = ctx.worldModelManager.detectStateChange(before, after);
295
+ ```
296
+
297
+ ### 8. RBAC and PII redaction
298
+
299
+ ```typescript
300
+ // Grant a role
301
+ await ctx.roleAssignmentStore.assign({
302
+ agentId: 'alice', role: 'writer', resourceType: 'entity',
303
+ });
304
+ ctx.rbacMiddleware.checkPermission('alice', 'write', 'entity'); // true
305
+
306
+ // Redact PII from exports / logs
307
+ import { PiiRedactor } from '@danielsimonjr/memoryjs';
308
+ const redactor = new PiiRedactor();
309
+ const cleanGraph = redactor.redactGraph(graph);
310
+ const { text, stats } = redactor.redactWithStats(observation);
311
+ ```
312
+
313
+ ## Core Concepts
314
+
315
+ ### Entity
316
+
317
+ The primary node in the knowledge graph. Required fields are `name`, `entityType`,
318
+ and `observations`; the rest are optional and unlock specific features:
319
+
320
+ ```typescript
321
+ interface Entity {
322
+ name: string; // Unique identifier
323
+ entityType: string; // Classification (person, project, concept, …)
324
+ observations: string[]; // Atomic facts about the entity
325
+ parentId?: string; // Parent entity for hierarchical nesting
326
+ tags?: string[]; // Lowercase tags for categorisation
327
+ importance?: number; // 0–10 scale for prioritisation
328
+ createdAt?: string; // ISO 8601
329
+ lastModified?: string; // ISO 8601
330
+
331
+ // Freshness
332
+ ttl?: number; // Seconds until stale
333
+ confidence?: number; // [0, 1] belief strength
334
+
335
+ // Project scoping + supersession
336
+ projectId?: string; // Multi-project isolation
337
+ version?: number; // Drives optimistic concurrency on updates
338
+ parentEntityName?: string;
339
+ rootEntityName?: string;
340
+ isLatest?: boolean;
341
+ supersededBy?: string;
342
+
343
+ // Memory-engine deduplication
344
+ contentHash?: string; // SHA-256 for O(1) exact-equality dedup
345
+
346
+ // Bitemporal validity (orthogonal to supersession)
347
+ validFrom?: string;
348
+ validUntil?: string;
349
+ observationMeta?: Array<{
350
+ content: string;
351
+ validFrom?: string;
352
+ validUntil?: string;
353
+ recordedAt?: string;
354
+ }>;
355
+ }
356
+ ```
357
+
358
+ ### Relation
359
+
360
+ A directed edge between two entities:
361
+
362
+ ```typescript
363
+ interface Relation {
364
+ from: string; // Source entity name
365
+ to: string; // Target entity name
366
+ relationType: string; // Relationship type (active voice — "depends_on", "wrote")
367
+ }
368
+ ```
369
+
370
+ ### Observation
371
+
372
+ A discrete atomic fact about an entity. Use `addObservations()` to append without
373
+ overwriting; combined with the bitemporal axis and per-observation `validFrom` /
374
+ `validUntil` you can preserve historical state instead of mutating in place.
375
+
376
+ ### ManagerContext
377
+
378
+ The central facade. Construct it with a storage-path string; every manager is
379
+ exposed as a property with lazy initialisation:
380
+
381
+ ```typescript
382
+ const ctx = new ManagerContext('./memory.jsonl');
383
+
384
+ // Core
385
+ ctx.entityManager // Entity CRUD + hierarchy + temporal validity + OCC
386
+ ctx.relationManager // Relation management + temporal invalidation
387
+ ctx.observationManager // Observation CRUD + bitemporal axis
388
+ ctx.hierarchyManager // Tree operations (parent / children / ancestors)
389
+ ctx.searchManager // All search operations including `searchByTime`
390
+ ctx.rankedSearch // TF-IDF / BM25 ranked search
391
+ ctx.graphTraversal // BFS / DFS / shortest path / centrality / communities
392
+ ctx.tagManager // Tag aliases + bulk operations
393
+ ctx.refIndex // Stable name entity O(1) lookup
394
+
395
+ // Storage + I/O
396
+ ctx.ioManager // Import / export (RDF/Turtle/JSON-LD) / backup / ingest
397
+ ctx.archiveManager // Entity archival
398
+ ctx.compressionManager // Duplicate detection, entity merging
399
+ ctx.analyticsManager // Graph statistics + validation
400
+ ctx.semanticForget // Two-tier deletion with audit
401
+ ctx.governanceManager // Transactions + policy enforcement
402
+ ctx.freshnessManager // TTL / confidence freshness reports
403
+
404
+ // Search extensions
405
+ ctx.semanticSearch // Vector similarity (lazy; needs embedding provider)
406
+ ctx.temporalSearch // Natural-language time-range search
407
+ ctx.activeRetrieval // Iterative query rewriting (no LLM required)
408
+ ctx.queryNaturalLanguage // Convenience wrapper for NL StructuredQuery
409
+
410
+ // Memory engine + agent system
411
+ ctx.memoryEngine // Turn-aware conversation memory (4-tier dedup)
412
+ ctx.memoryBackend // Pluggable IMemoryBackend (in-memory / sqlite)
413
+ ctx.agentMemory() // Agent Memory System facade
414
+
415
+ // Memory intelligence
416
+ ctx.memoryValidator // Consistency / contradictions / temporal-order checks
417
+ ctx.trajectoryCompressor // Distill / abstract / merge redundant trajectories
418
+
419
+ // Specialised memory managers
420
+ ctx.procedureManager // Executable procedure memory + feedback refinement
421
+ ctx.causalReasoner // findCauses / findEffects / counterfactual
422
+ ctx.worldModelManager // State-snapshot orchestrator + diff
423
+ ctx.heuristicManager // Condition action guidelines
424
+ ctx.decisionManager // ADR-style decision records
425
+ ctx.projectContextManager
426
+ ctx.toolAffordanceManager
427
+ ctx.spellChecker // Vocabulary-driven spell suggestions
428
+ ctx.exclusionManager // `do_not_remember` content-pattern rules
429
+ ctx.observationDedupManager
430
+
431
+ // Access control + audit
432
+ ctx.roleAssignmentStore
433
+ ctx.rbacMiddleware
434
+ ```
435
+
436
+ ## Storage Options
437
+
438
+ ### Comparison
439
+
440
+ | Feature | JSONL (Default) | SQLite (better-sqlite3) |
441
+ |---------|-----------------|-------------------------|
442
+ | Format | Human-readable text | Native binary database |
443
+ | Transactions | Basic | Full ACID with WAL mode |
444
+ | Full-Text Search | Basic | FTS5 with BM25 ranking |
445
+ | Performance | Good | 3-10x faster |
446
+ | Concurrency | Single-threaded | Thread-safe with async-mutex |
447
+ | Best For | Small graphs, debugging | Large graphs (10k+ entities) |
448
+
449
+ ### JSONL Storage
450
+
451
+ ```typescript
452
+ const ctx = new ManagerContext('./memory.jsonl');
453
+ ```
454
+
455
+ Features:
456
+ - Human-readable line-delimited JSON
457
+ - In-memory caching with write-through invalidation
458
+ - Atomic writes via temp file + rename
459
+ - Backward compatibility for legacy formats
460
+
461
+ ### SQLite Storage
462
+
463
+ ```typescript
464
+ // Set MEMORY_STORAGE_TYPE=sqlite environment variable
465
+ const ctx = new ManagerContext('./memory.db');
466
+ ```
467
+
468
+ Features:
469
+ - FTS5 full-text search with BM25 ranking
470
+ - WAL mode for better concurrency
471
+ - Referential integrity with ON DELETE CASCADE
472
+ - ACID transactions
473
+
474
+ ### Storage Files
475
+
476
+ When using JSONL, related files are automatically created:
477
+
478
+ ```
479
+ /your/data/directory/
480
+ ├── memory.jsonl # Main knowledge graph
481
+ ├── memory-saved-searches.jsonl # Saved search queries
482
+ ├── memory-tag-aliases.jsonl # Tag synonym mappings
483
+ └── .backups/ # Timestamped backups
484
+ ```
485
+
486
+ ## Search Capabilities
487
+
488
+ ### Available methods
489
+
490
+ | Method | Description | Use case |
491
+ |---|---|---|
492
+ | `searchManager.autoSearch(query)` | Auto-selects the best method + explains why | Default entry point |
493
+ | `searchManager.searchNodes(query)` | Substring + tag matching | Simple queries |
494
+ | `searchManager.booleanSearch(query)` | AND / OR / NOT with AST parser | Complex filters |
495
+ | `searchManager.fuzzySearch(query)` | Levenshtein + N-gram pre-filter | Typo tolerance |
496
+ | `searchManager.searchByTime(query)` | Natural-language time ranges (`chrono-node`) | "last hour", "since 2024-01-01" |
497
+ | `rankedSearch.searchNodesRanked(query, ...)` | TF-IDF / BM25 ranking | Most-relevant ordering |
498
+ | `semanticSearch.search(query)` | Vector similarity (requires embedding provider) | Semantic queries |
499
+ | `new HybridSearchManager(...).search(query)` | Semantic + lexical + symbolic | Multi-signal ranking |
500
+ | `activeRetrieval.adaptiveRetrieve({ query })` | Iterative query rewriting + coverage check | Adaptive refinement |
501
+ | `queryNaturalLanguage(query, llmProvider?)` | LLM-planned NL decomposition (fallback: keyword) | Free-text queries |
502
+ | `causalReasoner.findEffects(seed, candidates)` | Subgraph traversal over `causes`/`enables`/`prevents` | Causal inference |
503
+
504
+ ### Auto-search
505
+
506
+ ```typescript
507
+ const auto = await ctx.searchManager.autoSearch('TypeScript runtime');
508
+ console.log(auto.selectedMethod, auto.selectionReason);
509
+ console.log(auto.results);
510
+ ```
511
+
512
+ ### Boolean search
513
+
514
+ ```typescript
515
+ // AND both terms must match
516
+ await ctx.searchManager.booleanSearch('TypeScript AND runtime');
517
+
518
+ // OR either term matches
519
+ await ctx.searchManager.booleanSearch('frontend OR backend');
520
+
521
+ // NOT exclude term
522
+ await ctx.searchManager.booleanSearch('JavaScript NOT browser');
523
+
524
+ // Grouping
525
+ await ctx.searchManager.booleanSearch('(TypeScript OR JavaScript) AND server');
526
+ ```
527
+
528
+ ### Fuzzy search
529
+
530
+ ```typescript
531
+ // Typo-tolerant; threshold 0–1 (higher = stricter)
532
+ await ctx.searchManager.fuzzySearch('Typscript', { threshold: 0.7 });
533
+ ```
534
+
535
+ ### Hybrid search
536
+
537
+ `HybridSearchManager` combines three signal layers. Instantiate it directly —
538
+ it is exported from the package but not wired onto `ManagerContext` because the
539
+ weighting + filter configuration is application-specific.
540
+
541
+ ```typescript
542
+ import { HybridSearchManager } from '@danielsimonjr/memoryjs';
543
+
544
+ const hybrid = new HybridSearchManager(ctx.storage, ctx.rankedSearch);
545
+ const results = await hybrid.search('programming concepts', {
546
+ weights: {
547
+ semantic: 0.5, // Vector similarity (requires embeddings)
548
+ lexical: 0.3, // TF-IDF text matching
549
+ symbolic: 0.2, // Metadata (tags, importance, type)
550
+ },
551
+ filters: {
552
+ entityTypes: ['concept'],
553
+ minImportance: 5,
554
+ tags: ['programming'],
555
+ },
556
+ });
557
+ ```
558
+
559
+ ## Graph Algorithms
560
+
561
+ ### Path finding
562
+
563
+ ```typescript
564
+ // Shortest path between entities (BFS)
565
+ const result = await ctx.graphTraversal.findShortestPath('A', 'Z');
566
+ console.log(result.path); // ['A', 'B', 'C', 'Z']
567
+ console.log(result.distance); // 3
568
+
569
+ // All paths with a depth bound
570
+ const all = await ctx.graphTraversal.findAllPaths('A', 'Z', { maxDepth: 5 });
571
+ // [['A', 'B', 'Z'], ['A', 'C', 'D', 'Z'], …]
572
+ ```
573
+
574
+ ### Centrality
575
+
576
+ Each centrality algorithm has its own method (no unified `getCentrality()` — the
577
+ algorithms have different parameters and return shapes):
578
+
579
+ ```typescript
580
+ const degree = await ctx.graphTraversal.calculateDegreeCentrality();
581
+ const between = await ctx.graphTraversal.calculateBetweennessCentrality();
582
+ const pagerank = await ctx.graphTraversal.calculatePageRank();
583
+ const hits = await ctx.graphTraversal.calculateHITS();
584
+ // Each returns a Map<entityName, score>
585
+ ```
586
+
587
+ ### Connected components, communities, cliques
588
+
589
+ ```typescript
590
+ const components = await ctx.graphTraversal.findConnectedComponents();
591
+ const communities = await ctx.graphTraversal.findCommunities(); // Louvain
592
+ const cliques = await ctx.graphTraversal.findCliques(/* minSize */ 3);
593
+ ```
594
+
595
+ ### Traversal
596
+
597
+ ```typescript
598
+ // Returns a TraversalResult { visited, edges, depthMap }
599
+ const bfs = ctx.graphTraversal.bfs('startNode', { maxDepth: 3 });
600
+ const dfs = ctx.graphTraversal.dfs('startNode');
601
+ ```
602
+
603
+ ## Agent Memory System
604
+
605
+ A memory system for AI agents with session lifecycle, working / episodic /
606
+ semantic / procedural memory, decay, salience, multi-agent visibility, and
607
+ specialised memory types (prospective, failure, plan, reflection, heuristic,
608
+ decision rationale, project context, tool affordance).
609
+
610
+ ### Key components
611
+
612
+ | Component | Purpose |
613
+ |---|---|
614
+ | `AgentMemoryManager` | Unified facade for the system |
615
+ | `SessionManager` | Session lifecycle (start / end / restore / checkpoint) |
616
+ | `WorkingMemoryManager` | Short-term, session-scoped memories with promotion |
617
+ | `EpisodicMemoryManager` | Timeline-based event memories |
618
+ | `DecayEngine` | Time-based importance decay |
619
+ | `SalienceEngine` | Context-aware memory scoring |
620
+ | `MultiAgentMemoryManager` | Cross-agent memory with visibility controls |
621
+ | `ConflictResolver` | Resolution strategies for concurrent updates |
622
+
623
+ ### Quick start
624
+
625
+ ```typescript
626
+ import { ManagerContext } from '@danielsimonjr/memoryjs';
627
+
628
+ const ctx = new ManagerContext('./memory.jsonl');
629
+ const agent = ctx.agentMemory();
630
+
631
+ // Start a session
632
+ const session = await agent.startSession({ agentId: 'my-agent' });
633
+
634
+ // Add working memory
635
+ await agent.addWorkingMemory({
636
+ sessionId: session.name,
637
+ content: 'User prefers dark mode',
638
+ importance: 7,
639
+ });
640
+
641
+ // Episodic event
642
+ await agent.createEpisode('Completed onboarding flow', {
643
+ sessionId: session.name,
644
+ importance: 8,
645
+ });
646
+
647
+ // Retrieve context for an LLM prompt (token-budgeted)
648
+ const context = await agent.retrieveForContext({
649
+ maxTokens: 2000,
650
+ includeEpisodic: true,
651
+ });
652
+
653
+ // End session
654
+ await agent.endSession(session.name);
655
+ ```
656
+
657
+ ### Memory types
658
+
659
+ ```typescript
660
+ type MemoryType =
661
+ | 'working' // Short-term, session-scoped; may be promoted
662
+ | 'episodic' // Timeline-based event memories
663
+ | 'semantic' // Long-term factual knowledge
664
+ | 'procedural' // Executable procedures with feedback refinement
665
+ | 'prospective' // Intentions-to-act at a future time / event / condition
666
+ | 'failure' // Pre-task failure lookup keyed on applicability_hint
667
+ | 'plan' // Hierarchical goal trees with sub-tasks + acceptance criteria
668
+ | 'reflection' // Additive derived insights with content-hash dedup
669
+ | 'heuristic'; // Condition → action guidelines
670
+ ```
671
+
672
+ Each specialised type has a dedicated manager on `ManagerContext` —
673
+ `ctx.prospectiveMemory`, `ctx.failureManager`, `ctx.plan`, `ctx.reflectionManager`,
674
+ `ctx.heuristicManager`, `ctx.decisionManager`, `ctx.projectContextManager`,
675
+ `ctx.toolAffordanceManager`.
676
+
677
+ **Trust hierarchy mixin**: every `MemorySource` may carry an optional
678
+ categorical `trustLevel`: `'ground-truth' | 'verified' | 'inferred' | 'unverified'`.
679
+ Used by the `'trust_level'` `ConflictStrategy` (with recency tiebreak) and
680
+ backfilled from `method` + `reliability` via `inferTrustLevel(source)`.
681
+
682
+ ### Decay
683
+
684
+ Memories naturally decay over time unless reinforced:
685
+
686
+ ```typescript
687
+ const agent = ctx.agentMemory({
688
+ decay: {
689
+ halfLifeHours: 168, // One-week half-life
690
+ minImportance: 0.1, // Never fully forget
691
+ },
692
+ enableAutoDecay: true,
693
+ });
694
+
695
+ // Reinforce a memory
696
+ await agent.confirmMemory('memory_name', 0.1); // Boost confidence
697
+ await agent.promoteMemory('memory_name', 'episodic'); // Promote to long-term
698
+ ```
699
+
700
+ ### Multi-agent
701
+
702
+ ```typescript
703
+ // Register an agent
704
+ agent.registerAgent('agent_1', {
705
+ name: 'Research Agent',
706
+ type: 'llm',
707
+ trustLevel: 0.8,
708
+ capabilities: ['read', 'write'],
709
+ });
710
+
711
+ // Create with visibility (private / team / org / shared / public)
712
+ await agent.addWorkingMemory({
713
+ sessionId: session.name,
714
+ content: 'Shared insight',
715
+ visibility: 'shared',
716
+ ownerAgentId: 'agent_1',
717
+ });
718
+
719
+ // Cross-agent search
720
+ const results = await agent.searchCrossAgent('agent_2', 'query');
721
+ ```
722
+
723
+ ## API Reference
724
+
725
+ Method tables below cover the most-used surfaces. For the full surface use
726
+ your IDE's go-to-definition or read `dist/index.d.ts`.
727
+
728
+ ### EntityManager
729
+
730
+ | Method | Description |
731
+ |---|---|
732
+ | `createEntities(entities)` | Create multiple entities in one batch |
733
+ | `deleteEntities(names)` | Delete entities by name |
734
+ | `getEntity(name, options?)` | Get one entity (with optional access tracking) |
735
+ | `updateEntity(name, updates, { expectedVersion? })` | Partial update; opt-in optimistic concurrency |
736
+ | `addTags(name, tags)` / `removeTags(name, tags)` | Tag management |
737
+ | `setImportance(name, score)` | Set importance (0–10) |
738
+ | `getVersionChain(name)` / `getLatestVersion(name)` | Supersession chains |
739
+ | `invalidateEntity(name, ended?)` | Set `validUntil` (bitemporal) |
740
+ | `entityAsOf(name, asOf)` | Time-travel query |
741
+ | `entityTimeline(name)` | Versions sorted by `validFrom` |
742
+
743
+ ### RelationManager
744
+
745
+ | Method | Description |
746
+ |---|---|
747
+ | `createRelations(relations)` | Create multiple relations |
748
+ | `getRelations(entityName)` | Incoming + outgoing relations |
749
+ | `deleteRelations(relations)` | Delete specific relations |
750
+ | `invalidateRelation(from, type, to, ended?)` | Set `validUntil` on a relation |
751
+ | `queryAsOf(entity, asOf, options?)` | Relations valid at time T |
752
+ | `timeline(entity, options?)` | Chronological history |
753
+
754
+ ### ObservationManager
755
+
756
+ | Method | Description |
757
+ |---|---|
758
+ | `addObservations(adds, dedupOptions?)` | Add observations (optional dedup) |
759
+ | `deleteObservations(deletions)` | Remove specific observations |
760
+ | `getObservationsFor(entityName)` | Read observations (column-store-aware) |
761
+ | `invalidateObservation(entity, content, ended?)` | Set per-observation `validUntil` |
762
+ | `observationsAsOf(entity, asOf)` | Observations valid at time T |
763
+
764
+ ### SearchManager (`ctx.searchManager`)
765
+
766
+ | Method | Description |
767
+ |---|---|
768
+ | `searchNodes(query, options?)` | Substring + tag matching |
769
+ | `booleanSearch(query, options?)` | AND / OR / NOT with AST |
770
+ | `fuzzySearch(query, options?)` | Levenshtein + N-gram pre-filter |
771
+ | `searchByTime(query, options?)` | Natural-language time ranges |
772
+ | `autoSearch(query, limit?)` | Auto-select best method; returns `selectedMethod` + `selectionReason` |
773
+ | `openNodes(names)` | Bulk-fetch entities by name |
774
+
775
+ For ranked search use `ctx.rankedSearch.searchNodesRanked(query, tags?, min?, max?, limit?)`.
776
+ For hybrid search, instantiate `HybridSearchManager` directly.
777
+
778
+ ### IOManager (`ctx.ioManager`)
779
+
780
+ | Method | Description |
781
+ |---|---|
782
+ | `exportGraph(graph, format)` | Export to `json` / `csv` / `graphml` / `gexf` / `dot` / `markdown` / `mermaid` / `turtle` / `rdf-xml` / `json-ld` |
783
+ | `exportGraphWithCompression(graph, format, options?)` | Brotli-compressed export |
784
+ | `importGraph(format, data, options?)` | Import with merge strategies (`replace` / `skip` / `merge` / `fail`) |
785
+ | `ingest(input, options?)` | Conversation ingestion pipeline (format-agnostic) |
786
+ | `splitTranscript(content, options?)` | Split multi-session transcripts |
787
+ | `visualizeGraph(options?)` | Interactive HTML visualisation |
788
+ | `createBackup(options?)` / `restoreFromBackup(path)` / `deleteBackup(path)` / `cleanOldBackups(keepCount?)` | Backup lifecycle |
789
+
790
+ ### GraphTraversal (`ctx.graphTraversal`)
791
+
792
+ | Method | Description |
793
+ |---|---|
794
+ | `findShortestPath(from, to)` | BFS shortest path |
795
+ | `findAllPaths(from, to, options?)` | All paths with depth bound |
796
+ | `findConnectedComponents()` | Isolated subgraphs |
797
+ | `findCliques(minSize?)` | Maximal cliques |
798
+ | `findCommunities()` | Louvain community detection |
799
+ | `calculateDegreeCentrality()` / `calculateBetweennessCentrality()` / `calculatePageRank()` / `calculateHITS()` | Centrality (each returns `Map<entityName, score>`) |
800
+ | `bfs(start, options?)` / `dfs(start, options?)` | Returns `TraversalResult` |
801
+
802
+ ### CausalReasoner (`ctx.causalReasoner`)
803
+
804
+ | Method | Description |
805
+ |---|---|
806
+ | `findEffects(cause, candidates, maxDepth?)` | Forward inference; sorted by causal-strength product |
807
+ | `findCauses(effect, candidates, maxDepth?)` | Backward inference (symmetric inverse) |
808
+ | `counterfactual({ seed, removeFrom, removeTo, predict })` | Pure: doesn't mutate the graph |
809
+ | `detectCycles(seed, maxDepth?)` | Depth-bounded DFS over causal subgraph |
810
+
811
+ ### ProcedureManager (`ctx.procedureManager`)
812
+
813
+ | Method | Description |
814
+ |---|---|
815
+ | `addProcedure({ steps, ... })` | Persist a procedure; auto-generates id |
816
+ | `getProcedure(id)` / `getStep(id, order)` / `getNextStep(id, order)` | Access |
817
+ | `openSequencer(id)` | Stateful execution cursor with fallback support |
818
+ | `matchProcedure(context, candidates, threshold?)` | Token-overlap match |
819
+ | `refineProcedure(id, { succeeded, notes? })` | EWMA success-rate update |
820
+
821
+ ### WorldModelManager (`ctx.worldModelManager`)
822
+
823
+ | Method | Description |
824
+ |---|---|
825
+ | `getCurrentState()` | Snapshot from the live graph (capped at `maxSnapshotSize`) |
826
+ | `validateFact(observation, entityName)` | Delegates to `MemoryValidator` if wired |
827
+ | `predictOutcome(action, candidates)` | Delegates to `CausalReasoner.findEffects` |
828
+ | `detectStateChange(before, after)` | Pure snapshot diff |
829
+
830
+ ### ActiveRetrievalController (`ctx.activeRetrieval`)
831
+
832
+ | Method | Description |
833
+ |---|---|
834
+ | `shouldRetrieve(context)` | Cost heuristic; rejects empty / over-budget |
835
+ | `adaptiveRetrieve(context)` | Iterative rewrite + retrieve until coverage threshold |
836
+
837
+ ### CollaborativeSynthesis (`ctx.agentMemory().collaborativeSynthesis`)
838
+
839
+ | Method | Description |
840
+ |---|---|
841
+ | `synthesize(seedEntity, context?)` | BFS + salience scoring; surfaces multi-agent conflicts |
842
+ | `resolveConflicts(result, policy)` | Pick winners per `most_recent` / `highest_confidence` / `highest_score` / `trusted_agent` |
843
+
844
+ ### MemoryValidator (`ctx.memoryValidator`)
845
+
846
+ | Method | Description |
847
+ |---|---|
848
+ | `validateConsistency(newObs, existing)` | Composite duplicate / semantic / low-confidence check |
849
+ | `detectContradictions(entity)` | Delegates to `ContradictionDetector` |
850
+ | `repairWithResolver(entity, competing, resolver, contradiction?, options?)` | Apply `ConflictResolver` strategies |
851
+ | `validateTemporalOrder(observations)` | `[T=ISO]` ordering check |
852
+ | `calculateReliability(entity)` | Confidence × confirmation × age penalty |
853
+
854
+ ### RBAC (`ctx.rbacMiddleware`, `ctx.roleAssignmentStore`)
855
+
856
+ | Method | Description |
857
+ |---|---|
858
+ | `rbacMiddleware.checkPermission(agentId, action, resourceType, resourceName?, now?)` | Returns `true` / `false`; falls back to `defaultRole` (default `reader`) |
859
+ | `roleAssignmentStore.assign({ agentId, role, resourceType?, scope?, validFrom?, validUntil? })` | Grant a role |
860
+ | `roleAssignmentStore.revoke(agentId, role, resourceType?)` | Remove a grant |
861
+ | `roleAssignmentStore.listActive(agentId, now?)` | Active grants at a point in time |
862
+
863
+ ### PiiRedactor
864
+
865
+ | Method | Description |
866
+ |---|---|
867
+ | `redact(text)` | Apply patterns; returns redacted string |
868
+ | `redactWithStats(text)` | Returns `{ text, stats: { totalRedactedBytes, countsByPattern } }` |
869
+ | `redactGraph(graph)` | Apply to every observation in a graph-shaped object |
870
+
871
+ ### Specialised memory managers
872
+
873
+ | Manager | Path | Key methods |
874
+ |---|---|---|
875
+ | Prospective | `ctx.prospectiveMemory` | `schedule()` / `fire()` / `cancel()` / `expireDueIntentions()` / `getPending()` |
876
+ | Failure | `ctx.failureManager` | `record()` / `lookupForTask()` / `markResolved()` / `getAll()` |
877
+ | Plan | `ctx.plan` | `createPlan()` / `pushSubGoal()` / `transitionNode()` / `markPlanComplete()` / `getCurrentPath()` |
878
+ | Reflection | `ctx.reflectionManager` | `create()` / `list()` / `getRelevantForSession()` / `archive()` |
879
+ | Heuristic | `ctx.heuristicManager` | `add()` / `match()` / `reinforce()` / `recordContradiction()` / `detectConflicts()` |
880
+ | Decision | `ctx.decisionManager` | `propose()` / `accept()` / `reject()` / `supersede()` / `findByContext()` / `getChain()` |
881
+ | Project context | `ctx.projectContextManager` | `upsert()` / `appendFact()` / `appendCommand()` / `forContext()` |
882
+ | Tool affordance | `ctx.toolAffordanceManager` | `recordOutcome()` / `suggestTool()` / `rollingStats()` |
883
+ | Exclusion | `ctx.exclusionManager` | `add()` / `list()` / `remove()` / `check()` / `findMatchingMemories()` |
884
+ | Observation dedup | `ctx.observationDedupManager` | `findDuplicateObservations()` / `findJaccardDuplicates()` |
885
+ | Spell | `ctx.spellChecker` | `suggest()` / `rebuild()` / `vocabularySize()` |
886
+
887
+ ## Configuration
888
+
889
+ memoryjs is configured almost entirely through environment variables. The
890
+ table below lists the most-used; the full reference (decay / salience /
891
+ context-window / freshness / RBAC / mmap / segment / SQLite-pool / partial-index
892
+ knobs) lives in [CLAUDE.md](CLAUDE.md#environment-variables).
893
+
894
+ | Variable | Description | Default |
895
+ |---|---|---|
896
+ | `MEMORY_STORAGE_TYPE` | Storage backend: `jsonl` or `sqlite` | `jsonl` |
897
+ | `MEMORY_FILE_PATH` | Override storage file path | (per `ManagerContext` ctor) |
898
+ | `MEMORY_BACKEND` | Pluggable Memory-Engine backend: `sqlite` or `in-memory` | `sqlite` |
899
+ | `MEMORY_EMBEDDING_PROVIDER` | Embedding provider: `openai`, `local`, or `none` | `local` |
900
+ | `MEMORY_OPENAI_API_KEY` | OpenAI API key (required when provider is `openai`) | |
901
+ | `MEMORY_AUTO_INDEX_EMBEDDINGS` | Auto-build embedding index on entity create | `false` |
902
+ | `MEMORY_AUTO_DECAY` | Enable background memory decay | `false` |
903
+ | `MEMORY_DECAY_HALF_LIFE_HOURS` | Half-life for importance decay | `168` |
904
+ | `MEMORY_GOVERNANCE_ENABLED` | Enable `GovernanceManager` policy enforcement | `false` |
905
+ | `MEMORY_AUDIT_LOG_FILE` | Path for the audit JSONL trail | — |
906
+ | `MEMORY_AGENT_ROLE` | Apply a built-in role profile (`researcher` / `planner` / `executor` / `reviewer` / `coordinator`) | — |
907
+ | `MEMORY_VALIDATE_ON_STORE` | Run `MemoryValidator` before observation writes | `false` |
908
+ | `MEMORY_AUDIT_ATTRIBUTION_REQUIRED` | `CollaborationAuditEnforcer` strict mode | `false` |
909
+ | `MEMORY_RBAC_ENABLED` | Wire `RbacMiddleware` into `GovernancePolicy` | `false` |
910
+ | `MEMORY_DEFAULT_VISIBILITY` | Default `AgentEntity.visibility` | `private` |
911
+ | `MEMORY_USE_MMAP` | Use mmap for `GraphStorage.loadFromDisk` (strict `'true'` literal match) | `false` |
912
+ | `MEMORY_MMAP_THRESHOLD_BYTES` | Minimum file size to trigger the mmap path; `0` = always | `104857600` |
913
+ | `MEMORY_STORAGE_SEGMENT_COUNT` | FNV-routed JSONL shard count (1–1024) | `1` (off) |
914
+ | `MEMORY_SQLITE_READ_POOL_SIZE` | Read-connection pool size for `SQLiteStorage` | `4` |
915
+ | `MEMORY_SQLITE_AUTO_INDEX` | Enable `PartialIndexAdvisor`-driven automatic partial-index DDL | `false` |
916
+ | `SKIP_BENCHMARKS` | Skip perf-benchmark tests | `false` |
917
+ | `LOG_LEVEL` | `debug` / `info` / `warn` / `error` | (none) |
918
+
919
+ ## Development
920
+
921
+ ### Prerequisites
922
+
923
+ - Node.js 18+
924
+ - npm 9+
925
+ - TypeScript 5.0+
926
+
927
+ ### Common commands
928
+
929
+ ```bash
930
+ npm install # Install dependencies
931
+ npm run build # Build TypeScript to dist/ (tsup; ESM + CJS dual output)
932
+ npm run build:watch # Watch mode
933
+ npm test # Run all tests
934
+ npm run test:watch # Watch mode
935
+ npm run test:coverage # Run with coverage report
936
+ npm run test:ci # Excludes tests/performance/** (used by prepublishOnly)
937
+ npm run typecheck # Type checking without emit
938
+ npm run lint # ESLint (flat config; @typescript-eslint)
939
+ npm run benchmark # Standalone synthetic benchmarks
940
+ npm run bench # Vitest performance suite
941
+ SKIP_BENCHMARKS=true npm test # Skip perf tests in the main suite
942
+ ```
943
+
944
+ ### Tooling
945
+
946
+ ```bash
947
+ npm run audit:plans # Detect plan-doc rot
948
+ npx tsx tools/create-dependency-graph/create-dependency-graph.ts # Refresh DEPENDENCY_GRAPH.md
949
+ npx tsx tools/chunking-for-files/chunking-for-files.ts split <file> # Split a large file
950
+ npx tsx tools/chunking-for-files/chunking-for-files.ts merge <manifest> # Merge back
951
+ npx tsx tools/migrate-from-jsonl-to-sqlite/... # JSONL → SQLite migration
952
+ ```
953
+
954
+ ### Architecture overview
955
+
956
+ ```
957
+ ┌──────────────────────────────────────────────────────────────────┐
958
+ │ Layer 1: ManagerContext (Central Facade — lazy init) │
959
+ └──────────────────────────┬───────────────────────────────────────┘
960
+
961
+ ┌──────────────────────────┴───────────────────────────────────────┐
962
+ │ Layer 2: Domain managers │
963
+ │ Core: Entity / Relation / Observation / Hierarchy / Search / │
964
+ │ GraphTraversal / Tags / RefIndex │
965
+ │ I/O: IOManager / Archive / Compression / Analytics / Audit / │
966
+ │ Governance / Freshness / SemanticForget │
967
+ │ Search: Ranked / Semantic / Temporal / LLMQueryPlanner / │
968
+ │ ActiveRetrievalController │
969
+ Memory: MemoryEngine / MemoryBackend / ContextWindowManager / │
970
+ │ AgentMemory(facade) │
971
+ │ Intel: MemoryValidator / TrajectoryCompressor / │
972
+ │ ExperienceExtractor / PatternDetector │
973
+ │ Theory: ProcedureManager / CausalReasoner / WorldModelManager │
974
+ │ Auth: RbacMiddleware / RoleAssignmentStore / AccessTracker │
975
+ └──────────────────────────┬───────────────────────────────────────┘
976
+
977
+ ┌──────────────────────────┴───────────────────────────────────────┐
978
+ Layer 3: Storage │
979
+ │ GraphStorage (JSONL) or SQLiteStorage (better-sqlite3, FTS5) │
980
+ │ Pluggable IMemoryBackend: in-memory or sqlite-backed engine │
981
+ └──────────────────────────────────────────────────────────────────┘
982
+ ```
983
+
984
+ ### Project layout
985
+
986
+ ```
987
+ src/
988
+ ├── index.ts # Public entry point
989
+ ├── agent/ # Agent Memory System (managers, decay, salience,
990
+ # multi-agent, specialised memory types)
991
+ ├── core/ # ManagerContext, entity / relation / observation
992
+ # managers, storage backends, graph traversal
993
+ ├── search/ # Ranked / boolean / fuzzy / semantic / hybrid /
994
+ # temporal / LLM-planned search + indexes
995
+ ├── features/ # IOManager, Archive, Compression, Audit,
996
+ # Governance, Freshness, SemanticForget
997
+ ├── cli/ # `memory` / `memoryjs` CLI binary
998
+ ├── security/ # PII redactor, ABAC, RLS, API keys
999
+ ├── types/ # Shared TypeScript definitions
1000
+ ├── utils/ # Caching, schemas, compression adapters, logger
1001
+ └── workers/ # Worker pool for CPU-intensive tasks
1002
+
1003
+ tests/ # vitest test suite
1004
+ ├── unit/ # Per-module unit tests
1005
+ ├── integration/ # Cross-module workflows
1006
+ ├── edge-cases/ # Boundary conditions
1007
+ └── performance/ # Benchmarks (gated by SKIP_BENCHMARKS)
1008
+
1009
+ tools/ # Dev utilities (chunker, dep-graph generator,
1010
+ # migration, plan-doc audit, etc.)
1011
+ ```
1012
+
1013
+ See [`docs/architecture/DEPENDENCY_GRAPH.md`](docs/architecture/DEPENDENCY_GRAPH.md)
1014
+ for the autogenerated dependency graph and module breakdown.
1015
+
1016
+ ## Documentation
1017
+
1018
+ Architecture documentation lives under `docs/architecture/`:
1019
+
1020
+ - [OVERVIEW.md](docs/architecture/OVERVIEW.md) high-level project overview
1021
+ - [ARCHITECTURE.md](docs/architecture/ARCHITECTURE.md) technical design
1022
+ - [COMPONENTS.md](docs/architecture/COMPONENTS.md) — module-by-module breakdown
1023
+ - [DATAFLOW.md](docs/architecture/DATAFLOW.md) data-flow patterns
1024
+ - [API.md](docs/architecture/API.md) full API reference
1025
+ - [DEPENDENCY_GRAPH.md](docs/architecture/DEPENDENCY_GRAPH.md) — module dependencies (auto-generated)
1026
+ - [AGENT_MEMORY.md](docs/architecture/AGENT_MEMORY.md) Agent Memory System design
1027
+ - [TEST_COVERAGE.md](docs/architecture/TEST_COVERAGE.md) test coverage analysis
1028
+
1029
+ Other:
1030
+
1031
+ - [ARCHITECTURE_DECISIONS.md](docs/development/ARCHITECTURE_DECISIONS.md) Architecture Decision Records
1032
+ - [ROADMAP.md](docs/roadmap/ROADMAP.md) — feature roadmap
1033
+ - [CLAUDE.md](CLAUDE.md) — full environment-variable reference + working notes
1034
+ - [CHANGELOG.md](CHANGELOG.md) — version-by-version history
1035
+
1036
+ ## License
1037
+
1038
+ **MIT License** - see [LICENSE](LICENSE)
1039
+
1040
+ ## Related
1041
+
1042
+ - [@danielsimonjr/memory-mcp](https://github.com/danielsimonjr/memory-mcp) - MCP server built on this library
1043
+
1044
+ ---
1045
+
1046
+ **Repository:** https://github.com/danielsimonjr/memoryjs
1047
+ **NPM:** https://www.npmjs.com/package/@danielsimonjr/memoryjs
1048
+ **Issues:** https://github.com/danielsimonjr/memoryjs/issues