memctl 0.2.1__tar.gz → 0.4.0__tar.gz
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.
- {memctl-0.2.1 → memctl-0.4.0}/PKG-INFO +130 -10
- {memctl-0.2.1 → memctl-0.4.0}/README.md +129 -9
- {memctl-0.2.1 → memctl-0.4.0}/memctl/__init__.py +1 -1
- memctl-0.4.0/memctl/chat.py +414 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/cli.py +345 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/ingest.py +6 -2
- memctl-0.4.0/memctl/inspect.py +586 -0
- memctl-0.4.0/memctl/mount.py +111 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/store.py +183 -5
- memctl-0.4.0/memctl/sync.py +368 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl.egg-info/PKG-INFO +130 -10
- {memctl-0.2.1 → memctl-0.4.0}/memctl.egg-info/SOURCES.txt +8 -0
- {memctl-0.2.1 → memctl-0.4.0}/pyproject.toml +1 -1
- memctl-0.4.0/tests/test_chat.py +317 -0
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_cli.py +247 -1
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_forward_compat.py +50 -0
- memctl-0.4.0/tests/test_inspect.py +571 -0
- memctl-0.4.0/tests/test_mount.py +118 -0
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_store.py +177 -1
- memctl-0.4.0/tests/test_sync.py +297 -0
- {memctl-0.2.1 → memctl-0.4.0}/LICENSE +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/config.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/consolidate.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/extract.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/loop.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/mcp/__init__.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/mcp/formatting.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/mcp/server.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/mcp/tools.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/policy.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/proposer.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/similarity.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl/types.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl.egg-info/dependency_links.txt +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl.egg-info/entry_points.txt +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl.egg-info/requires.txt +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/memctl.egg-info/top_level.txt +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/setup.cfg +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_contracts.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_extract.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_ingest.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_loop.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_pipe_compose.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_policy.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_similarity.py +0 -0
- {memctl-0.2.1 → memctl-0.4.0}/tests/test_types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: memctl
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.4.0
|
|
4
4
|
Summary: A Unix-native memory control plane for LLM orchestration
|
|
5
5
|
Author-email: Olivier Vitrac <olivier.vitrac@adservio.fr>
|
|
6
6
|
License: MIT
|
|
@@ -150,7 +150,34 @@ memctl search "authentication"
|
|
|
150
150
|
memctl search "database" --json -k 5
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
### 5. Inspect
|
|
153
|
+
### 5. Inspect a folder (one-liner)
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Auto-mounts, auto-syncs, and inspects — all in one command
|
|
157
|
+
memctl inspect docs/
|
|
158
|
+
|
|
159
|
+
# Same in JSON (for scripts)
|
|
160
|
+
memctl inspect docs/ --json
|
|
161
|
+
|
|
162
|
+
# Skip sync (use cached state)
|
|
163
|
+
memctl inspect docs/ --no-sync
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
`inspect` auto-mounts the folder if needed, checks staleness, syncs only if stale, and produces a structural summary. All implicit actions are announced on stderr.
|
|
167
|
+
|
|
168
|
+
### 6. Chat with memory-backed context
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
# Interactive chat with any LLM
|
|
172
|
+
memctl chat --llm "claude -p" --session
|
|
173
|
+
|
|
174
|
+
# With pre-ingested files and answer storage
|
|
175
|
+
memctl chat --llm "ollama run granite3.1:2b" --source docs/ --store --session
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Each question recalls from the memory store, sends context + question to the LLM, and displays the answer. `--session` keeps a sliding window of recent Q&A pairs. `--store` persists answers as STM items.
|
|
179
|
+
|
|
180
|
+
### 7. Manage
|
|
154
181
|
|
|
155
182
|
```bash
|
|
156
183
|
memctl show MEM-abc123def456 # Show item details
|
|
@@ -180,6 +207,10 @@ memctl <command> [options]
|
|
|
180
207
|
| `stats` | Store statistics |
|
|
181
208
|
| `consolidate [--dry-run]` | Deterministic merge of similar STM items |
|
|
182
209
|
| `loop QUERY --llm CMD` | Bounded recall-answer loop with LLM |
|
|
210
|
+
| `mount PATH` | Register a folder as a structured source |
|
|
211
|
+
| `sync [PATH]` | Delta-sync mounted folders into the store |
|
|
212
|
+
| `inspect [PATH]` | Structural inspection with auto-mount and auto-sync |
|
|
213
|
+
| `chat --llm CMD` | Interactive memory-backed chat REPL |
|
|
183
214
|
| `serve` | Start MCP server (requires `memctl[mcp]`) |
|
|
184
215
|
|
|
185
216
|
### Global Flags
|
|
@@ -291,6 +322,77 @@ memctl push "database schema" --source src/ \
|
|
|
291
322
|
memctl loop --replay trace.jsonl "original question"
|
|
292
323
|
```
|
|
293
324
|
|
|
325
|
+
#### `memctl mount`
|
|
326
|
+
|
|
327
|
+
```bash
|
|
328
|
+
memctl mount PATH [--name NAME] [--ignore PATTERN ...] [--lang HINT]
|
|
329
|
+
memctl mount --list
|
|
330
|
+
memctl mount --remove ID_OR_NAME
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Registers a folder as a structured source. Stores metadata only — no scanning, no ingestion. The folder contents are synced separately via `sync` or automatically via `inspect`.
|
|
334
|
+
|
|
335
|
+
#### `memctl sync`
|
|
336
|
+
|
|
337
|
+
```bash
|
|
338
|
+
memctl sync [PATH] [--full] [--json] [--quiet]
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Delta-syncs mounted folders into the memory store. Uses a 3-tier delta rule:
|
|
342
|
+
1. **New file** (not in DB) → ingest
|
|
343
|
+
2. **Size + mtime match** → fast skip (no hashing)
|
|
344
|
+
3. **Hash compare** → ingest only if content changed
|
|
345
|
+
|
|
346
|
+
If `PATH` is given but not yet mounted, it is auto-registered first. `--full` forces re-processing of all files.
|
|
347
|
+
|
|
348
|
+
#### `memctl inspect`
|
|
349
|
+
|
|
350
|
+
```bash
|
|
351
|
+
# Orchestration mode — auto-mounts, auto-syncs, and inspects
|
|
352
|
+
memctl inspect PATH [--sync auto|always|never] [--no-sync] [--mount-mode persist|ephemeral]
|
|
353
|
+
[--budget N] [--ignore PATTERN ...] [--json] [--quiet]
|
|
354
|
+
|
|
355
|
+
# Classic mode — inspect an existing mount by ID/name
|
|
356
|
+
memctl inspect --mount ID_OR_NAME [--budget N] [--json] [--quiet]
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
When given a positional `PATH`, inspect operates in **orchestration mode**:
|
|
360
|
+
1. **Auto-mount** — registers the folder if not already mounted
|
|
361
|
+
2. **Staleness check** — compares disk inventory (path/size/mtime triples) against the store
|
|
362
|
+
3. **Auto-sync** — runs delta sync only if stale (or always/never per `--sync`)
|
|
363
|
+
4. **Inspect** — generates a deterministic structural summary
|
|
364
|
+
|
|
365
|
+
Output includes file/chunk/size totals, per-folder breakdown, per-extension distribution, top-5 largest files, and rule-based observations. All paths in output are mount-relative (never absolute).
|
|
366
|
+
|
|
367
|
+
`--mount-mode ephemeral` removes the mount record after inspection (corpus data is preserved). `--no-sync` is shorthand for `--sync never`.
|
|
368
|
+
|
|
369
|
+
All implicit actions (mount, sync) are announced on stderr. `--quiet` suppresses them.
|
|
370
|
+
|
|
371
|
+
#### `memctl chat`
|
|
372
|
+
|
|
373
|
+
```bash
|
|
374
|
+
memctl chat --llm CMD [--session] [--store] [--protocol passive|json|regex]
|
|
375
|
+
[--max-calls N] [--budget N] [--source FILE ...] [--quiet]
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
Interactive memory-backed chat REPL. Each turn: FTS5 recall from the memory store, send context + question to the LLM, display the answer.
|
|
379
|
+
|
|
380
|
+
**Stateless by default.** Each question sees only the memory store — no hidden conversation state.
|
|
381
|
+
|
|
382
|
+
| Flag | Default | Description |
|
|
383
|
+
|------|---------|-------------|
|
|
384
|
+
| `--llm CMD` | *(required)* | LLM command (e.g. `"claude -p"`, `"ollama run granite3.1:2b"`) |
|
|
385
|
+
| `--protocol` | `passive` | LLM output protocol. `passive` = single-pass; `json` = iterative refinement |
|
|
386
|
+
| `--max-calls` | `1` | Max loop iterations per turn |
|
|
387
|
+
| `--session` | off | Enable in-memory session context (sliding window of recent Q&A) |
|
|
388
|
+
| `--history-turns` | `5` | Session window size (turns) |
|
|
389
|
+
| `--session-budget` | `4000` | Session block character limit |
|
|
390
|
+
| `--store` | off | Persist each answer as STM item |
|
|
391
|
+
| `--source FILE...` | *(none)* | Pre-ingest files before starting |
|
|
392
|
+
| `--tags` | `chat` | Tags for stored items (comma-separated) |
|
|
393
|
+
|
|
394
|
+
**stdout purity:** answers go to stdout only. Prompt, banner, and hints go to stderr.
|
|
395
|
+
|
|
294
396
|
---
|
|
295
397
|
|
|
296
398
|
## Environment Variables
|
|
@@ -348,6 +450,18 @@ memctl search "" --json | jq -c '.[]'
|
|
|
348
450
|
|
|
349
451
|
# Iterative recall-answer loop with trace
|
|
350
452
|
memctl push "auth flow" --source docs/ | memctl loop "auth flow" --llm "claude -p" --trace
|
|
453
|
+
|
|
454
|
+
# One-liner: inspect a folder (auto-mount + auto-sync)
|
|
455
|
+
memctl inspect docs/
|
|
456
|
+
|
|
457
|
+
# Inspect in JSON, pipe to jq for extension breakdown
|
|
458
|
+
memctl inspect src/ --json | jq '.extensions'
|
|
459
|
+
|
|
460
|
+
# Inspect without syncing (use cached state)
|
|
461
|
+
memctl inspect docs/ --no-sync --json
|
|
462
|
+
|
|
463
|
+
# Interactive chat with pre-ingested docs
|
|
464
|
+
memctl chat --llm "claude -p" --source docs/ --session --store
|
|
351
465
|
```
|
|
352
466
|
|
|
353
467
|
---
|
|
@@ -402,14 +516,18 @@ Tool names use the `memory_*` prefix for drop-in compatibility with RAGIX.
|
|
|
402
516
|
```
|
|
403
517
|
memctl/
|
|
404
518
|
├── types.py Data model (MemoryItem, MemoryProposal, MemoryEvent, MemoryLink)
|
|
405
|
-
├── store.py SQLite + FTS5 + WAL backend (
|
|
519
|
+
├── store.py SQLite + FTS5 + WAL backend (10 tables + schema_meta)
|
|
406
520
|
├── extract.py Text extraction (text files + binary format dispatch)
|
|
407
521
|
├── ingest.py Paragraph chunking, SHA-256 dedup, source resolution
|
|
408
522
|
├── policy.py Write governance (30 patterns: secrets, injection, instructional)
|
|
409
523
|
├── config.py Dataclass configuration
|
|
410
524
|
├── similarity.py Stdlib text similarity (Jaccard + SequenceMatcher)
|
|
411
525
|
├── loop.py Bounded recall-answer loop controller
|
|
412
|
-
├──
|
|
526
|
+
├── mount.py Folder mount registration and management
|
|
527
|
+
├── sync.py Delta sync with 3-tier change detection
|
|
528
|
+
├── inspect.py Structural inspection and orchestration
|
|
529
|
+
├── chat.py Interactive memory-backed chat REPL
|
|
530
|
+
├── cli.py 13 CLI commands
|
|
413
531
|
├── consolidate.py Deterministic merge (Jaccard clustering, no LLM)
|
|
414
532
|
├── proposer.py LLM output parsing (delimiter + regex)
|
|
415
533
|
└── mcp/
|
|
@@ -418,7 +536,7 @@ memctl/
|
|
|
418
536
|
└── server.py FastMCP server entry point
|
|
419
537
|
```
|
|
420
538
|
|
|
421
|
-
|
|
539
|
+
20 source files. ~7,700 lines. Zero compiled dependencies for core.
|
|
422
540
|
|
|
423
541
|
### Memory Tiers
|
|
424
542
|
|
|
@@ -485,7 +603,7 @@ Deterministic, no-LLM merge pipeline:
|
|
|
485
603
|
|
|
486
604
|
## Database Schema
|
|
487
605
|
|
|
488
|
-
Single SQLite file with WAL mode.
|
|
606
|
+
Single SQLite file with WAL mode. 10 tables + 1 FTS5 virtual table:
|
|
489
607
|
|
|
490
608
|
| Table | Purpose |
|
|
491
609
|
|-------|---------|
|
|
@@ -494,13 +612,14 @@ Single SQLite file with WAL mode. 9 tables + 1 FTS5 virtual table:
|
|
|
494
612
|
| `memory_events` | Audit log (every read/write/consolidate) |
|
|
495
613
|
| `memory_links` | Directional relationships (supersedes, supports, etc.) |
|
|
496
614
|
| `memory_embeddings` | Reserved for RAGIX (empty in memctl) |
|
|
497
|
-
| `corpus_hashes` | SHA-256 file dedup
|
|
615
|
+
| `corpus_hashes` | SHA-256 file dedup + mount metadata (mount_id, rel_path, ext, size_bytes, mtime_epoch, lang_hint) |
|
|
498
616
|
| `corpus_metadata` | Corpus-level metadata |
|
|
499
617
|
| `schema_meta` | Schema version, creation info |
|
|
500
618
|
| `memory_palace_locations` | Reserved for RAGIX |
|
|
619
|
+
| `memory_mounts` | Registered folder mounts (path, name, ignore patterns, lang hint) |
|
|
501
620
|
| `memory_items_fts` | FTS5 virtual table for full-text search |
|
|
502
621
|
|
|
503
|
-
Schema version is tracked in `schema_meta`. Current: `SCHEMA_VERSION=
|
|
622
|
+
Schema version is tracked in `schema_meta`. Current: `SCHEMA_VERSION=2`. Migration from v1 is additive (ALTER TABLE ADD COLUMN) and idempotent.
|
|
504
623
|
|
|
505
624
|
---
|
|
506
625
|
|
|
@@ -518,10 +637,11 @@ ragix memory stats --db /path/to/your/.memory/memory.db
|
|
|
518
637
|
|
|
519
638
|
| Feature | memctl | RAGIX |
|
|
520
639
|
|---------|--------|-------|
|
|
521
|
-
| SQLite schema |
|
|
640
|
+
| SQLite schema | Forward-compatible (RAGIX can open memctl DBs) | Superset |
|
|
522
641
|
| Injection format | `format_version=1` | `format_version=1` |
|
|
523
642
|
| MCP tool names | `memory_*` | `memory_*` |
|
|
524
643
|
| FTS5 recall | Yes | Yes (+ hybrid embeddings) |
|
|
644
|
+
| Folder mount + sync | Yes (v0.3+) | No |
|
|
525
645
|
| Embeddings | No | Yes (FAISS + Ollama) |
|
|
526
646
|
| LLM-assisted merge | No | Yes |
|
|
527
647
|
| Graph-RAG | No | Yes |
|
|
@@ -575,7 +695,7 @@ pip install memctl[dev]
|
|
|
575
695
|
pytest tests/ -v
|
|
576
696
|
```
|
|
577
697
|
|
|
578
|
-
|
|
698
|
+
492 tests across 15 test files covering types, store, policy, ingest, text extraction, similarity, loop controller, mount, sync, inspect, chat, forward compatibility, contracts, CLI (subprocess), and pipe composition.
|
|
579
699
|
|
|
580
700
|
---
|
|
581
701
|
|
|
@@ -107,7 +107,34 @@ memctl search "authentication"
|
|
|
107
107
|
memctl search "database" --json -k 5
|
|
108
108
|
```
|
|
109
109
|
|
|
110
|
-
### 5. Inspect
|
|
110
|
+
### 5. Inspect a folder (one-liner)
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
# Auto-mounts, auto-syncs, and inspects — all in one command
|
|
114
|
+
memctl inspect docs/
|
|
115
|
+
|
|
116
|
+
# Same in JSON (for scripts)
|
|
117
|
+
memctl inspect docs/ --json
|
|
118
|
+
|
|
119
|
+
# Skip sync (use cached state)
|
|
120
|
+
memctl inspect docs/ --no-sync
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`inspect` auto-mounts the folder if needed, checks staleness, syncs only if stale, and produces a structural summary. All implicit actions are announced on stderr.
|
|
124
|
+
|
|
125
|
+
### 6. Chat with memory-backed context
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
# Interactive chat with any LLM
|
|
129
|
+
memctl chat --llm "claude -p" --session
|
|
130
|
+
|
|
131
|
+
# With pre-ingested files and answer storage
|
|
132
|
+
memctl chat --llm "ollama run granite3.1:2b" --source docs/ --store --session
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Each question recalls from the memory store, sends context + question to the LLM, and displays the answer. `--session` keeps a sliding window of recent Q&A pairs. `--store` persists answers as STM items.
|
|
136
|
+
|
|
137
|
+
### 7. Manage
|
|
111
138
|
|
|
112
139
|
```bash
|
|
113
140
|
memctl show MEM-abc123def456 # Show item details
|
|
@@ -137,6 +164,10 @@ memctl <command> [options]
|
|
|
137
164
|
| `stats` | Store statistics |
|
|
138
165
|
| `consolidate [--dry-run]` | Deterministic merge of similar STM items |
|
|
139
166
|
| `loop QUERY --llm CMD` | Bounded recall-answer loop with LLM |
|
|
167
|
+
| `mount PATH` | Register a folder as a structured source |
|
|
168
|
+
| `sync [PATH]` | Delta-sync mounted folders into the store |
|
|
169
|
+
| `inspect [PATH]` | Structural inspection with auto-mount and auto-sync |
|
|
170
|
+
| `chat --llm CMD` | Interactive memory-backed chat REPL |
|
|
140
171
|
| `serve` | Start MCP server (requires `memctl[mcp]`) |
|
|
141
172
|
|
|
142
173
|
### Global Flags
|
|
@@ -248,6 +279,77 @@ memctl push "database schema" --source src/ \
|
|
|
248
279
|
memctl loop --replay trace.jsonl "original question"
|
|
249
280
|
```
|
|
250
281
|
|
|
282
|
+
#### `memctl mount`
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
memctl mount PATH [--name NAME] [--ignore PATTERN ...] [--lang HINT]
|
|
286
|
+
memctl mount --list
|
|
287
|
+
memctl mount --remove ID_OR_NAME
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
Registers a folder as a structured source. Stores metadata only — no scanning, no ingestion. The folder contents are synced separately via `sync` or automatically via `inspect`.
|
|
291
|
+
|
|
292
|
+
#### `memctl sync`
|
|
293
|
+
|
|
294
|
+
```bash
|
|
295
|
+
memctl sync [PATH] [--full] [--json] [--quiet]
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Delta-syncs mounted folders into the memory store. Uses a 3-tier delta rule:
|
|
299
|
+
1. **New file** (not in DB) → ingest
|
|
300
|
+
2. **Size + mtime match** → fast skip (no hashing)
|
|
301
|
+
3. **Hash compare** → ingest only if content changed
|
|
302
|
+
|
|
303
|
+
If `PATH` is given but not yet mounted, it is auto-registered first. `--full` forces re-processing of all files.
|
|
304
|
+
|
|
305
|
+
#### `memctl inspect`
|
|
306
|
+
|
|
307
|
+
```bash
|
|
308
|
+
# Orchestration mode — auto-mounts, auto-syncs, and inspects
|
|
309
|
+
memctl inspect PATH [--sync auto|always|never] [--no-sync] [--mount-mode persist|ephemeral]
|
|
310
|
+
[--budget N] [--ignore PATTERN ...] [--json] [--quiet]
|
|
311
|
+
|
|
312
|
+
# Classic mode — inspect an existing mount by ID/name
|
|
313
|
+
memctl inspect --mount ID_OR_NAME [--budget N] [--json] [--quiet]
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
When given a positional `PATH`, inspect operates in **orchestration mode**:
|
|
317
|
+
1. **Auto-mount** — registers the folder if not already mounted
|
|
318
|
+
2. **Staleness check** — compares disk inventory (path/size/mtime triples) against the store
|
|
319
|
+
3. **Auto-sync** — runs delta sync only if stale (or always/never per `--sync`)
|
|
320
|
+
4. **Inspect** — generates a deterministic structural summary
|
|
321
|
+
|
|
322
|
+
Output includes file/chunk/size totals, per-folder breakdown, per-extension distribution, top-5 largest files, and rule-based observations. All paths in output are mount-relative (never absolute).
|
|
323
|
+
|
|
324
|
+
`--mount-mode ephemeral` removes the mount record after inspection (corpus data is preserved). `--no-sync` is shorthand for `--sync never`.
|
|
325
|
+
|
|
326
|
+
All implicit actions (mount, sync) are announced on stderr. `--quiet` suppresses them.
|
|
327
|
+
|
|
328
|
+
#### `memctl chat`
|
|
329
|
+
|
|
330
|
+
```bash
|
|
331
|
+
memctl chat --llm CMD [--session] [--store] [--protocol passive|json|regex]
|
|
332
|
+
[--max-calls N] [--budget N] [--source FILE ...] [--quiet]
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
Interactive memory-backed chat REPL. Each turn: FTS5 recall from the memory store, send context + question to the LLM, display the answer.
|
|
336
|
+
|
|
337
|
+
**Stateless by default.** Each question sees only the memory store — no hidden conversation state.
|
|
338
|
+
|
|
339
|
+
| Flag | Default | Description |
|
|
340
|
+
|------|---------|-------------|
|
|
341
|
+
| `--llm CMD` | *(required)* | LLM command (e.g. `"claude -p"`, `"ollama run granite3.1:2b"`) |
|
|
342
|
+
| `--protocol` | `passive` | LLM output protocol. `passive` = single-pass; `json` = iterative refinement |
|
|
343
|
+
| `--max-calls` | `1` | Max loop iterations per turn |
|
|
344
|
+
| `--session` | off | Enable in-memory session context (sliding window of recent Q&A) |
|
|
345
|
+
| `--history-turns` | `5` | Session window size (turns) |
|
|
346
|
+
| `--session-budget` | `4000` | Session block character limit |
|
|
347
|
+
| `--store` | off | Persist each answer as STM item |
|
|
348
|
+
| `--source FILE...` | *(none)* | Pre-ingest files before starting |
|
|
349
|
+
| `--tags` | `chat` | Tags for stored items (comma-separated) |
|
|
350
|
+
|
|
351
|
+
**stdout purity:** answers go to stdout only. Prompt, banner, and hints go to stderr.
|
|
352
|
+
|
|
251
353
|
---
|
|
252
354
|
|
|
253
355
|
## Environment Variables
|
|
@@ -305,6 +407,18 @@ memctl search "" --json | jq -c '.[]'
|
|
|
305
407
|
|
|
306
408
|
# Iterative recall-answer loop with trace
|
|
307
409
|
memctl push "auth flow" --source docs/ | memctl loop "auth flow" --llm "claude -p" --trace
|
|
410
|
+
|
|
411
|
+
# One-liner: inspect a folder (auto-mount + auto-sync)
|
|
412
|
+
memctl inspect docs/
|
|
413
|
+
|
|
414
|
+
# Inspect in JSON, pipe to jq for extension breakdown
|
|
415
|
+
memctl inspect src/ --json | jq '.extensions'
|
|
416
|
+
|
|
417
|
+
# Inspect without syncing (use cached state)
|
|
418
|
+
memctl inspect docs/ --no-sync --json
|
|
419
|
+
|
|
420
|
+
# Interactive chat with pre-ingested docs
|
|
421
|
+
memctl chat --llm "claude -p" --source docs/ --session --store
|
|
308
422
|
```
|
|
309
423
|
|
|
310
424
|
---
|
|
@@ -359,14 +473,18 @@ Tool names use the `memory_*` prefix for drop-in compatibility with RAGIX.
|
|
|
359
473
|
```
|
|
360
474
|
memctl/
|
|
361
475
|
├── types.py Data model (MemoryItem, MemoryProposal, MemoryEvent, MemoryLink)
|
|
362
|
-
├── store.py SQLite + FTS5 + WAL backend (
|
|
476
|
+
├── store.py SQLite + FTS5 + WAL backend (10 tables + schema_meta)
|
|
363
477
|
├── extract.py Text extraction (text files + binary format dispatch)
|
|
364
478
|
├── ingest.py Paragraph chunking, SHA-256 dedup, source resolution
|
|
365
479
|
├── policy.py Write governance (30 patterns: secrets, injection, instructional)
|
|
366
480
|
├── config.py Dataclass configuration
|
|
367
481
|
├── similarity.py Stdlib text similarity (Jaccard + SequenceMatcher)
|
|
368
482
|
├── loop.py Bounded recall-answer loop controller
|
|
369
|
-
├──
|
|
483
|
+
├── mount.py Folder mount registration and management
|
|
484
|
+
├── sync.py Delta sync with 3-tier change detection
|
|
485
|
+
├── inspect.py Structural inspection and orchestration
|
|
486
|
+
├── chat.py Interactive memory-backed chat REPL
|
|
487
|
+
├── cli.py 13 CLI commands
|
|
370
488
|
├── consolidate.py Deterministic merge (Jaccard clustering, no LLM)
|
|
371
489
|
├── proposer.py LLM output parsing (delimiter + regex)
|
|
372
490
|
└── mcp/
|
|
@@ -375,7 +493,7 @@ memctl/
|
|
|
375
493
|
└── server.py FastMCP server entry point
|
|
376
494
|
```
|
|
377
495
|
|
|
378
|
-
|
|
496
|
+
20 source files. ~7,700 lines. Zero compiled dependencies for core.
|
|
379
497
|
|
|
380
498
|
### Memory Tiers
|
|
381
499
|
|
|
@@ -442,7 +560,7 @@ Deterministic, no-LLM merge pipeline:
|
|
|
442
560
|
|
|
443
561
|
## Database Schema
|
|
444
562
|
|
|
445
|
-
Single SQLite file with WAL mode.
|
|
563
|
+
Single SQLite file with WAL mode. 10 tables + 1 FTS5 virtual table:
|
|
446
564
|
|
|
447
565
|
| Table | Purpose |
|
|
448
566
|
|-------|---------|
|
|
@@ -451,13 +569,14 @@ Single SQLite file with WAL mode. 9 tables + 1 FTS5 virtual table:
|
|
|
451
569
|
| `memory_events` | Audit log (every read/write/consolidate) |
|
|
452
570
|
| `memory_links` | Directional relationships (supersedes, supports, etc.) |
|
|
453
571
|
| `memory_embeddings` | Reserved for RAGIX (empty in memctl) |
|
|
454
|
-
| `corpus_hashes` | SHA-256 file dedup
|
|
572
|
+
| `corpus_hashes` | SHA-256 file dedup + mount metadata (mount_id, rel_path, ext, size_bytes, mtime_epoch, lang_hint) |
|
|
455
573
|
| `corpus_metadata` | Corpus-level metadata |
|
|
456
574
|
| `schema_meta` | Schema version, creation info |
|
|
457
575
|
| `memory_palace_locations` | Reserved for RAGIX |
|
|
576
|
+
| `memory_mounts` | Registered folder mounts (path, name, ignore patterns, lang hint) |
|
|
458
577
|
| `memory_items_fts` | FTS5 virtual table for full-text search |
|
|
459
578
|
|
|
460
|
-
Schema version is tracked in `schema_meta`. Current: `SCHEMA_VERSION=
|
|
579
|
+
Schema version is tracked in `schema_meta`. Current: `SCHEMA_VERSION=2`. Migration from v1 is additive (ALTER TABLE ADD COLUMN) and idempotent.
|
|
461
580
|
|
|
462
581
|
---
|
|
463
582
|
|
|
@@ -475,10 +594,11 @@ ragix memory stats --db /path/to/your/.memory/memory.db
|
|
|
475
594
|
|
|
476
595
|
| Feature | memctl | RAGIX |
|
|
477
596
|
|---------|--------|-------|
|
|
478
|
-
| SQLite schema |
|
|
597
|
+
| SQLite schema | Forward-compatible (RAGIX can open memctl DBs) | Superset |
|
|
479
598
|
| Injection format | `format_version=1` | `format_version=1` |
|
|
480
599
|
| MCP tool names | `memory_*` | `memory_*` |
|
|
481
600
|
| FTS5 recall | Yes | Yes (+ hybrid embeddings) |
|
|
601
|
+
| Folder mount + sync | Yes (v0.3+) | No |
|
|
482
602
|
| Embeddings | No | Yes (FAISS + Ollama) |
|
|
483
603
|
| LLM-assisted merge | No | Yes |
|
|
484
604
|
| Graph-RAG | No | Yes |
|
|
@@ -532,7 +652,7 @@ pip install memctl[dev]
|
|
|
532
652
|
pytest tests/ -v
|
|
533
653
|
```
|
|
534
654
|
|
|
535
|
-
|
|
655
|
+
492 tests across 15 test files covering types, store, policy, ingest, text extraction, similarity, loop controller, mount, sync, inspect, chat, forward compatibility, contracts, CLI (subprocess), and pipe composition.
|
|
536
656
|
|
|
537
657
|
---
|
|
538
658
|
|