engrm 0.1.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/.mcp.json +9 -0
- package/AUTH-DESIGN.md +436 -0
- package/BRIEF.md +197 -0
- package/CLAUDE.md +44 -0
- package/COMPETITIVE.md +174 -0
- package/CONTEXT-OPTIMIZATION.md +305 -0
- package/INFRASTRUCTURE.md +252 -0
- package/LICENSE +105 -0
- package/MARKET.md +230 -0
- package/PLAN.md +278 -0
- package/README.md +121 -0
- package/SENTINEL.md +293 -0
- package/SERVER-API-PLAN.md +553 -0
- package/SPEC.md +843 -0
- package/SWOT.md +148 -0
- package/SYNC-ARCHITECTURE.md +294 -0
- package/VIBE-CODER-STRATEGY.md +250 -0
- package/bun.lock +375 -0
- package/hooks/post-tool-use.ts +144 -0
- package/hooks/session-start.ts +64 -0
- package/hooks/stop.ts +131 -0
- package/mem-page.html +1305 -0
- package/package.json +30 -0
- package/src/capture/dedup.test.ts +103 -0
- package/src/capture/dedup.ts +76 -0
- package/src/capture/extractor.test.ts +245 -0
- package/src/capture/extractor.ts +330 -0
- package/src/capture/quality.test.ts +168 -0
- package/src/capture/quality.ts +104 -0
- package/src/capture/retrospective.test.ts +115 -0
- package/src/capture/retrospective.ts +121 -0
- package/src/capture/scanner.test.ts +131 -0
- package/src/capture/scanner.ts +100 -0
- package/src/capture/scrubber.test.ts +144 -0
- package/src/capture/scrubber.ts +181 -0
- package/src/cli.ts +517 -0
- package/src/config.ts +238 -0
- package/src/context/inject.test.ts +940 -0
- package/src/context/inject.ts +382 -0
- package/src/embeddings/backfill.ts +50 -0
- package/src/embeddings/embedder.test.ts +76 -0
- package/src/embeddings/embedder.ts +139 -0
- package/src/lifecycle/aging.test.ts +103 -0
- package/src/lifecycle/aging.ts +36 -0
- package/src/lifecycle/compaction.test.ts +264 -0
- package/src/lifecycle/compaction.ts +190 -0
- package/src/lifecycle/purge.test.ts +100 -0
- package/src/lifecycle/purge.ts +37 -0
- package/src/lifecycle/scheduler.test.ts +120 -0
- package/src/lifecycle/scheduler.ts +101 -0
- package/src/provisioning/browser-auth.ts +172 -0
- package/src/provisioning/provision.test.ts +198 -0
- package/src/provisioning/provision.ts +94 -0
- package/src/register.test.ts +167 -0
- package/src/register.ts +178 -0
- package/src/server.ts +436 -0
- package/src/storage/migrations.test.ts +244 -0
- package/src/storage/migrations.ts +261 -0
- package/src/storage/outbox.test.ts +229 -0
- package/src/storage/outbox.ts +131 -0
- package/src/storage/projects.test.ts +137 -0
- package/src/storage/projects.ts +184 -0
- package/src/storage/sqlite.test.ts +798 -0
- package/src/storage/sqlite.ts +934 -0
- package/src/storage/vec.test.ts +198 -0
- package/src/sync/auth.test.ts +76 -0
- package/src/sync/auth.ts +68 -0
- package/src/sync/client.ts +183 -0
- package/src/sync/engine.test.ts +94 -0
- package/src/sync/engine.ts +127 -0
- package/src/sync/pull.test.ts +279 -0
- package/src/sync/pull.ts +170 -0
- package/src/sync/push.test.ts +117 -0
- package/src/sync/push.ts +230 -0
- package/src/tools/get.ts +34 -0
- package/src/tools/pin.ts +47 -0
- package/src/tools/save.test.ts +301 -0
- package/src/tools/save.ts +231 -0
- package/src/tools/search.test.ts +69 -0
- package/src/tools/search.ts +181 -0
- package/src/tools/timeline.ts +64 -0
- package/tsconfig.json +22 -0
package/PLAN.md
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
# Implementation Plan — Engrm
|
|
2
|
+
|
|
3
|
+
## Approach
|
|
4
|
+
|
|
5
|
+
**Internal tooling first.** We're building this so our dev team can share project context across machines and developers. The public product comes later — first it needs to work for us.
|
|
6
|
+
|
|
7
|
+
Built from scratch. claude-mem is a reference for how to hook into Claude Code (hooks, MCP registration, observation capture patterns) but no code is shared. This avoids AGPL licensing issues and lets us design the architecture around cross-device team memory from the start.
|
|
8
|
+
|
|
9
|
+
## Component Architecture
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
engrm/
|
|
13
|
+
├── src/
|
|
14
|
+
│ ├── server.ts # MCP protocol handler (entry point)
|
|
15
|
+
│ ├── tools/ # MCP tool implementations
|
|
16
|
+
│ │ ├── search.ts # search() — hybrid local + remote, project-scoped
|
|
17
|
+
│ │ ├── timeline.ts # timeline() — chronological context
|
|
18
|
+
│ │ ├── get.ts # get_observations() — fetch by ID
|
|
19
|
+
│ │ ├── save.ts # save_observation() — manual save with quality scoring
|
|
20
|
+
│ │ └── pin.ts # pin_observation() — prevent aging
|
|
21
|
+
│ ├── capture/ # Observation extraction
|
|
22
|
+
│ │ ├── extractor.ts # Extract observations from tool use
|
|
23
|
+
│ │ ├── scrubber.ts # Secret/PII scrubbing
|
|
24
|
+
│ │ ├── quality.ts # Quality scoring (0.0-1.0)
|
|
25
|
+
│ │ └── dedup.ts # Near-duplicate detection (title similarity)
|
|
26
|
+
│ ├── storage/ # Local storage layer
|
|
27
|
+
│ │ ├── sqlite.ts # SQLite database (source of truth)
|
|
28
|
+
│ │ ├── migrations.ts # Schema migrations
|
|
29
|
+
│ │ ├── outbox.ts # Sync outbox queue
|
|
30
|
+
│ │ └── projects.ts # Project identity (git remote → canonical ID)
|
|
31
|
+
│ ├── lifecycle/ # Observation lifecycle management
|
|
32
|
+
│ │ ├── aging.ts # Daily: active → aging after 30 days
|
|
33
|
+
│ │ ├── compaction.ts # Weekly: aging → archived, generate digests
|
|
34
|
+
│ │ └── purge.ts # Monthly: delete archived > 12 months
|
|
35
|
+
│ ├── sync/ # Remote sync layer
|
|
36
|
+
│ │ ├── client.ts # Candengo Vector REST client
|
|
37
|
+
│ │ └── engine.ts # Sync engine (outbox flush, backfill, archival cleanup)
|
|
38
|
+
│ ├── context/ # Context injection
|
|
39
|
+
│ │ └── inject.ts # Session start context builder
|
|
40
|
+
│ └── config.ts # Configuration management
|
|
41
|
+
│
|
|
42
|
+
├── hooks/ # Claude Code hooks
|
|
43
|
+
│ ├── post-tool-use.sh # Observation capture
|
|
44
|
+
│ └── stop.sh # Session summary + sync flush
|
|
45
|
+
│
|
|
46
|
+
├── package.json
|
|
47
|
+
├── tsconfig.json
|
|
48
|
+
├── BRIEF.md
|
|
49
|
+
├── SPEC.md
|
|
50
|
+
├── PLAN.md # This file
|
|
51
|
+
└── CLAUDE.md
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Phase 1: Local MCP Server + Provisioning (Weeks 1-2)
|
|
57
|
+
|
|
58
|
+
**Goal**: Working MCP server with local SQLite storage, and a self-service provisioning flow so any developer can go from zero to working memory in under 2 minutes.
|
|
59
|
+
|
|
60
|
+
### 1.1 MCP Server Core
|
|
61
|
+
|
|
62
|
+
| Task | Description | Effort |
|
|
63
|
+
|---|---|---|
|
|
64
|
+
| Project scaffolding | TypeScript + Bun, MCP SDK, bun:sqlite | S |
|
|
65
|
+
| SQLite schema + migrations | projects, observations, sessions, sync_outbox tables (see SPEC §1-2) | M |
|
|
66
|
+
| Project identity detection | Auto-detect canonical project ID from git remote URL, normalise, store in projects table | M |
|
|
67
|
+
| MCP tool: `save_observation` | Save to local SQLite with project FK, quality score, add to sync outbox | S |
|
|
68
|
+
| MCP tool: `search` | Local SQLite FTS5 search, project-scoped by default, quality-weighted ranking | M |
|
|
69
|
+
| MCP tool: `get_observations` | Fetch by IDs from local SQLite | S |
|
|
70
|
+
| MCP tool: `timeline` | Chronological context around an observation | M |
|
|
71
|
+
| MCP tool: `pin_observation` | Pin/unpin observations to prevent aging | XS |
|
|
72
|
+
| Quality scoring | Score observations at capture time (0.0-1.0) based on type, content signals (see SPEC §2) | M |
|
|
73
|
+
| Secret scrubber | Regex-based scrubbing of API keys, passwords, tokens before storage | M |
|
|
74
|
+
| Relative file paths | Store file paths relative to project root, resolve at capture time | S |
|
|
75
|
+
| Configuration | `~/.engrm/settings.json` — local paths, remote config | S |
|
|
76
|
+
|
|
77
|
+
### 1.2 Self-Provisioning
|
|
78
|
+
|
|
79
|
+
| Task | Description | Effort |
|
|
80
|
+
|---|---|---|
|
|
81
|
+
| Engrm landing page | `www.engrm.dev` — product page + signup + install instructions | M |
|
|
82
|
+
| Account provisioning backend | Signup → create mem_accounts row, namespace, provision token | M |
|
|
83
|
+
| Provision API endpoint | `POST /v1/mem/provision` — exchange token for permanent credentials | S |
|
|
84
|
+
| `npx engrm init` | CLI command: redeem token, write settings, register MCP + hooks in Claude Code | M |
|
|
85
|
+
| Team invite flow | Admin creates team → invite URL → member joins with team namespace pre-configured | M |
|
|
86
|
+
| Self-hosted init path | `--url` flag for custom endpoints, `--manual` for air-gapped environments | S |
|
|
87
|
+
|
|
88
|
+
### 1.3 Provisioning Flow
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
1. Developer visits www.engrm.dev
|
|
92
|
+
2. Signs up (email or GitHub OAuth)
|
|
93
|
+
3. Backend provisions account + namespace
|
|
94
|
+
4. Page shows personalised install command:
|
|
95
|
+
npx engrm init --token=cmt_abc123...
|
|
96
|
+
5. Developer runs command in terminal
|
|
97
|
+
6. Plugin exchanges token → gets API key, endpoint, namespace
|
|
98
|
+
7. Plugin writes settings.json, registers MCP server + hooks in Claude Code
|
|
99
|
+
8. Next Claude Code session has memory
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
For teams: admin creates team at `www.engrm.dev/team`, shares invite link, team members get pre-configured for the shared namespace.
|
|
103
|
+
|
|
104
|
+
**Deliverable**: A working MCP server that Claude Code can call, with self-service provisioning from candengo.com. Any developer can sign up and be running in under 2 minutes.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Phase 2: Claude Code Hooks (Week 3)
|
|
109
|
+
|
|
110
|
+
**Goal**: Automatic observation capture from Claude Code sessions.
|
|
111
|
+
|
|
112
|
+
| Task | Description | Effort |
|
|
113
|
+
|---|---|---|
|
|
114
|
+
| PostToolUse hook | Shell script that extracts observations from tool results | L |
|
|
115
|
+
| Stop hook | Session summary generation, sync flush | M |
|
|
116
|
+
| MCP server registration | `.mcp.json` config for Claude Code | XS |
|
|
117
|
+
| Hooks registration | `hooks.json` for Claude Code | XS |
|
|
118
|
+
| Context injection | Inject relevant history on session start (via MCP tool call) | M |
|
|
119
|
+
| Observation quality filtering | Skip trivial tool uses (ls, cat of small files), focus on meaningful work | M |
|
|
120
|
+
|
|
121
|
+
**Deliverable**: Claude Code automatically captures observations as you work. Session summaries on exit. Relevant history injected on start.
|
|
122
|
+
|
|
123
|
+
### Observation Extraction Design
|
|
124
|
+
|
|
125
|
+
This is the hardest problem. What makes a good observation?
|
|
126
|
+
|
|
127
|
+
**Capture triggers** (PostToolUse):
|
|
128
|
+
- File edits → what changed and why
|
|
129
|
+
- Command execution with errors → what failed and how it was fixed
|
|
130
|
+
- Multiple file reads in sequence → likely investigating something
|
|
131
|
+
- Test runs → pass/fail context
|
|
132
|
+
|
|
133
|
+
**Skip** (low signal):
|
|
134
|
+
- Simple file reads (single `cat`)
|
|
135
|
+
- `ls`, `pwd`, `git status` and similar navigation
|
|
136
|
+
- Repeated identical tool calls
|
|
137
|
+
|
|
138
|
+
**Extraction approach**: The hook sends the tool name + result summary to the MCP server. The server decides whether it's worth capturing based on the tool type and content. Quality score is assigned at capture time. Observations are batched per-session and deduplicated (title similarity > 0.8 against last 24h → merge into existing).
|
|
139
|
+
|
|
140
|
+
### Observation Lifecycle + Deduplication
|
|
141
|
+
|
|
142
|
+
| Task | Description | Effort |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| Deduplication on save | Check title similarity against last 24h for same project, merge if > 0.8 | M |
|
|
145
|
+
| Aging job | Daily: move active observations older than 30 days to aging (0.7x search weight) | S |
|
|
146
|
+
| Archival + compaction | Weekly: observations > 90 days grouped by session, summarised into digest | L |
|
|
147
|
+
| Purge job | Monthly: delete archived observations > 12 months (keep digests + pinned) | S |
|
|
148
|
+
| FTS5 index maintenance | Remove archived observations from FTS5 index during compaction | S |
|
|
149
|
+
| Quota check | Count active+aging observations for free tier enforcement | S |
|
|
150
|
+
|
|
151
|
+
**Why this matters now**: Without lifecycle management, a developer generating ~100 observations/day hits 10K in ~3 months. Search results degrade as old, irrelevant observations pollute rankings. Compaction turns 25 old observations from a debugging session into one useful digest. Aging reduces the weight of stale knowledge. The free tier stays usable because only active+aging observations count toward the 10K limit — compacted observations are free.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Phase 3: Cross-Device Sync + Team Memory (Weeks 4-6)
|
|
156
|
+
|
|
157
|
+
**Goal**: Offline-first sync to Candengo Vector with team support from day one. Work on laptop, continue on desktop. Other developers' observations are searchable too.
|
|
158
|
+
|
|
159
|
+
Team memory isn't a separate phase — it's the reason we're building this. User identity, attribution, and shared namespaces are built into the sync layer from the start.
|
|
160
|
+
|
|
161
|
+
### 3.1 Candengo Vector API Prep
|
|
162
|
+
|
|
163
|
+
| Task | Description | Effort |
|
|
164
|
+
|---|---|---|
|
|
165
|
+
| Metadata filtering on search API | `metadata_filters` param on `/v1/search` — filter by `project_canonical`, `user_id`, etc. | S |
|
|
166
|
+
| Document listing by source_type | `GET /v1/documents?source_type=X` with pagination | S |
|
|
167
|
+
| Document deletion by source_id | `DELETE /v1/documents/{source_id}` — needed for archival/compaction cleanup | S |
|
|
168
|
+
| Device/user ID tracking in metadata | Accept `device_id`, `user_id` in metadata | XS |
|
|
169
|
+
|
|
170
|
+
### 3.2 Sync Engine
|
|
171
|
+
|
|
172
|
+
| Task | Description | Effort |
|
|
173
|
+
|---|---|---|
|
|
174
|
+
| Candengo Vector REST client | TypeScript HTTP client for `/v1/ingest`, `/v1/search`, `/v1/ingest/batch`, `/v1/documents/{id}` | M |
|
|
175
|
+
| Fire-and-forget sync | On observation save → attempt immediate push | S |
|
|
176
|
+
| Background sync timer | Every 30s → flush pending outbox items (batch of 50) | S |
|
|
177
|
+
| Startup backfill | On boot → sync observations saved while offline (high-water-mark) | M |
|
|
178
|
+
| Connectivity detection | Skip sync when offline, resume when connected | S |
|
|
179
|
+
| Retry with exponential backoff | Failed syncs retry 30s, 60s, 120s, max 5min | S |
|
|
180
|
+
| Observation → Candengo mapping | Map to ingest format with `project_canonical` in metadata, source_id = `{user}-{device}-obs-{id}` | M |
|
|
181
|
+
| Archival sync | When compaction runs: delete archived source_ids from Vector, ingest digest | M |
|
|
182
|
+
|
|
183
|
+
### 3.3 Team + Hybrid Search
|
|
184
|
+
|
|
185
|
+
| Task | Description | Effort |
|
|
186
|
+
|---|---|---|
|
|
187
|
+
| Hybrid search orchestrator | Query local FTS5 + Candengo `/v1/search` in parallel, scoped by `project_canonical` | M |
|
|
188
|
+
| Result merging + deduplication | Merge by source_id, weighted scoring (semantic × quality × lifecycle) | M |
|
|
189
|
+
| Graceful degradation | Candengo unreachable → local-only search (transparent) | S |
|
|
190
|
+
| Device ID generation | Auto-generate stable device ID on first run | XS |
|
|
191
|
+
| User identity + attribution | `user_id` in all observations, "david/laptop" in results | S |
|
|
192
|
+
| Source ID namespacing | `{user_id}-{device_id}-obs-{local_id}` prevents all collisions | S |
|
|
193
|
+
| Visibility controls | `shared` / `personal` / `secret` flags | M |
|
|
194
|
+
| Team search scope | Search own + team observations by default, filtered by `project_canonical` | M |
|
|
195
|
+
| Cross-project search | Support `project: "*"` to search across all projects | S |
|
|
196
|
+
|
|
197
|
+
**Deliverable**: Full cross-device team sync. Observations from any team member appear on any device within 30 seconds. Works offline, syncs when reconnected. Projects are matched across machines by git remote URL. New developer installs, connects to the shared namespace, and their agent has the full team knowledge base.
|
|
198
|
+
|
|
199
|
+
### Backfill Strategy
|
|
200
|
+
|
|
201
|
+
Instead of diffing all IDs on every startup (expensive at scale), use a high-water-mark:
|
|
202
|
+
|
|
203
|
+
```
|
|
204
|
+
1. Store last_synced_epoch locally
|
|
205
|
+
2. On startup: SELECT * FROM observations WHERE created_at_epoch > last_synced_epoch
|
|
206
|
+
3. Batch push missing observations
|
|
207
|
+
4. Update last_synced_epoch
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Simple, efficient, scales to any observation count.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Phase 4: Dogfood (Weeks 7-8)
|
|
215
|
+
|
|
216
|
+
**Goal**: Run it internally on our projects (Candengo, Alchemy, AIMY). Fix what hurts.
|
|
217
|
+
|
|
218
|
+
| Task | Description | Effort |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| Team onboarding | Install on all dev machines, shared Candengo Vector namespace | S |
|
|
221
|
+
| Observation quality tuning | Adjust capture filters based on real usage — too noisy? too quiet? | M |
|
|
222
|
+
| Search relevance tuning | Adjust scoring weights based on real queries | M |
|
|
223
|
+
| Bug fixes from dogfooding | Whatever breaks | M |
|
|
224
|
+
| Automated testing | Unit tests, sync integration tests | L |
|
|
225
|
+
| Performance benchmarking | <50ms local search, <200ms remote search | M |
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Phase 5: Public Launch (Weeks 9-10)
|
|
230
|
+
|
|
231
|
+
| Task | Description | Effort |
|
|
232
|
+
|---|---|---|
|
|
233
|
+
| One-line installer | `npx engrm install` or similar | M |
|
|
234
|
+
| CLI tool | `engrm status`, `search`, `sync` commands | M |
|
|
235
|
+
| Documentation | Installation, configuration, usage guide | M |
|
|
236
|
+
| GitHub repo (FSL-1.1-ALv2 license) | README, examples, contributing guide, LICENSE file | M |
|
|
237
|
+
| Free tier limits enforcement | Observation count, device count checks against account tier | M |
|
|
238
|
+
| Upgrade flow | In-plugin nudge when approaching limits, link to engrm.dev/upgrade | S |
|
|
239
|
+
|
|
240
|
+
**Licensing**: Core client released under FSL-1.1-ALv2 (Functional Source License, Fair Source). Source-available — developers can read, modify, and self-host freely. The restriction: nobody can fork it and offer a competing hosted service. Each version converts to Apache 2.0 after 2 years. Sentinel (real-time AI audit) is proprietary, delivered from a separate private repo to paying customers only.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## Effort Key
|
|
245
|
+
|
|
246
|
+
| Size | Estimated Effort | Description |
|
|
247
|
+
|---|---|---|
|
|
248
|
+
| XS | < 2 hours | Trivial change, config, or wrapper |
|
|
249
|
+
| S | 2-4 hours | Straightforward implementation |
|
|
250
|
+
| M | 4-8 hours | Moderate complexity, some design decisions |
|
|
251
|
+
| L | 1-2 days | Significant feature, requires careful design |
|
|
252
|
+
|
|
253
|
+
---
|
|
254
|
+
|
|
255
|
+
## Dependencies & Critical Path
|
|
256
|
+
|
|
257
|
+
```
|
|
258
|
+
Phase 1 (Local MCP) ──→ Phase 2 (Hooks) ──→ Phase 3 (Sync + Team) ──→ Phase 4 (Dogfood) ──→ Phase 5 (Launch)
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Phase 1+2 are usable standalone** — local-only memory is already valuable.
|
|
262
|
+
**Phase 3 is the whole point** — cross-device team sync is why we're building this.
|
|
263
|
+
**Phase 4 is essential** — dogfooding on our own projects before releasing externally.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
## Risk Register
|
|
268
|
+
|
|
269
|
+
| Risk | Impact | Likelihood | Mitigation |
|
|
270
|
+
|---|---|---|---|
|
|
271
|
+
| Observation quality too noisy | High | Medium | Quality scoring (0.0-1.0), skip below 0.1, deduplication on save, compaction at 90 days |
|
|
272
|
+
| Observation volume exceeds quota | Medium | High | Lifecycle management: aging → archival → purge. Compaction summarises old sessions into digests. Only active+aging counts toward quota |
|
|
273
|
+
| Project identity mismatch across machines | High | Medium | Canonical ID from normalised git remote URL. Fallback: `.engrm.json` in project root |
|
|
274
|
+
| Search relevance degrades over time | High | Medium | Quality-weighted ranking, lifecycle scoring (aging=0.7x), project scoping, compaction removes noise |
|
|
275
|
+
| Source ID collisions across devices | Medium | High | Source ID = `{user_id}-{device_id}-obs-{local_id}` — unique across all dimensions |
|
|
276
|
+
| MCP protocol breaking changes | High | Low | Pin MCP SDK version, abstract protocol layer |
|
|
277
|
+
| Secret leakage in observations | Critical | Medium | Multi-layer scrubbing, sensitivity classification, relative file paths only |
|
|
278
|
+
| Sync conflicts | Medium | Low | Source ID namespacing — structurally impossible for two users to overwrite each other |
|
package/README.md
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Engrm
|
|
2
|
+
|
|
3
|
+
**Cross-device memory for AI coding agents** — powered by [Candengo Vector](https://www.candengo.com).
|
|
4
|
+
|
|
5
|
+
Engrm captures observations from AI-assisted coding sessions (discoveries, bugfixes, decisions, patterns) and syncs them to Candengo Vector so they're available on any machine, in any future session.
|
|
6
|
+
|
|
7
|
+
Built from scratch. Inspired by [claude-mem](https://github.com/thedotmack/claude-mem)'s approach to hooking into Claude Code — but designed around cross-device sync from day one, with Candengo Vector as the backend.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## The Problem
|
|
12
|
+
|
|
13
|
+
Our dev team works across multiple machines and projects (Candengo, Alchemy, AIMY). Every Claude Code session starts from zero — no memory of what was done yesterday, on another machine, or by another developer. The agent re-discovers the same patterns, hits the same gotchas, and asks the same questions that were already answered in a different session.
|
|
14
|
+
|
|
15
|
+
## The Solution
|
|
16
|
+
|
|
17
|
+
An MCP server + Claude Code hooks that:
|
|
18
|
+
|
|
19
|
+
1. **Capture observations automatically** from coding sessions via Claude Code hooks (`PostToolUse`, `Stop`)
|
|
20
|
+
2. **Store locally** in SQLite (offline-first, always available)
|
|
21
|
+
3. **Sync to Candengo Vector** for cross-device, cross-developer search (BGE-M3 hybrid dense+sparse, cross-encoder reranking)
|
|
22
|
+
4. **Inject relevant context** on session start — so the agent picks up where you (or a teammate) left off, on any machine
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Architecture
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
Developer's Machine (any device)
|
|
30
|
+
+---------------------------------------------+
|
|
31
|
+
| Claude Code |
|
|
32
|
+
| | MCP (stdio) |
|
|
33
|
+
| +-----------------------------------+ |
|
|
34
|
+
| | Engrm MCP Server | |
|
|
35
|
+
| | - Observation capture | |
|
|
36
|
+
| | - Local SQLite + FTS5 | |
|
|
37
|
+
| | - Sync outbox queue | |
|
|
38
|
+
| | - Secret scrubbing | |
|
|
39
|
+
| +--------------+--------------------+ |
|
|
40
|
+
| | HTTPS (when available) |
|
|
41
|
+
+-----------------+----------------------------+
|
|
42
|
+
|
|
|
43
|
+
v
|
|
44
|
+
+---------------------------------------------+
|
|
45
|
+
| Candengo Vector (self-hosted or cloud) |
|
|
46
|
+
| - BGE-M3 hybrid dense+sparse search |
|
|
47
|
+
| - Cross-encoder reranking |
|
|
48
|
+
| - Multi-tenant (site_id / namespace) |
|
|
49
|
+
+---------------------------------------------+
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Key principle**: SQLite is the source of truth. Always available, always fast. Candengo Vector is the sync target that enables cross-device search. If the remote is unreachable, everything still works locally.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Getting Started
|
|
57
|
+
|
|
58
|
+
Sign up at [engrm.dev](https://engrm.dev), then run the install command shown on the page:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npx engrm init --token=cmt_your_token_here
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
That's it. The command provisions your account, writes config, registers the MCP server and hooks in Claude Code. Your next Claude Code session has memory.
|
|
65
|
+
|
|
66
|
+
**For teams**: Admin creates a team at [engrm.dev/team](https://engrm.dev/team), shares the invite link. Team members sign up via the link and are pre-configured for the shared namespace.
|
|
67
|
+
|
|
68
|
+
**Self-hosted**: Point at your own Candengo Vector instance:
|
|
69
|
+
```bash
|
|
70
|
+
npx engrm init --url=https://vector.internal.company.com --token=cmt_...
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## How It Hooks Into Claude Code
|
|
76
|
+
|
|
77
|
+
Engrm integrates via two mechanisms:
|
|
78
|
+
|
|
79
|
+
### MCP Server
|
|
80
|
+
Registered in Claude Code's MCP config, exposes tools the agent can call:
|
|
81
|
+
- `search` — find relevant observations from memory
|
|
82
|
+
- `timeline` — chronological context around an observation
|
|
83
|
+
- `get_observations` — fetch full details by ID
|
|
84
|
+
- `save_observation` — manually save something worth remembering
|
|
85
|
+
|
|
86
|
+
### Claude Code Hooks
|
|
87
|
+
Shell scripts triggered by Claude Code lifecycle events:
|
|
88
|
+
- `PostToolUse` — extract observations from tool results (the main capture path)
|
|
89
|
+
- `Stop` — generate session summary, flush sync queue
|
|
90
|
+
|
|
91
|
+
This is similar to how claude-mem hooks in, but our implementation is independent — no shared code, no fork relationship.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## Status
|
|
96
|
+
|
|
97
|
+
**Building.** The product brief, technical spec, and implementation plan are complete. Implementation is starting with Phase 1: local MCP server with SQLite storage, observation capture, and secret scrubbing.
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Project Documents
|
|
102
|
+
|
|
103
|
+
| Document | Contents |
|
|
104
|
+
|---|---|
|
|
105
|
+
| [BRIEF.md](BRIEF.md) | Product brief, target users, revenue model |
|
|
106
|
+
| [SPEC.md](SPEC.md) | Technical specification: schemas, MCP tools, sync engine, search pipeline |
|
|
107
|
+
| [PLAN.md](PLAN.md) | Phased implementation plan with effort estimates |
|
|
108
|
+
| [SWOT.md](SWOT.md) | Strengths, weaknesses, opportunities, threats |
|
|
109
|
+
| [COMPETITIVE.md](COMPETITIVE.md) | Competitive landscape analysis |
|
|
110
|
+
| [MARKET.md](MARKET.md) | Market research, pricing, growth projections |
|
|
111
|
+
| [INFRASTRUCTURE.md](INFRASTRUCTURE.md) | Scaling roadmap, capacity planning |
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
Functional Source License v1.1 (FSL-1.1-ALv2) — source-available, part of the [Fair Source](https://fair.io) movement. Free to use, modify, and self-host for any non-competing purpose. You cannot offer this as a competing hosted service. Each version converts to Apache 2.0 after 2 years. Sentinel (real-time AI audit) is a separate proprietary product. See [LICENSE](LICENSE) for details.
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
Built by [Unimpossible Consultants](https://unimpossible.com) — the team behind Candengo, Alchemy, and AIMY.
|