mnemos-capture 1.0.6 → 1.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/README.md +285 -74
- package/dist/cli/__tests__/config.test.js +49 -0
- package/dist/cli/__tests__/hooks.test.js +276 -0
- package/dist/cli/__tests__/kos.test.js +65 -0
- package/dist/cli/config.js +70 -0
- package/dist/cli/hooks.js +303 -0
- package/dist/cli/index.js +85 -6
- package/dist/cli/kos.js +123 -0
- package/dist/cli/mcp-server.js +21 -1
- package/dist/cli/version-check.js +79 -0
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -4,133 +4,344 @@
|
|
|
4
4
|
|
|
5
5
|
<h1 align="center">Mnemos</h1>
|
|
6
6
|
|
|
7
|
-
<p align="center"
|
|
7
|
+
<p align="center">
|
|
8
|
+
<img src="https://img.shields.io/npm/v/mnemos-capture" alt="npm" />
|
|
9
|
+
<img src="https://img.shields.io/badge/license-MIT-blue" alt="License" />
|
|
10
|
+
<img src="https://img.shields.io/badge/MCP-compatible-green" alt="MCP" />
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<p align="center"><strong>Capture anything. Your agents apply it.</strong></p>
|
|
14
|
+
|
|
15
|
+
<p align="center">A knowledge pipeline that ingests the outside world and makes it directly actionable by any AI agent — over MCP.</p>
|
|
16
|
+
|
|
17
|
+
Your agent only knows what it was trained on. It doesn't know the article you read this morning, the framework you found last week, or the decision you made last sprint. **Your AI agent finally knows what you've been reading.**
|
|
18
|
+
|
|
19
|
+
Mnemos is the pipeline between the two. Capture any insight once — Mnemos extracts it, stores it as plain Markdown in your own GitHub repo, and serves it to your agent over MCP. Then it goes further: at session start it briefs your agent on what matters right now, turns insights into implementation plans, and hands them to whatever assistant you run — Claude Code, Codex, Cursor, Gemini, anything MCP-compatible.
|
|
20
|
+
|
|
21
|
+
It's not a second brain, a vault, or a note-taking app — those store knowledge for *you* to read later. Mnemos makes knowledge your **agent acts on now**.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## Get started
|
|
25
|
+
|
|
26
|
+
### 1. Sign up (30 seconds)
|
|
27
|
+
|
|
28
|
+
Go to **[mnemos-capture.vercel.app](https://mnemos-capture.vercel.app)** → **Sign in with GitHub**.
|
|
8
29
|
|
|
9
|
-
|
|
30
|
+
During setup, Mnemos will:
|
|
10
31
|
|
|
11
|
-
|
|
32
|
+
- Create a knowledge repo in your GitHub account — plain Markdown files, no proprietary format
|
|
33
|
+
- Ask for your API key (your provider, your key — Mnemos never pays for your API calls)
|
|
34
|
+
- Set a PIN so you can unlock the app quickly on mobile
|
|
12
35
|
|
|
13
|
-
|
|
36
|
+
No config files. No repos to clone. No CLI setup required.
|
|
14
37
|
|
|
15
|
-
|
|
38
|
+
### 2. Connect to your AI assistant
|
|
16
39
|
|
|
17
|
-
|
|
40
|
+
When you finish onboarding, Mnemos generates a personal **MCP API key** — copy it.
|
|
18
41
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
42
|
+
**Claude Code:**
|
|
43
|
+
```bash
|
|
44
|
+
claude mcp add mnemos -- npx -y mnemos-capture@latest serve-mcp --key <your-mcp-key>
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Any MCP-compatible client** (Cursor, Continue, Gemini CLI, etc.) — point it at the stdio proxy:
|
|
48
|
+
```bash
|
|
49
|
+
npx -y mnemos-capture@latest serve-mcp --key <your-mcp-key>
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
The proxy forwards your agent's MCP tool calls to the hosted Mnemos API. Nothing is stored locally — your knowledge lives in your GitHub repo.
|
|
53
|
+
|
|
54
|
+
### 3. Capture something
|
|
55
|
+
|
|
56
|
+
Open the app on any device — phone, tablet, or desktop. Paste any content and hit **Capture**. Or capture directly from your agent:
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
capture "The Mom Test — don't ask if your idea is good, ask about their life."
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
That's it. Your knowledge is now indexed and available to every agent session.
|
|
22
63
|
|
|
23
|
-
Every capture includes an **"Applied to"** field — a concrete sentence linking what you learned to what you're building. This is the difference between a saved-for-later graveyard and a knowledge system that compounds.
|
|
24
64
|
|
|
25
65
|
## How it works
|
|
26
66
|
|
|
27
67
|
```mermaid
|
|
28
|
-
flowchart
|
|
29
|
-
A["
|
|
30
|
-
B -->|
|
|
31
|
-
C -->|
|
|
32
|
-
D -->|
|
|
33
|
-
|
|
34
|
-
|
|
68
|
+
flowchart TD
|
|
69
|
+
A["Article / research /\ntranscript / idea"] -->|paste| B["Mnemos\n(web / mobile / agent)"]
|
|
70
|
+
B -->|extracts insight| C["Structured Markdown\ncommitted to your repo"]
|
|
71
|
+
C -->|session start| D["Briefing\nranked suggestions + plan"]
|
|
72
|
+
D -->|generate_plan| E["Implementation plan\nsaved to plans/"]
|
|
73
|
+
E -->|mnemos kos| F["Your AI assistant\nexecutes in isolated worktree"]
|
|
74
|
+
F -->|verify| G["Branch ready\nto review & merge"]
|
|
35
75
|
|
|
36
76
|
style A fill:#1a1a2e,stroke:#444,color:#fff
|
|
37
77
|
style B fill:#2A62C6,stroke:#1a4a9e,color:#fff
|
|
38
|
-
style C fill:#
|
|
39
|
-
style D fill:#
|
|
40
|
-
style E fill:#
|
|
78
|
+
style C fill:#2d8a4e,stroke:#1e6b3a,color:#fff
|
|
79
|
+
style D fill:#d4a843,stroke:#b8912e,color:#fff
|
|
80
|
+
style E fill:#2A62C6,stroke:#1a4a9e,color:#fff
|
|
41
81
|
style F fill:#1a1a2e,stroke:#444,color:#fff
|
|
42
|
-
style G fill:#
|
|
82
|
+
style G fill:#2d8a4e,stroke:#1e6b3a,color:#fff
|
|
43
83
|
```
|
|
44
84
|
|
|
45
|
-
|
|
85
|
+
1. **Capture** — paste anything text-based. Mnemos extracts the core idea, key takeaways, where to apply it, and auto-detects whether it's a URL, short note, or long paste. Committed to your GitHub repo as structured Markdown.
|
|
86
|
+
2. **Brief** — at session start, the `--briefing` flag sends your project context (branch, recent commits, CLAUDE.md) to Mnemos. It returns ranked suggestions — *why* each insight matters now, *what* applying it achieves, *where* in your codebase.
|
|
87
|
+
3. **Plan** — `generate_plan` reads your selected captures and produces a structured Markdown plan: Codebase Mapping table, per-file steps with effort tiers (`simple` / `complex` / `architectural`), and a Verification Checklist.
|
|
88
|
+
4. **Execute** — `mnemos kos` (coming) creates an isolated git worktree, launches your configured AI assistant with the plan as its contract, and runs the verification checklist when it's done.
|
|
46
89
|
|
|
47
|
-
Mnemos handles any text-based input. Paste it, and the LLM figures out the format and extracts accordingly.
|
|
48
90
|
|
|
49
|
-
|
|
50
|
-
- **Twitter/X threads** — the argument stitched together
|
|
51
|
-
- **Podcast and meeting transcripts** — the signal, not the filler
|
|
52
|
-
- **Your own notes and ideas** — raw thoughts turned into structured knowledge
|
|
53
|
-
- **Book highlights and excerpts** — the quotes and frameworks worth keeping
|
|
54
|
-
- **Newsletter and Substack posts** — the actionable takeaways
|
|
91
|
+
## What you can feed it
|
|
55
92
|
|
|
56
|
-
|
|
93
|
+
If it's text, Mnemos can extract insight from it. No manual tagging required.
|
|
57
94
|
|
|
58
|
-
|
|
95
|
+
- **Research papers and preprints** — new models, architectures, evaluation methods
|
|
96
|
+
- **Framework and library docs** — patterns, APIs, integration approaches worth keeping
|
|
97
|
+
- **Technical threads and writeups** — the argument or finding, not the noise
|
|
98
|
+
- **Optimization techniques** — prompt engineering, caching strategies, latency improvements
|
|
99
|
+
- **Your own ideas** — architecture decisions, workflow changes, things you want your agents to act on later
|
|
100
|
+
- **Transcripts and talks** — signal extracted, ready to apply
|
|
59
101
|
|
|
60
|
-
Mnemos uses your own Anthropic API key (BYOK — you bring your own key, Mnemos never charges you).
|
|
61
102
|
|
|
62
|
-
|
|
103
|
+
## Example capture
|
|
63
104
|
|
|
64
|
-
|
|
65
|
-
|-------|----------------------|
|
|
66
|
-
| 50 captures/month (casual) | ~$0.15 |
|
|
67
|
-
| 100 captures/month (regular) | ~$0.30 |
|
|
68
|
-
| 200 captures/month (heavy) | ~$0.60 |
|
|
105
|
+
Paste a research post about error observability. This is what lands in your repo:
|
|
69
106
|
|
|
70
|
-
|
|
107
|
+
```markdown
|
|
108
|
+
---
|
|
109
|
+
date: 2026-06-05
|
|
110
|
+
source: Error Context First — Observability for AI Systems
|
|
111
|
+
url: https://example.com/error-context
|
|
112
|
+
type: post
|
|
113
|
+
source_type: url
|
|
114
|
+
tags: observability, error-handling, ai-agents, debugging
|
|
115
|
+
status: inbox
|
|
116
|
+
lowConfidence: false
|
|
117
|
+
---
|
|
71
118
|
|
|
72
|
-
|
|
119
|
+
# Error Context First — Observability for AI Systems
|
|
73
120
|
|
|
74
|
-
|
|
121
|
+
## Core idea
|
|
122
|
+
Opaque error messages make every fix a guess. Adding source context to every
|
|
123
|
+
error — which handler, which step, which input — turns debugging from archaeology
|
|
124
|
+
into a directed search.
|
|
75
125
|
|
|
76
|
-
|
|
126
|
+
## Key takeaways
|
|
127
|
+
- Every catch block should prefix messages with where it came from
|
|
128
|
+
- "The string did not match the expected pattern" is useless; "[github-write] ..." is actionable
|
|
129
|
+
- Instrument before you fix — opaque errors cause repeated misdiagnoses
|
|
77
130
|
|
|
78
|
-
|
|
131
|
+
## Applied to
|
|
132
|
+
Add handler-name prefixes to every catch block in your agent's tool pipeline.
|
|
133
|
+
```
|
|
79
134
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
135
|
+
`source_type` is auto-detected (`url` / `note` / `paste`). `lowConfidence` flags short or ambiguous input for review before acting on it.
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
## Knowledge lifecycle
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
┌─────────┐
|
|
142
|
+
│ Capture │
|
|
143
|
+
└────┬─────┘
|
|
144
|
+
▼
|
|
145
|
+
┌─────────┐ ┌──────────┐
|
|
146
|
+
│ Inbox │────▶│ Applied │ Insight used — plan executed, rule added, code changed
|
|
147
|
+
└────┬─────┘ └──────────┘
|
|
148
|
+
│
|
|
149
|
+
├──────────▶┌──────────┐
|
|
150
|
+
│ │ Archived │ Reviewed, not actionable right now
|
|
151
|
+
│ └──────────┘
|
|
152
|
+
│
|
|
153
|
+
└──────────▶┌──────────┐
|
|
154
|
+
│ Deleted │ Not useful, permanently removed
|
|
155
|
+
└──────────┘
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
All captures are tracked in `INDEX.md` — a master table your agents search across your entire knowledge base. Generated plans land in `plans/`.
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
## Session hooks
|
|
162
|
+
|
|
163
|
+
`serve-mcp` writes a `SessionStart` hook to `~/.claude/settings.json` on first run. Every session opens with your inbox count:
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
Mnemos: 4 captures in inbox — run list_inbox to review
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Briefing mode
|
|
170
|
+
|
|
171
|
+
Opt in for a structured briefing instead of a count:
|
|
83
172
|
|
|
84
|
-
|
|
173
|
+
```bash
|
|
174
|
+
npx -y mnemos-capture@latest setup-hooks --key YOUR_KEY --briefing
|
|
175
|
+
```
|
|
85
176
|
|
|
86
|
-
|
|
177
|
+
At session start, Mnemos collects your project context — branch, recent commits, CLAUDE.md excerpt — and returns:
|
|
87
178
|
|
|
88
|
-
|
|
179
|
+
1. Ranked suggestions with `why`, `benefit`, `where`, and whether to apply now
|
|
180
|
+
2. Relevant synthesized rules
|
|
181
|
+
3. A `generate_plan` prompt pre-loaded with the captures to apply
|
|
89
182
|
|
|
90
|
-
|
|
183
|
+
```
|
|
184
|
+
3 insights to apply now:
|
|
91
185
|
|
|
92
|
-
|
|
186
|
+
1. error-context-first → src/app/api/capture/route.ts
|
|
187
|
+
Why: Your current branch rewrites the capture pipeline and all catch blocks are opaque
|
|
188
|
+
Benefit: Every error will identify its source in < 1 line
|
|
93
189
|
|
|
94
|
-
|
|
190
|
+
Run generate_plan with selected_captures: ["inbox/2026-06-05-error-context-first.md"]
|
|
191
|
+
```
|
|
95
192
|
|
|
96
|
-
|
|
193
|
+
### Vault mode (PreToolCall hook)
|
|
194
|
+
|
|
195
|
+
Surfaces relevant captures *before* you edit a file — not just at session start:
|
|
97
196
|
|
|
98
197
|
```bash
|
|
99
|
-
|
|
198
|
+
npx -y mnemos-capture@latest setup-hooks --key YOUR_KEY --vault
|
|
100
199
|
```
|
|
101
200
|
|
|
102
|
-
|
|
201
|
+
Before every `Edit`, `Write`, or `MultiEdit` tool call, Mnemos scans your vault for captures scoring ≥ 0.7 relevance to the file you're about to touch. Each capture is surfaced at most once per session.
|
|
202
|
+
|
|
203
|
+
Opt-in only — not installed by default because it fires on every file edit.
|
|
204
|
+
|
|
205
|
+
### Compatibility
|
|
206
|
+
|
|
207
|
+
| Surface | Hook fires |
|
|
208
|
+
|---|---|
|
|
209
|
+
| Claude Code CLI, VS Code / JetBrains extensions, desktop app | Yes |
|
|
210
|
+
| Claude Code on the web | No — `~/.claude/settings.json` is local only |
|
|
211
|
+
| Cursor / other MCP clients | No — distinct hook systems |
|
|
212
|
+
|
|
213
|
+
MCP tools work everywhere. For unsupported surfaces, add to `CLAUDE.md`:
|
|
214
|
+
|
|
215
|
+
> At session start, call `list_inbox` to surface pending captures.
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
## MCP tools
|
|
219
|
+
|
|
220
|
+
Mnemos exposes 15 tools via MCP:
|
|
103
221
|
|
|
104
|
-
|
|
105
|
-
- *"What's in my inbox?"*
|
|
106
|
-
- *"Search my captures for evaluation frameworks"*
|
|
222
|
+
### Capture
|
|
107
223
|
|
|
108
|
-
|
|
224
|
+
| Tool | What it does |
|
|
225
|
+
|------|-------------|
|
|
226
|
+
| `capture` | Extracts insight from any pasted content. Auto-detects source type, flags low-confidence input, auto-links to related captures. |
|
|
109
227
|
|
|
110
|
-
|
|
228
|
+
### Discover
|
|
111
229
|
|
|
112
|
-
|
|
230
|
+
| Tool | What it does |
|
|
231
|
+
|------|-------------|
|
|
232
|
+
| `list_inbox` | Unprocessed captures with summaries — title, type, tags, core idea. |
|
|
233
|
+
| `search_captures` | Keyword + tag search across inbox, applied, and archived. |
|
|
234
|
+
| `read_capture` | Full Markdown of any capture. |
|
|
235
|
+
| `recall` | Semantic search — describe your task, get the most relevant captures back. More powerful than keyword search. |
|
|
236
|
+
|
|
237
|
+
### Apply
|
|
238
|
+
|
|
239
|
+
| Tool | What it does |
|
|
240
|
+
|------|-------------|
|
|
241
|
+
| `apply_capture` | Moves inbox → applied. Records how and where knowledge was used, which plan drove it, and what changed. Triggers rule re-synthesis. |
|
|
242
|
+
| `archive_capture` | Moves inbox → archived. Reviewed but not actionable now. |
|
|
243
|
+
| `delete_capture` | Permanently removes a capture and its index entry. |
|
|
244
|
+
| `apply_to_context` | Paste task + stack + code snippet → get concrete, file-level suggestions for applying your captured knowledge. |
|
|
245
|
+
|
|
246
|
+
### Plan
|
|
247
|
+
|
|
248
|
+
| Tool | What it does |
|
|
249
|
+
|------|-------------|
|
|
250
|
+
| `briefing` | Session-start briefing: ranked suggestions with `applyNow` flags, relevant rules, and a `generate_plan` prompt. Requires `project_context`. |
|
|
251
|
+
| `generate_plan` | Reads selected captures + optional codebase files → structured Markdown plan with Codebase Mapping table, effort tiers per step, and Verification Checklist. Saved to `plans/`. |
|
|
252
|
+
| `list_plans` | Lists saved plans, or reads a specific plan in full. |
|
|
253
|
+
|
|
254
|
+
### Synthesize
|
|
255
|
+
|
|
256
|
+
| Tool | What it does |
|
|
257
|
+
|------|-------------|
|
|
258
|
+
| `synthesize` | Distills captures on a tag into actionable rules. Updates `RULES.md`. |
|
|
259
|
+
| `get_rules` | Returns synthesized rules — filtered by tag or all. Use to populate `CLAUDE.md` or a system prompt. |
|
|
260
|
+
|
|
261
|
+
### Curate
|
|
262
|
+
|
|
263
|
+
| Tool | What it does |
|
|
264
|
+
|------|-------------|
|
|
265
|
+
| `curate` | Validates inbox captures: HEAD-checks URLs (404/410 → stale), flags low-confidence extractions. Optional `auto_archive`. Batch cap: 20 files. |
|
|
266
|
+
| `vault_scan` | Scans the full vault for captures relevant to your current activity (score ≥ 0.7). Used by the vault hook. |
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
## CLI
|
|
270
|
+
|
|
271
|
+
```
|
|
272
|
+
mnemos-capture Open hosted app
|
|
273
|
+
mnemos-capture serve-mcp --key KEY Run local MCP proxy (auto-installs hook)
|
|
274
|
+
mnemos-capture setup-hooks --key KEY [--briefing] [--vault] Install session hooks
|
|
275
|
+
mnemos-capture inbox-check --key KEY [--briefing] Debug what the hook runs
|
|
276
|
+
mnemos-capture vault-check --key KEY Debug what the vault hook runs
|
|
277
|
+
mnemos-capture help Show help
|
|
278
|
+
```
|
|
113
279
|
|
|
114
|
-
|
|
280
|
+
All commands run via `npx -y mnemos-capture@latest <subcommand>`. `@latest` forces npm to resolve against the registry on every invocation.
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
## Mobile
|
|
284
|
+
|
|
285
|
+
Open Mnemos in your phone's browser → **Share → Add to Home Screen**. Runs full-screen like a native app. Capture while reading — your agents have it by the time you sit down to work.
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
## Your data, your storage
|
|
289
|
+
|
|
290
|
+
Your knowledge lives in a GitHub repo you own. Plain Markdown files, version-controlled, portable.
|
|
291
|
+
|
|
292
|
+
- **No lock-in** — clone it, move it, delete Mnemos and your repo stays exactly where it is
|
|
293
|
+
- **No proprietary format** — every capture is a readable `.md` file
|
|
294
|
+
- **No training on your data** — Mnemos never reads your captures for any purpose other than serving them back to you
|
|
295
|
+
- **Any tool can access it** — anything that reads Git or speaks MCP works with your knowledge base
|
|
296
|
+
- **BYOK** — your provider, your key, your cost
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
## Cost
|
|
300
|
+
|
|
301
|
+
Mnemos is BYOK — you bring your own API key, Mnemos never charges you for inference.
|
|
302
|
+
|
|
303
|
+
Extraction runs on a fast, low-cost model (Claude Haiku 4.5 by default) with prompt caching and input truncation:
|
|
304
|
+
|
|
305
|
+
| Usage | Estimated monthly cost |
|
|
306
|
+
|-------|----------------------|
|
|
307
|
+
| 50 captures/month | ~$0.15 |
|
|
308
|
+
| 100 captures/month | ~$0.30 |
|
|
309
|
+
| 200 captures/month | ~$0.60 |
|
|
310
|
+
|
|
311
|
+
Briefing and plan generation use your configured model and only run when you explicitly invoke them.
|
|
115
312
|
|
|
116
|
-
Your knowledge lives in a repo you own. No proprietary database, no vendor lock-in. It's version-controlled, portable, and readable as plain Markdown. Clone it, search it, back it up — it's just files. And because it's a standard Git repo, any MCP-compatible agent or tool can read from it directly.
|
|
117
313
|
|
|
118
314
|
## Tech stack
|
|
119
315
|
|
|
120
|
-
Next.js · TypeScript
|
|
316
|
+
Next.js · TypeScript · Vercel Postgres · GitHub OAuth · GitHub Content API · MCP protocol · Anthropic SDK · Tailwind CSS · Vitest
|
|
317
|
+
|
|
121
318
|
|
|
122
319
|
## Roadmap
|
|
123
320
|
|
|
124
|
-
-
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
321
|
+
- **`mnemos kos`** — CLI orchestrator: creates isolated git worktree, launches your configured AI assistant with the plan as its contract, runs the Verification Checklist, reports the branch
|
|
322
|
+
- **Provider abstraction** — bring your OpenAI, Google, or any OpenAI-compatible key; Mnemos routes accordingly
|
|
323
|
+
- **Chrome extension** — one-click capture from anywhere in the browser
|
|
324
|
+
- Voice memo capture
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
## Built by
|
|
328
|
+
|
|
329
|
+
[Sofía Padrón Valdez](https://github.com/Soph20) — builder, AI systems architect.
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
## Citation
|
|
333
|
+
|
|
334
|
+
```
|
|
335
|
+
@misc{2026mnemos,
|
|
336
|
+
title = {Mnemos: A Knowledge Pipeline for AI Agents},
|
|
337
|
+
author = {Sofia Padron Valdez},
|
|
338
|
+
year = 2026,
|
|
339
|
+
journal = {GitHub repository},
|
|
340
|
+
publisher = {GitHub},
|
|
341
|
+
howpublished = {\url{https://github.com/Soph20/mnemos-capture}}
|
|
342
|
+
}
|
|
343
|
+
```
|
|
133
344
|
|
|
134
345
|
## License
|
|
135
346
|
|
|
136
|
-
[MIT](LICENSE)
|
|
347
|
+
[MIT License - see LICENSE file for details](./LICENSE)
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
|
|
2
|
+
import { mkdtempSync, rmSync, readFileSync, existsSync } from "fs";
|
|
3
|
+
import { tmpdir } from "os";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
describe("config", () => {
|
|
6
|
+
let tmpDir;
|
|
7
|
+
let configPath;
|
|
8
|
+
let origHome;
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
tmpDir = mkdtempSync(join(tmpdir(), "mnemos-config-test-"));
|
|
11
|
+
configPath = join(tmpDir, ".mnemos", "config.json");
|
|
12
|
+
origHome = process.env["HOME"];
|
|
13
|
+
process.env["HOME"] = tmpDir;
|
|
14
|
+
// Module-level CONFIG_DIR is computed from homedir() at import — reset cache
|
|
15
|
+
vi.resetModules();
|
|
16
|
+
});
|
|
17
|
+
afterEach(() => {
|
|
18
|
+
rmSync(tmpDir, { recursive: true, force: true });
|
|
19
|
+
process.env["HOME"] = origHome;
|
|
20
|
+
});
|
|
21
|
+
it("returns an empty object when no config exists", async () => {
|
|
22
|
+
const { readConfig } = await import("../config.js");
|
|
23
|
+
expect(readConfig()).toEqual({});
|
|
24
|
+
});
|
|
25
|
+
it("writes and reads back the agent field", async () => {
|
|
26
|
+
const { setConfigField, readConfig } = await import("../config.js");
|
|
27
|
+
setConfigField("agent", "claude -p");
|
|
28
|
+
expect(readConfig().agent).toBe("claude -p");
|
|
29
|
+
expect(existsSync(configPath)).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
it("persists the agent command verbatim, including flags", async () => {
|
|
32
|
+
const { setConfigField } = await import("../config.js");
|
|
33
|
+
setConfigField("agent", "aider --yes --message");
|
|
34
|
+
const saved = JSON.parse(readFileSync(configPath, "utf-8"));
|
|
35
|
+
expect(saved.agent).toBe("aider --yes --message");
|
|
36
|
+
});
|
|
37
|
+
it("preserves other fields when updating one", async () => {
|
|
38
|
+
const { setConfigField, readConfig } = await import("../config.js");
|
|
39
|
+
setConfigField("key", "mnemos_abc123");
|
|
40
|
+
setConfigField("agent", "codex exec");
|
|
41
|
+
const cfg = readConfig();
|
|
42
|
+
expect(cfg.key).toBe("mnemos_abc123");
|
|
43
|
+
expect(cfg.agent).toBe("codex exec");
|
|
44
|
+
});
|
|
45
|
+
it("throws on an unknown config field", async () => {
|
|
46
|
+
const { setConfigField } = await import("../config.js");
|
|
47
|
+
expect(() => setConfigField("provider", "openai")).toThrow(/Unknown config field/);
|
|
48
|
+
});
|
|
49
|
+
});
|