memory-crystal 0.2.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/.env.example +20 -0
- package/CHANGELOG.md +6 -0
- package/LETTERS.md +22 -0
- package/LICENSE +21 -0
- package/README-ENTERPRISE.md +162 -0
- package/README-old.md +275 -0
- package/README.md +91 -0
- package/RELAY.md +88 -0
- package/TECHNICAL.md +379 -0
- package/ai/dev-updates/2026-02-25--cc-air--phase2-architecture-pivot.md +70 -0
- package/ai/dev-updates/2026-02-25--cc-air--phase2-worker-build.md +72 -0
- package/ai/dev-updates/2026-02-26--10-25-16--cc-mini--phase2-implementation.md +49 -0
- package/ai/dev-updates/2026-02-27--20-30-00--cc-mini--readme-overhaul-and-public-deploy.md +69 -0
- package/ai/notes/2026-02-26--cc-air--notes.md +412 -0
- package/ai/notes/2026-02-27--cc-mini--grok-feedback.md +44 -0
- package/ai/notes/2026-02-27--cc-mini--lesa-feedback.md +45 -0
- package/ai/notes/RESEARCH.md +1185 -0
- package/ai/notes/salience-research/README.md +29 -0
- package/ai/notes/salience-research/eurosla-salience-review.md +64 -0
- package/ai/notes/salience-research/full-research-summary.md +269 -0
- package/ai/notes/salience-research/salience-levels-diagram.png +0 -0
- package/ai/plan/2026-02-27--cc-mini--qr-pairing-spec.md +203 -0
- package/ai/plan/_archive/PLAN.md +194 -0
- package/ai/plan/_archive/PRD.md +1014 -0
- package/ai/plan/cc-plans-duplicates-from-dot-claude/2026-02-26--cc-mini--phase2-implementation-plan.md +245 -0
- package/ai/plan/dev-conventions-note.md +70 -0
- package/ai/plan/ldm-os-install-and-boot-architecture.md +285 -0
- package/ai/plan/memory-crystal-phase2-plan.md +192 -0
- package/ai/plan/memory-system-lay-of-the-land.md +214 -0
- package/ai/plan/phase2-ephemeral-relay.md +238 -0
- package/ai/plan/readme-first.md +68 -0
- package/ai/plan/roadmap.md +159 -0
- package/ai/todos/PUNCHLIST.md +44 -0
- package/ai/todos/README.md +31 -0
- package/ai/todos/inboxes/cc-air/2026-02-26--cc-air--post-relay-todos.md +85 -0
- package/ai/todos/inboxes/cc-mini/2026-02-26--cc-mini--phase2-status.md +100 -0
- package/ai/todos/inboxes/cc-mini/_archive/TODO.md +25 -0
- package/ai/todos/inboxes/parker/2026-02-25--cc-air--setup-checklist.md +139 -0
- package/ai/todos/inboxes/parker/2026-02-26--cc-mini--phase2-your-moves.md +72 -0
- package/dist/cc-hook.d.ts +1 -0
- package/dist/cc-hook.js +349 -0
- package/dist/chunk-3VFIJYS4.js +818 -0
- package/dist/chunk-52QE3YI3.js +1169 -0
- package/dist/chunk-AA3OPP4Z.js +432 -0
- package/dist/chunk-D3I3ZSE2.js +411 -0
- package/dist/chunk-EKSACBTJ.js +1070 -0
- package/dist/chunk-F3Y7EL7K.js +83 -0
- package/dist/chunk-JWZXYVET.js +1068 -0
- package/dist/chunk-KYVWO6ZM.js +1069 -0
- package/dist/chunk-L3VHARQH.js +413 -0
- package/dist/chunk-LOVAHSQV.js +411 -0
- package/dist/chunk-LQOYCAGG.js +446 -0
- package/dist/chunk-MK42FMEG.js +147 -0
- package/dist/chunk-NIJCVN3O.js +147 -0
- package/dist/chunk-O2UITJGH.js +465 -0
- package/dist/chunk-PEK6JH65.js +432 -0
- package/dist/chunk-PJ6FFKEX.js +77 -0
- package/dist/chunk-PLUBBZYR.js +800 -0
- package/dist/chunk-SGL6ISBJ.js +1061 -0
- package/dist/chunk-UNHVZB5G.js +411 -0
- package/dist/chunk-VAFTWSTE.js +1061 -0
- package/dist/chunk-XZ3S56RQ.js +1061 -0
- package/dist/chunk-Y72C7F6O.js +148 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +325 -0
- package/dist/core.d.ts +188 -0
- package/dist/core.js +12 -0
- package/dist/crypto.d.ts +16 -0
- package/dist/crypto.js +18 -0
- package/dist/dev-update-SZ2Z4WCQ.js +6 -0
- package/dist/ldm.d.ts +17 -0
- package/dist/ldm.js +12 -0
- package/dist/mcp-server.d.ts +1 -0
- package/dist/mcp-server.js +250 -0
- package/dist/migrate.d.ts +1 -0
- package/dist/migrate.js +89 -0
- package/dist/mirror-sync.d.ts +1 -0
- package/dist/mirror-sync.js +130 -0
- package/dist/openclaw.d.ts +5 -0
- package/dist/openclaw.js +349 -0
- package/dist/poller.d.ts +1 -0
- package/dist/poller.js +272 -0
- package/dist/summarize.d.ts +19 -0
- package/dist/summarize.js +10 -0
- package/dist/worker.js +137 -0
- package/openclaw.plugin.json +11 -0
- package/package.json +40 -0
- package/scripts/migrate-lance-to-sqlite.mjs +217 -0
- package/skills/memory/SKILL.md +61 -0
- package/src/cc-hook.ts +447 -0
- package/src/cli.ts +356 -0
- package/src/core.ts +1472 -0
- package/src/crypto.ts +113 -0
- package/src/dev-update.ts +178 -0
- package/src/ldm.ts +117 -0
- package/src/mcp-server.ts +274 -0
- package/src/migrate.ts +104 -0
- package/src/mirror-sync.ts +175 -0
- package/src/openclaw.ts +250 -0
- package/src/poller.ts +345 -0
- package/src/summarize.ts +210 -0
- package/src/worker.ts +208 -0
- package/tsconfig.json +18 -0
- package/wrangler.toml +20 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Memory Crystal: Sovereign Memory + Four-Door Architecture
|
|
2
|
+
|
|
3
|
+
## Context
|
|
4
|
+
|
|
5
|
+
**The problem:** Agents have fragmented memory (sessions isolated, compaction = amnesia, no remote access). And tools are siloed — OpenClaw plugins invisible to Claude Code, MCP servers invisible to OpenClaw, CLIs lack structure.
|
|
6
|
+
|
|
7
|
+
**Two existing plans converge here:**
|
|
8
|
+
1. **memory-crystal** (`repos/memory-crystal/PRD.md`) — sovereign local-first memory with LanceDB + SQLite, semantic search, knowledge graph
|
|
9
|
+
2. **refactor-plan** (`repos/refactor-plan.md`) — every tool gets four interfaces: core + CLI + MCP + plugin + skill
|
|
10
|
+
|
|
11
|
+
**Parker's cloud insight:** Mac mini = source of truth. Cloud (Cloudflare Worker) = ephemeral disposable mirror. Wiped daily, rebuilt from mini. Breach = instant delete, nothing lost.
|
|
12
|
+
|
|
13
|
+
**Peter Steinberger's philosophy (OpenClaw creator):** "Bot is really good at Unix." CLI is the universal interface. But also: OpenClaw plugins for Lēsa, MCP for Claude Code, skills to teach agents. One codebase, four doors.
|
|
14
|
+
|
|
15
|
+
## Architecture: Four Doors, One Core
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
memory-crystal/
|
|
19
|
+
├── src/
|
|
20
|
+
│ ├── core.ts ← Pure logic. Zero framework deps.
|
|
21
|
+
│ │ search(), remember(), forget(), sync()
|
|
22
|
+
│ │ Talks to local LanceDB/SQLite OR remote Worker API.
|
|
23
|
+
│ │
|
|
24
|
+
│ ├── cli.ts ← crystal search "query"
|
|
25
|
+
│ │ crystal search --remote "query"
|
|
26
|
+
│ │ crystal remember "Parker prefers Opus"
|
|
27
|
+
│ │ crystal push / crystal pull / crystal status
|
|
28
|
+
│ │
|
|
29
|
+
│ ├── mcp-server.ts ← crystal_search, crystal_remember, crystal_forget
|
|
30
|
+
│ │ For Claude Code via .mcp.json
|
|
31
|
+
│ │
|
|
32
|
+
│ ├── openclaw.ts ← api.registerTool() wrappers
|
|
33
|
+
│ │ For Lēsa via OpenClaw plugin system
|
|
34
|
+
│ │
|
|
35
|
+
│ └── worker.ts ← Cloudflare Worker (REST API)
|
|
36
|
+
│ POST /search, POST /remember, GET /health
|
|
37
|
+
│ Backed by D1 + Vectorize + R2
|
|
38
|
+
│
|
|
39
|
+
├── skills/
|
|
40
|
+
│ └── memory/SKILL.md ← Teaches agents when/how to use memory tools
|
|
41
|
+
│
|
|
42
|
+
├── openclaw.plugin.json ← Plugin manifest
|
|
43
|
+
├── wrangler.toml ← Cloudflare Worker config
|
|
44
|
+
└── package.json ← bin: { "crystal": "./dist/cli.js" }
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### How each consumer uses it
|
|
48
|
+
|
|
49
|
+
| Agent | Native Door | Also available |
|
|
50
|
+
|-------|------------|----------------|
|
|
51
|
+
| Lēsa (OpenClaw) | Plugin (openclaw.ts) + Skill | CLI via bash |
|
|
52
|
+
| Claude Code | MCP (mcp-server.ts) | CLI via Bash tool |
|
|
53
|
+
| Claude.ai (web) | Remote MCP (SSE transport) | — |
|
|
54
|
+
| ChatGPT / Grok / Gemini | CLI or direct HTTP to Worker | — |
|
|
55
|
+
| Any future agent | Whichever door it supports | — |
|
|
56
|
+
|
|
57
|
+
### Core design rules (from refactor-plan)
|
|
58
|
+
- Core has zero framework dependencies
|
|
59
|
+
- Core functions return plain TypeScript types, not MCP content arrays
|
|
60
|
+
- Config via function params, not framework globals
|
|
61
|
+
- Errors: core throws, wrappers catch and format
|
|
62
|
+
- `--remote` flag in core switches between local DB and Worker API
|
|
63
|
+
|
|
64
|
+
## Phase 1: Local Memory Crystal (Mac Mini) — COMPLETE ✅
|
|
65
|
+
|
|
66
|
+
Built 2026-02-09/10. All four doors live. Running alongside context-embeddings for verification.
|
|
67
|
+
|
|
68
|
+
### What's deployed
|
|
69
|
+
- **Vector DB:** LanceDB with cosine distance search
|
|
70
|
+
- **Metadata DB:** SQLite (knowledge graph, provenance, connector state)
|
|
71
|
+
- **Embedding:** OpenAI `text-embedding-3-small` (default), configurable to Ollama or Google
|
|
72
|
+
- **Chunking:** Paragraph/sentence-aware, 400 token target, 80 token overlap
|
|
73
|
+
- **Search:** Vector search with cosine similarity scoring (0-100%)
|
|
74
|
+
- **Data:** 5,502 chunks migrated from context-embeddings.sqlite (0 failures)
|
|
75
|
+
|
|
76
|
+
### What was built
|
|
77
|
+
1. ✅ **core.ts** — Crystal class: init, embed, chunkText, ingest, search, remember, forget, status, captureState
|
|
78
|
+
2. ✅ **Migration** — imported 5,502 chunks from context-embeddings.sqlite into LanceDB (re-embedded with OpenAI)
|
|
79
|
+
3. ✅ **cli.ts** — `crystal search`, `crystal remember`, `crystal forget`, `crystal status` with `--provider` flag
|
|
80
|
+
4. ✅ **openclaw.ts** — plugin wrapping core, `agent_end` hook for continuous ingestion
|
|
81
|
+
5. ✅ **mcp-server.ts** — MCP tools: crystal_search, crystal_remember, crystal_forget, crystal_status
|
|
82
|
+
6. ✅ **skills/memory/SKILL.md** — documents all tools and CLI commands
|
|
83
|
+
|
|
84
|
+
### Deployed to
|
|
85
|
+
- ✅ `~/.openclaw/.mcp.json` — memory-crystal MCP server registered
|
|
86
|
+
- ✅ `~/.openclaw/extensions/memory-crystal/` — OpenClaw plugin deployed, gateway loads successfully
|
|
87
|
+
- ✅ `~/.openclaw/openclaw.json` — plugin entry added
|
|
88
|
+
- ⏳ `repos/lesa-bridge/src/index.ts` — conversation_search/memory_search NOT yet removed (running in parallel)
|
|
89
|
+
|
|
90
|
+
### Embedding providers (configurable)
|
|
91
|
+
| Provider | Model | Dimensions | Cost | Set via |
|
|
92
|
+
|----------|-------|-----------|------|---------|
|
|
93
|
+
| OpenAI (default) | text-embedding-3-small | 1536 | paid | `CRYSTAL_EMBEDDING_PROVIDER=openai` |
|
|
94
|
+
| Ollama (local) | nomic-embed-text | 768 | free | `CRYSTAL_EMBEDDING_PROVIDER=ollama` |
|
|
95
|
+
| Google | text-embedding-004 | 768 | paid | `CRYSTAL_EMBEDDING_PROVIDER=google` |
|
|
96
|
+
|
|
97
|
+
### Still to do (Phase 1 cleanup)
|
|
98
|
+
- [ ] Verify agent_end hook captures new turns (check chunk count after Lēsa conversations)
|
|
99
|
+
- [ ] Install CLI globally (`npm link`)
|
|
100
|
+
- [ ] Disable context-embeddings once memory-crystal proven stable (~few days)
|
|
101
|
+
- [ ] Remove lesa-bridge conversation_search/memory_search tools
|
|
102
|
+
|
|
103
|
+
## Phase 2: Cloudflare Worker Mirror
|
|
104
|
+
|
|
105
|
+
Ephemeral cloud mirror. Wiped daily, rebuilt from mini.
|
|
106
|
+
|
|
107
|
+
### Architecture
|
|
108
|
+
```
|
|
109
|
+
Mac Mini (source of truth) Cloudflare (ephemeral mirror)
|
|
110
|
+
┌──────────────────────┐ ┌─────────────────────────┐
|
|
111
|
+
│ memory-crystal │ push │ Worker (REST API) │
|
|
112
|
+
│ ├── LanceDB (local) │ ────────► │ ├── D1 (SQLite) │
|
|
113
|
+
│ ├── SQLite (local) │ │ ├── Vectorize (vectors) │
|
|
114
|
+
│ └── sync-state.json │ ◄──────── │ └── R2 (DB snapshot) │
|
|
115
|
+
└──────────────────────┘ pull └─────────────────────────┘
|
|
116
|
+
▲
|
|
117
|
+
Any remote agent
|
|
118
|
+
(CLI / MCP / HTTP)
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Daily cycle
|
|
122
|
+
1. **04:00** — Mini exports DB snapshot → R2 bucket
|
|
123
|
+
2. **04:05** — Worker rebuilds D1 + Vectorize from snapshot
|
|
124
|
+
3. **All day** — Remote agents read/write via Worker
|
|
125
|
+
4. **Every 4-6h** — Mini pulls new remote writes
|
|
126
|
+
5. **Next 04:00** — Wipe, re-upload. Repeat.
|
|
127
|
+
|
|
128
|
+
### Security model
|
|
129
|
+
- Worker auth: bearer token per agent
|
|
130
|
+
- Mini → Worker: HTTPS only
|
|
131
|
+
- Worker → Mini: NEVER (mini pulls, Worker never pushes)
|
|
132
|
+
- R2: private, Worker-binding only
|
|
133
|
+
- **Breach protocol:** `wrangler delete` — everything gone in seconds. Mini untouched.
|
|
134
|
+
|
|
135
|
+
### Why Cloudflare Workers (not VPS)
|
|
136
|
+
- Ephemeral by design — no persistent state to defend
|
|
137
|
+
- No server to maintain (no SSH, no OS, no patches)
|
|
138
|
+
- D1 = managed SQLite on edge
|
|
139
|
+
- Vectorize = managed vector search
|
|
140
|
+
- R2 = blob storage for snapshots
|
|
141
|
+
- Free tier covers it: 100K req/day, 5M rows D1, 5M vectors, 10GB R2
|
|
142
|
+
|
|
143
|
+
### Build order
|
|
144
|
+
1. **worker.ts** — REST endpoints: `/search`, `/remember`, `/health`, `/sync`
|
|
145
|
+
2. **wrangler.toml** — D1 binding, Vectorize binding, R2 bucket, secrets
|
|
146
|
+
3. **core.ts update** — add remote mode (HTTP calls to Worker when `--remote`)
|
|
147
|
+
4. **Sync script** — `crystal push` / `crystal pull` / `crystal reset`
|
|
148
|
+
5. **Cron on mini** — daily upload + periodic pull
|
|
149
|
+
|
|
150
|
+
### Parker does
|
|
151
|
+
- Cloudflare account (if needed)
|
|
152
|
+
- `wrangler login`
|
|
153
|
+
- Set Worker secrets (agent tokens)
|
|
154
|
+
|
|
155
|
+
## Phase 3: Multi-Agent Access
|
|
156
|
+
|
|
157
|
+
Any agent anywhere connects via its native door.
|
|
158
|
+
|
|
159
|
+
### Remote MCP server (for Claude.ai web, remote Claude Code)
|
|
160
|
+
- Thin MCP server wrapping Worker HTTP calls
|
|
161
|
+
- Embeds locally before pushing (Ollama or OpenAI)
|
|
162
|
+
- Config: Worker URL + agent token
|
|
163
|
+
|
|
164
|
+
### GPT Action (for ChatGPT)
|
|
165
|
+
- OpenAPI spec pointing at Worker REST endpoints
|
|
166
|
+
- Zero additional code — just a schema file
|
|
167
|
+
|
|
168
|
+
### CLI (universal)
|
|
169
|
+
- `crystal search --remote "query"` hits Worker
|
|
170
|
+
- Any agent with shell access can use it
|
|
171
|
+
- `npm install -g memory-crystal` for remote machines
|
|
172
|
+
|
|
173
|
+
## Verification
|
|
174
|
+
|
|
175
|
+
### Phase 1 (verified)
|
|
176
|
+
- [x] `crystal search "OpenAI API key"` returns relevant results with proper scoring
|
|
177
|
+
- [x] All four doors work: CLI, MCP, plugin, skill
|
|
178
|
+
- [x] `openclaw gateway restart` — no errors (plugin loads)
|
|
179
|
+
- [x] Original context-embeddings.sqlite preserved (41MB, untouched)
|
|
180
|
+
- [x] Search scores positive and sensible (cosine distance, 0-100%)
|
|
181
|
+
- [ ] Verify agent_end hook ingests new conversation turns
|
|
182
|
+
- [ ] Ollama provider tested (`crystal search --provider ollama`)
|
|
183
|
+
|
|
184
|
+
### Phase 2 (not started)
|
|
185
|
+
- [ ] `crystal search --remote` hits Worker and returns results
|
|
186
|
+
- [ ] Remote agent pushes chunk → mini pulls it within sync window
|
|
187
|
+
- [ ] `wrangler delete` nukes cloud — mini data intact
|
|
188
|
+
- [ ] Daily reset cycle works end-to-end
|
|
189
|
+
|
|
190
|
+
## Risk
|
|
191
|
+
|
|
192
|
+
- **LanceDB maturity** — newer than SQLite. Mitigation: context-embeddings running in parallel as fallback
|
|
193
|
+
- **Dual embedding cost** — both plugins embed every turn until context-embeddings disabled. Temporary.
|
|
194
|
+
- **Plugin API compatibility** — OpenClaw plugin format required: object export with `register()` method, `api.on()` for hooks, `api.registerTool()` with `execute` method, `configSchema` in manifest
|