pi-hermes-memory 0.3.2 → 0.4.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
@@ -19,56 +19,15 @@ Your Pi agent normally forgets everything when you close a session. This extensi
19
19
  | **Memory Aging** | Entries carry timestamps — consolidation knows which facts are stale and which are fresh |
20
20
  | **Project Memory** | Per-project memory (`~/.pi/agent/<project>/MEMORY.md`) alongside your global memory |
21
21
  | **Secret Detection** | API keys, tokens, SSH keys, and credential assignments are blocked from being persisted to memory |
22
+ | **Session History Search** | Search across all past conversations via SQLite FTS5 — "what did we discuss about auth?" |
23
+ | **Extended Memory Store** | Unlimited searchable memories beyond the core 5,000-char limit |
24
+ | **Learn Memory Tool** | `/learn-memory-tool` — a skill that teaches users how to use the memory system |
22
25
 
23
26
  ## How It Works
24
27
 
25
28
  ### Session Lifecycle
26
29
 
27
- ```mermaid
28
- sequenceDiagram
29
- participant User
30
- participant Pi
31
- participant Extension
32
- participant Disk as ~/.pi/agent/memory/
33
-
34
- Note over Pi,Disk: ── Session Start ──
35
- Pi->>Extension: session_start event
36
- Extension->>Disk: loadFromDisk() — read MEMORY.md + USER.md + skills/
37
- Extension-->>Extension: Capture frozen snapshot (memory + skill index)
38
-
39
- Note over Pi,Disk: ── System Prompt Injection ──
40
- Pi->>Extension: before_agent_start event
41
- Extension-->>Pi: systemPrompt + frozen memory block + skill index
42
- Note right of Pi: Agent now "remembers"<br/>facts AND procedures<br/>from past sessions
43
-
44
- Note over Pi,Disk: ── Agent Loop ──
45
- User->>Pi: "Remember I prefer vim"
46
- Pi->>Extension: tool_call (memory, add)
47
- Extension->>Extension: scanContent() — security check
48
- Extension->>Disk: Atomic write to USER.md
49
- Extension-->>Pi: { success: true, usage: "3% — 41/1375" }
50
-
51
- Note over Pi,Disk: ── User Correction ──
52
- User->>Pi: "No, don't use npm — use pnpm"
53
- Extension->>Extension: isCorrection() = true
54
- Extension->>Pi: pi.exec("pi -p", correctionPrompt)
55
- Note right of Pi: Immediate save<br/>no waiting for nudge
56
-
57
- Note over Pi,Disk: ── Complex Task (8+ tool calls) ──
58
- Pi->>Extension: turn_end (8 tool calls, 3 tool types)
59
- Extension->>Pi: pi.exec("pi -p", skillExtractionPrompt)
60
- Note right of Pi: Extract reusable<br/>procedure as skill
61
-
62
- Note over Pi,Disk: ── Background Review (10 turns or 15 tool calls) ──
63
- Pi->>Extension: turn_end event
64
- Extension->>Pi: pi.exec("pi -p", reviewPrompt)
65
- Note right of Pi: Reviews conversation<br/>saves memories AND skills
66
-
67
- Note over Pi,Disk: ── Session End ──
68
- Pi->>Extension: session_shutdown event
69
- Extension->>Pi: pi.exec("pi -p", flushPrompt)
70
- Note right of Pi: One last turn to flush<br/>anything worth saving
71
- ```
30
+ ![Session Lifecycle](docs/images/session-lifecycle.svg)
72
31
 
73
32
  ### Memory + Skills Architecture
74
33
 
@@ -80,63 +39,13 @@ The extension manages three types of knowledge:
80
39
  | **User Profile** (USER.md) | Who you are — name, preferences, communication style | 1,375 chars max | Fixed per session |
81
40
  | **Skills** (skills/*.md) | Procedures — *how* to do something, reusable across sessions | Unlimited | ~3K for index, full on demand |
82
41
 
83
- ```mermaid
84
- graph TB
85
- subgraph "Persistent Storage"
86
- MEM["MEMORY.md<br/><i>Agent's notes</i>"]
87
- USR["USER.md<br/><i>User profile</i>"]
88
- SKL["skills/<br/><i>Procedural memory</i><br/>debug-ts.md<br/>deploy-checklist.md"]
89
- end
90
-
91
- subgraph "System Prompt (frozen snapshot)"
92
- SMEM["Memory block<br/>Full content"]
93
- SUSR["User block<br/>Full content"]
94
- SSKL["Skill index<br/>Names + descriptions only"]
95
- end
96
-
97
- subgraph "On Demand (via skill tool)"
98
- FULL["Full skill content<br/>Loaded when needed"]
99
- end
100
-
101
- MEM --> SMEM
102
- USR --> SUSR
103
- SKL --> SSKL
104
- SSKL -.->|"skill view"| FULL
105
-
106
- style SMEM fill:#1a1a2e,stroke:#e94560,color:#fff
107
- style SUSR fill:#1a1a2e,stroke:#e94560,color:#fff
108
- style SSKL fill:#16213e,stroke:#0f3460,color:#fff
109
- style FULL fill:#0a1128,stroke:#1282a2,color:#fff
110
- ```
42
+ ![Memory + Skills Architecture](docs/images/memory-architecture.svg)
111
43
 
112
44
  ### Security: Content Scanning
113
45
 
114
46
  Every write — memory and skills — passes through a scanner before being accepted. This prevents the LLM from being tricked into storing malicious content that would later be injected into the system prompt.
115
47
 
116
- ```mermaid
117
- flowchart LR
118
- A["LLM calls<br/>memory or skill"] --> B{scanContent}
119
- B -->|Blocked| C["❌ Return error"]
120
- B -->|Safe| D{Char limit<br/>check}
121
- D -->|Exceeds| E{autoConsolidate?}
122
- E -->|Yes| G["🔄 Merge & prune<br/>then retry"]
123
- E -->|No| F["❌ Return budget error"]
124
- D -->|Within limit| H["✅ Write to disk"]
125
-
126
- subgraph "Blocked Patterns"
127
- P1["'ignore previous instructions'"]
128
- P2["'curl ${API_KEY}'"]
129
- P3["Zero-width chars"]
130
- end
131
-
132
- B -.- P1
133
- B -.- P2
134
- B -.- P3
135
-
136
- style C fill:#3d0000,stroke:#ff4444,color:#fff
137
- style G fill:#003d3d,stroke:#00cccc,color:#fff
138
- style H fill:#003d00,stroke:#44ff44,color:#fff
139
- ```
48
+ ![Security: Content Scanning](docs/images/security-flow.svg)
140
49
 
141
50
  ## Installation
142
51
 
@@ -251,9 +160,34 @@ Run `tsc --noEmit` and confirm zero errors.
251
160
 
252
161
  | Store | File | What goes here | Limit |
253
162
  |---|---|---|---|
254
- | **memory** | `MEMORY.md` | Agent's notes — env facts, project conventions, tool quirks, lessons learned | 2,200 chars |
255
- | **user** | `USER.md` | User profile — name, preferences, communication style, habits | 1,375 chars |
163
+ | **memory** | `MEMORY.md` | Agent's notes — env facts, project conventions, tool quirks, lessons learned | 5,000 chars |
164
+ | **user** | `USER.md` | User profile — name, preferences, communication style, habits | 5,000 chars |
256
165
  | **skills** | `skills/*.md` | Procedures — *how* to debug, deploy, test, or fix something | Unlimited |
166
+ | **extended** | `sessions.db` | Searchable memories beyond the core limit | Unlimited |
167
+ | **sessions** | `sessions.db` | Past conversation history (searchable via FTS5) | Unlimited |
168
+
169
+ ### Session History Search
170
+
171
+ The extension indexes your Pi session history into a SQLite database with FTS5 full-text search. The agent can search across all past conversations using the `session_search` tool:
172
+
173
+ | Tool | What it does |
174
+ |---|---|---|
175
+ | `session_search` | Search past conversations — "what did we discuss about auth?" |
176
+ | `memory_search` | Search extended memory store — unlimited capacity, keyword-based |
177
+
178
+ Session history is indexed automatically on session shutdown. To bulk-import existing sessions:
179
+
180
+ ```
181
+ /memory-index-sessions
182
+ ```
183
+
184
+ ### Extended Memory Store
185
+
186
+ When the core memory (5,000 chars) isn't enough, the agent can store additional memories in the SQLite-backed extended store. These are searchable via `memory_search` but not automatically injected into the system prompt.
187
+
188
+ This is the **hybrid memory architecture**:
189
+ - **Core memory** (MEMORY.md/USER.md): Always injected, 5,000 chars each, human-readable
190
+ - **Extended memory** (SQLite): Unlimited, searchable on demand, agent-driven
257
191
 
258
192
  ### Correction Detection
259
193
 
@@ -305,6 +239,8 @@ This means skills build up naturally over time without you having to ask.
305
239
  | `/memory-consolidate` | Manually trigger memory consolidation to free space |
306
240
  | `/memory-interview` | Answer a few questions to pre-fill your user profile |
307
241
  | `/memory-switch-project` | List all project memories and their entry counts |
242
+ | `/memory-index-sessions` | Import past Pi sessions into the search database |
243
+ | `/learn-memory-tool` | Skill that teaches users how to use the memory system |
308
244
 
309
245
  ### `/memory-insights` Output
310
246
 
@@ -348,9 +284,9 @@ Create `~/.pi/agent/hermes-memory-config.json`:
348
284
 
349
285
  ```json
350
286
  {
351
- "memoryCharLimit": 2200,
352
- "userCharLimit": 1375,
353
- "projectCharLimit": 2200,
287
+ "memoryCharLimit": 5000,
288
+ "userCharLimit": 5000,
289
+ "projectCharLimit": 5000,
354
290
  "memoryDir": "~/.pi/agent/memory",
355
291
  "nudgeInterval": 10,
356
292
  "nudgeToolCalls": 15,
@@ -365,9 +301,9 @@ Create `~/.pi/agent/hermes-memory-config.json`:
365
301
 
366
302
  | Setting | Default | Description |
367
303
  |---|---|---|
368
- | `memoryCharLimit` | `2200` | Max characters in MEMORY.md |
369
- | `userCharLimit` | `1375` | Max characters in USER.md |
370
- | `projectCharLimit` | `2200` | Max characters in project-scoped MEMORY.md |
304
+ | `memoryCharLimit` | `5000` | Max characters in MEMORY.md |
305
+ | `userCharLimit` | `5000` | Max characters in USER.md |
306
+ | `projectCharLimit` | `5000` | Max characters in project-scoped MEMORY.md |
371
307
  | `memoryDir` | `~/.pi/agent/memory` | Custom directory for memory files |
372
308
  | `nudgeInterval` | `10` | Turns between auto-reviews |
373
309
  | `nudgeToolCalls` | `15` | Tool calls between auto-reviews (OR with turns) |
@@ -384,6 +320,7 @@ Create `~/.pi/agent/hermes-memory-config.json`:
384
320
  ~/.pi/agent/memory/
385
321
  ├── MEMORY.md ← Agent's personal notes (env facts, patterns, lessons)
386
322
  ├── USER.md ← User profile (name, preferences, habits)
323
+ ├── sessions.db ← SQLite database (session history + extended memory)
387
324
  └── skills/
388
325
  ├── debug-typescript-errors.md
389
326
  └── deploy-checklist.md
@@ -391,60 +328,19 @@ Create `~/.pi/agent/hermes-memory-config.json`:
391
328
 
392
329
  These are plain markdown files. You can read and edit them directly if you want to curate what the agent remembers. Memory entries are separated by `§` (section sign). Skills use standard SKILL.md format with frontmatter.
393
330
 
331
+ The `sessions.db` SQLite database stores session history and extended memory entries. It's searchable via FTS5 full-text search.
332
+
394
333
  ## Known Limitations
395
334
 
396
335
  - **`§` delimiter**: Memory entries are separated by `§` (section sign). If an entry naturally contains `§`, it will be split incorrectly on reload. This is rare in English text but possible. [Hermes uses the same delimiter.]
397
336
  - **Background review cost**: Each review cycle costs one full LLM API call via a child `pi -p` process. Correction detection and skill auto-extraction add occasional extra calls.
398
- - **No search/indexing**: At the 2,200-char limit, the LLM can scan the entire block. Full-text search across sessions is planned for v0.3.
337
+ - **Session search requires indexing**: Past sessions must be indexed before they're searchable. Run `/memory-index-sessions` to bulk-import, or let the extension auto-index on session shutdown.
399
338
  - **System prompts are invisible**: Pi's TUI does not display the system prompt. Memory injection works but you won't see it in the interface — verify by asking the agent a question that relies on stored memory.
400
339
  - **Skills are agent-generated**: Skills are created by the agent based on its experience. They may not always be perfectly structured. You can edit or delete them in `~/.pi/agent/memory/skills/`.
401
340
 
402
341
  ## Architecture
403
342
 
404
- ```mermaid
405
- graph LR
406
- subgraph "pi-hermes-memory/src/"
407
- IDX["index.ts<br/><i>Entry point</i>"]
408
- MS["memory-store.ts<br/><i>Memory CRUD</i>"]
409
- SS["skill-store.ts<br/><i>Skill CRUD</i>"]
410
- MT["memory-tool.ts<br/><i>Memory LLM tool</i>"]
411
- ST["skill-tool.ts<br/><i>Skill LLM tool</i>"]
412
- CS["content-scanner.ts<br/><i>Security</i>"]
413
- BR["background-review.ts<br/><i>Learning loop</i>"]
414
- AC["auto-consolidate.ts<br/><i>Memory merge</i>"]
415
- CD["correction-detector.ts<br/><i>Instant save</i>"]
416
- SA["skill-auto-trigger.ts<br/><i>Skill extraction</i>"]
417
- SF["session-flush.ts<br/><i>Pre-compaction flush</i>"]
418
- IN["insights.ts<br/><i>/memory-insights</i>"]
419
- SC["skills-command.ts<br/><i>/memory-skills</i>"]
420
- end
421
-
422
- IDX --> MS
423
- IDX --> SS
424
- IDX --> MT
425
- IDX --> ST
426
- IDX --> BR
427
- IDX --> AC
428
- IDX --> CD
429
- IDX --> SA
430
- IDX --> SF
431
- IDX --> IN
432
- IDX --> SC
433
- MT --> MS
434
- ST --> SS
435
- MS --> CS
436
- SS --> CS
437
- BR --> MS
438
- AC --> MS
439
- CD --> MS
440
- SA --> MS
441
- SA --> SS
442
-
443
- style IDX fill:#e94560,stroke:#fff,color:#fff
444
- style MS fill:#0f3460,stroke:#fff,color:#fff
445
- style SS fill:#0f3460,stroke:#fff,color:#fff
446
- style CS fill:#ff6600,stroke:#fff,color:#fff
447
- ```
343
+ ![Source Architecture](docs/images/source-architecture.svg)
448
344
 
449
345
  ## Credits
450
346
 
@@ -0,0 +1,160 @@
1
+ # v0.4 Plan: SQLite FTS5 Session Search + Hybrid Memory
2
+
3
+ ## Problem
4
+
5
+ The current memory architecture has two scaling bottlenecks:
6
+
7
+ 1. **Memory capacity**: MEMORY.md is capped at 2,200 chars. Power users accumulate knowledge faster than consolidation can manage. Important facts get pruned.
8
+ 2. **No session history search**: Past conversations are stored as JSONL files in `~/.pi/agent/sessions/<project>/`, but there's no way to search them. When the agent needs context from a previous session, it's gone forever.
9
+
10
+ ## Solution: Hybrid Memory Architecture
11
+
12
+ ### Core memory (always injected, unchanged)
13
+ - `MEMORY.md` — 5,000 chars (up from 2,200)
14
+ - `USER.md` — 5,000 chars (up from 1,375)
15
+ - Still injected into every session via `<memory-context>` tags
16
+ - Still human-readable, still editable
17
+
18
+ ### Extended memory (SQLite, searchable on demand)
19
+ - `~/.pi/agent/memory/sessions.db`
20
+ - `memories` table — unlimited entries, searchable via FTS5
21
+ - Agent uses `memory_search` tool to query when it needs context
22
+ - Not automatically injected — agent must explicitly search
23
+
24
+ ### Session history (SQLite, searchable on demand)
25
+ - Same `sessions.db` file
26
+ - `sessions` + `messages` tables — all past conversations indexed
27
+ - `session_fts` FTS5 index — full-text search across all sessions
28
+ - Agent uses `session_search` tool to find relevant past context
29
+
30
+ ## Architecture
31
+
32
+ ```
33
+ Session starts
34
+
35
+ ┌─────────────────────────────────────────────────┐
36
+ │ System Prompt (always injected) │
37
+ │ ┌─────────────────────────────────────────────┐ │
38
+ │ │ <memory-context> │ │
39
+ │ │ MEMORY (your personal notes) [5,000 chars] │ │
40
+ │ │ ═══ END MEMORY ═══ │ │
41
+ │ │ </memory-context> │ │
42
+ │ │ <memory-context> │ │
43
+ │ │ USER PROFILE [5,000 chars] │ │
44
+ │ │ ═══ END MEMORY ═══ │ │
45
+ │ │ </memory-context> │ │
46
+ │ │ <memory-context> │ │
47
+ │ │ PROJECT MEMORY [5,000 chars] │ │
48
+ │ │ ═══ END MEMORY ═══ │ │
49
+ │ │ </memory-context> │ │
50
+ │ └─────────────────────────────────────────────┘ │
51
+ └─────────────────────────────────────────────────┘
52
+
53
+ Agent has access to tools:
54
+ memory_search("prisma migration")
55
+ → Searches memories table (global + project)
56
+ → Returns top-10 relevant entries
57
+
58
+ session_search("how we fixed the test hang")
59
+ → Searches session history via FTS5
60
+ → Returns relevant conversation snippets
61
+ ```
62
+
63
+ ## Data Model
64
+
65
+ ```sql
66
+ -- Session metadata
67
+ CREATE TABLE sessions (
68
+ id TEXT PRIMARY KEY, -- UUID from JSONL
69
+ project TEXT NOT NULL, -- decoded cwd path
70
+ started_at TEXT NOT NULL, -- ISO timestamp
71
+ ended_at TEXT, -- ISO timestamp (null if still running)
72
+ message_count INTEGER DEFAULT 0
73
+ );
74
+
75
+ -- All messages from all sessions
76
+ CREATE TABLE messages (
77
+ id TEXT PRIMARY KEY, -- message ID from JSONL
78
+ session_id TEXT NOT NULL REFERENCES sessions(id),
79
+ role TEXT NOT NULL, -- 'user', 'assistant', 'system'
80
+ content TEXT NOT NULL, -- extracted text content
81
+ timestamp TEXT NOT NULL, -- ISO timestamp
82
+ tool_calls TEXT -- JSON array of tool call names (for assistant messages)
83
+ );
84
+
85
+ -- FTS5 index for full-text search across messages
86
+ CREATE VIRTUAL TABLE message_fts USING fts5(
87
+ content,
88
+ content='messages',
89
+ content_rowid='rowid'
90
+ );
91
+
92
+ -- Extended memory entries (beyond MEMORY.md limit)
93
+ CREATE TABLE memories (
94
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
95
+ project TEXT, -- NULL for global, project name for project-specific
96
+ target TEXT NOT NULL, -- 'memory' or 'user'
97
+ content TEXT NOT NULL,
98
+ created DATE NOT NULL,
99
+ last_referenced DATE NOT NULL
100
+ );
101
+
102
+ -- FTS5 index for memory search
103
+ CREATE VIRTUAL TABLE memory_fts USING fts5(
104
+ content,
105
+ content='memories',
106
+ content_rowid='id'
107
+ );
108
+ ```
109
+
110
+ ## Key Design Decisions
111
+
112
+ ### 1. Session indexing is lazy (on session end)
113
+ - Don't parse JSONL files on every startup
114
+ - Index a session when `session_shutdown` fires
115
+ - Bulk import existing sessions via `/memory-index-sessions` command
116
+
117
+ ### 2. FTS5 for both memories and sessions
118
+ - Keyword search is sufficient for v0.4
119
+ - Embeddings deferred to v0.5+ if search quality isn't enough
120
+ - `better-sqlite3` includes FTS5 by default
121
+
122
+ ### 3. Single DB file
123
+ - `~/.pi/agent/memory/sessions.db` stores everything
124
+ - Memories + sessions + FTS indices in one file
125
+ - Simple backup (copy one file), simple cleanup
126
+
127
+ ### 4. Agent-driven search
128
+ - `memory_search` and `session_search` are LLM tools
129
+ - Agent decides when to search (not automatic)
130
+ - Avoids injecting irrelevant context into every session
131
+
132
+ ### 5. Char limit increase to 5,000
133
+ - MEMORY.md: 2,200 → 5,000 chars
134
+ - USER.md: 1,375 → 5,000 chars
135
+ - Project MEMORY.md: 2,200 → 5,000 chars
136
+ - More room for core memories before consolidation kicks in
137
+
138
+ ## Dependencies
139
+
140
+ | Package | Purpose | Size |
141
+ |---|---|---|
142
+ | `better-sqlite3` | SQLite with FTS5 | ~1MB native addon |
143
+
144
+ ## Risks
145
+
146
+ | Risk | Mitigation |
147
+ |---|---|
148
+ | `better-sqlite3` is a native C++ addon | Standard for dev tools; CI has build tools |
149
+ | FTS5 search quality | Start with keyword search, add embeddings later if needed |
150
+ | Session JSONL format changes | Parse defensively, skip unknown message types |
151
+ | Large session history (1000+ sessions) | FTS5 handles this well; add pagination to results |
152
+ | DB corruption | Atomic writes, WAL mode, backup before migrations |
153
+
154
+ ## Success Criteria
155
+
156
+ 1. `session_search("prisma migration")` returns relevant conversation snippets from past sessions
157
+ 2. `memory_search("auth setup")` returns relevant entries from extended memory store
158
+ 3. MEMORY.md limit raised to 5,000 chars without breaking existing functionality
159
+ 4. Existing session files indexed without data loss
160
+ 5. All tests pass, zero regressions
@@ -0,0 +1,146 @@
1
+ # v0.4 Tasks: SQLite FTS5 Session Search + Hybrid Memory
2
+
3
+ ## Status Legend
4
+ - `[ ]` Not started
5
+ - `[~]` In progress
6
+ - `[x]` Done
7
+
8
+ ---
9
+
10
+ ## Epic 1: SQLite Foundation
11
+
12
+ ### Task 1.1: Install better-sqlite3 and create DB module
13
+ - [ ] Install `better-sqlite3` + `@types/better-sqlite3`
14
+ - [ ] Create `src/store/db.ts` — DatabaseManager class
15
+ - Lazy initialization (create/open DB on first use)
16
+ - WAL mode for concurrent reads
17
+ - Auto-create tables if they don't exist
18
+ - `close()` method for cleanup
19
+ - [ ] Create `tests/store/db.test.ts` — tests for DB initialization, table creation, close/reopen
20
+
21
+ ### Task 1.2: Create schema and migrations
22
+ - [ ] Define schema in `src/store/schema.ts` — all CREATE TABLE statements
23
+ - `sessions` table
24
+ - `messages` table
25
+ - `message_fts` FTS5 virtual table
26
+ - `memories` table
27
+ - `memory_fts` FTS5 virtual table
28
+ - [ ] Add triggers to keep FTS index in sync (INSERT/UPDATE/DELETE)
29
+ - [ ] Test: schema creates cleanly on fresh DB, idempotent on existing DB
30
+
31
+ ---
32
+
33
+ ## Epic 2: Session History Indexing
34
+
35
+ ### Task 2.1: JSONL parser
36
+ - [ ] Create `src/store/session-parser.ts`
37
+ - `parseSessionFile(path)` — read JSONL, extract session metadata + messages
38
+ - Handle all message types: user, assistant, system, tool_result
39
+ - Extract text content from `content` array (handle text, thinking, tool_use types)
40
+ - Skip unknown types gracefully
41
+ - Return structured `SessionData` with `messages: ParsedMessage[]`
42
+ - [ ] Create `tests/store/session-parser.test.ts` — test with real JSONL fixtures
43
+
44
+ ### Task 2.2: Session indexer
45
+ - [ ] Create `src/store/session-indexer.ts`
46
+ - `indexSession(db, sessionData)` — INSERT into sessions + messages tables
47
+ - `indexAllSessions(db, projectPath?)` — bulk index all sessions for a project (or all projects)
48
+ - Skip already-indexed sessions (by session ID)
49
+ - `getSessionStats(db)` — count of sessions, messages, indexed projects
50
+ - [ ] Create `tests/store/session-indexer.test.ts` — test indexing, deduplication, stats
51
+
52
+ ### Task 2.3: /memory-index-sessions command
53
+ - [ ] Create `src/handlers/index-sessions.ts`
54
+ - `/memory-index-sessions` — bulk import existing JSONL sessions
55
+ - Show progress: "Indexing 36 sessions..."
56
+ - Show result: "Indexed 36 sessions, 1,247 messages"
57
+ - Handle errors gracefully (corrupt JSONL, missing files)
58
+ - [ ] Wire into `src/index.ts`
59
+ - [ ] Create `tests/handlers/index-sessions.test.ts`
60
+
61
+ ---
62
+
63
+ ## Epic 3: Session Search
64
+
65
+ ### Task 3.1: Session search store
66
+ - [ ] Add to `src/store/session-indexer.ts` (or separate `session-search.ts`)
67
+ - `searchSessions(db, query, options?)` — FTS5 search across messages
68
+ - Options: `limit`, `project`, `role` filter, `since` date filter
69
+ - Returns: `SearchResult[]` with `{sessionId, role, content, timestamp, snippet, project}`
70
+ - `snippet` — highlighted match context from FTS5 `snippet()` function
71
+ - [ ] Create `tests/store/session-search.test.ts` — test search, filters, relevance
72
+
73
+ ### Task 3.2: session_search tool
74
+ - [ ] Create `src/tools/session-search-tool.ts`
75
+ - LLM tool definition: `session_search(query, project?, limit?)`
76
+ - Returns formatted results for the agent
77
+ - Includes session date, project, and content snippet
78
+ - [ ] Register in `src/index.ts`
79
+ - [ ] Create `tests/tools/session-search-tool.test.ts`
80
+
81
+ ---
82
+
83
+ ## Epic 4: Extended Memory Store
84
+
85
+ ### Task 4.1: SQLite memory store
86
+ - [ ] Create `src/store/sqlite-memory-store.ts`
87
+ - `addMemory(db, content, project?, target?)` — INSERT into memories + memory_fts
88
+ - `searchMemories(db, query, options?)` — FTS5 search across memories
89
+ - `getMemories(db, project?, target?)` — list all memories (optionally filtered)
90
+ - `removeMemory(db, id)` — DELETE by ID
91
+ - `getMemoryStats(db)` — count by project/target
92
+ - [ ] Create `tests/store/sqlite-memory-store.test.ts`
93
+
94
+ ### Task 4.2: memory_search tool
95
+ - [ ] Create `src/tools/memory-search-tool.ts`
96
+ - LLM tool definition: `memory_search(query, project?, limit?)`
97
+ - Searches both global and project-specific memories
98
+ - Returns formatted results for the agent
99
+ - [ ] Register in `src/index.ts`
100
+ - [ ] Create `tests/tools/memory-search-tool.test.ts`
101
+
102
+ ---
103
+
104
+ ## Epic 5: Char Limit Increase
105
+
106
+ ### Task 5.1: Update defaults
107
+ - [ ] Update `src/config.ts` — change defaults:
108
+ - `memoryCharLimit`: 2200 → 5000
109
+ - `userCharLimit`: 1375 → 5000
110
+ - `projectCharLimit`: 2200 → 5000
111
+ - [ ] Update `src/constants.ts` — change constants if any
112
+ - [ ] Update README configuration table
113
+
114
+ ### Task 5.2: Update tests
115
+ - [ ] Update all tests that depend on char limits
116
+ - [ ] Verify consolidation still works at new limits
117
+ - [ ] Verify interview still works at new limits
118
+
119
+ ---
120
+
121
+ ## Epic 6: Integration & Polish
122
+
123
+ ### Task 6.1: Wire everything into index.ts
124
+ - [ ] Initialize DatabaseManager on extension load
125
+ - [ ] Register `session_search` and `memory_search` tools
126
+ - [ ] Register `/memory-index-sessions` command
127
+ - [ ] Auto-index session on `session_shutdown` event
128
+ - [ ] Close DB on extension unload
129
+
130
+ ### Task 6.2: Add session indexing to background review
131
+ - [ ] In `session-flush.ts` — also index the session to SQLite before flushing memories
132
+ - [ ] Ensure session is indexed even if shutdown event is missed
133
+
134
+ ### Task 6.3: Update README
135
+ - [ ] Add "Hybrid Memory Architecture" section
136
+ - [ ] Document `session_search` and `memory_search` tools
137
+ - [ ] Document `/memory-index-sessions` command
138
+ - [ ] Update char limit documentation
139
+ - [ ] Update configuration table
140
+
141
+ ### Task 6.4: Version bump & release
142
+ - [ ] Bump version to `0.4.0`
143
+ - [ ] Update CHANGELOG.md
144
+ - [ ] Run full test suite
145
+ - [ ] Publish to npm
146
+ - [ ] Create GitHub release