baby-daemon 1.0.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 +3 -0
- package/LICENSE +21 -0
- package/README.md +224 -0
- package/bin/baby-daemon.js +189 -0
- package/bin/memory-watch.js +98 -0
- package/bin/memory.js +399 -0
- package/mcp-server.js +553 -0
- package/package.json +63 -0
- package/src/config.js +18 -0
- package/src/idempotency.js +159 -0
- package/src/memoryStore.js +95 -0
- package/src/summarizer.js +151 -0
- package/src/vectorStore.js +410 -0
- package/src/watcher.js +263 -0
package/.env.example
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 sankolte
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
# ๐ง Baby Daemon
|
|
2
|
+
|
|
3
|
+
> A background daemon that gives AI coding agents persistent memory across sessions.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## The Problem
|
|
8
|
+
|
|
9
|
+
Every AI coding session is stateless by default. Switch agents, restart a session, or continue the next day โ your AI forgets everything. Decisions, bugs, architecture choices. You re-explain it all. Every. Single. Time.
|
|
10
|
+
|
|
11
|
+
**Baby Daemon fixes that.**
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## How It Works
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
1. Run `memory-watch ./logs` โ daemon starts watching your agent's chat logs
|
|
19
|
+
2. File changes detected โ Gemini 2.5 Flash extracts structured memories
|
|
20
|
+
3. Memories stored โ LanceDB (vector) + memory.jsonl (flat)
|
|
21
|
+
4. New session, new agent โ `memory search "why did auth break?"` โ instant context
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## CLI Commands
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Start the daemon (watches a folder for AI chat logs)
|
|
30
|
+
memory-watch ./logs
|
|
31
|
+
|
|
32
|
+
# Start with human approval for high-confidence decisions
|
|
33
|
+
memory-watch ./logs --require-approval
|
|
34
|
+
|
|
35
|
+
# Semantic search across all stored memories
|
|
36
|
+
memory search "authentication bug"
|
|
37
|
+
|
|
38
|
+
# Filtered search
|
|
39
|
+
memory search "caching strategy" --type decision --since "3 days ago"
|
|
40
|
+
|
|
41
|
+
# Dump raw logs (bypasses vector DB โ emergency fallback)
|
|
42
|
+
memory dump --since "yesterday"
|
|
43
|
+
|
|
44
|
+
# Archive old memories to keep search fast
|
|
45
|
+
memory archive --age 14
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Tech Stack
|
|
51
|
+
|
|
52
|
+
| Layer | Technology |
|
|
53
|
+
|---|---|
|
|
54
|
+
| Runtime | Node.js (ES Modules) |
|
|
55
|
+
| File Watcher | `chokidar` (event-driven, OS-native) |
|
|
56
|
+
| LLM Summarizer | Google Gemini 2.5 Flash |
|
|
57
|
+
| Embeddings | `gemini-embedding-2` |
|
|
58
|
+
| Vector DB | LanceDB (local, embedded โ no server) |
|
|
59
|
+
| Keyword Fallback | `minisearch` (pure JS) |
|
|
60
|
+
| Date Parsing | `chrono-node` ("yesterday", "2 days ago") |
|
|
61
|
+
| Integrity | SHA-256 hashing (`node:crypto`) |
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Memory Schema
|
|
66
|
+
|
|
67
|
+
Every memory is a structured, typed object โ never a plain string:
|
|
68
|
+
|
|
69
|
+
```json
|
|
70
|
+
{
|
|
71
|
+
"id": "mem-1716300000-a1b2c3d4",
|
|
72
|
+
"timestamp": "2026-05-21T10:30:00Z",
|
|
73
|
+
"type": "proposed_idea",
|
|
74
|
+
"content": "Consider switching to Redis for caching layer",
|
|
75
|
+
"original_text": "maybe we should use Redis...",
|
|
76
|
+
"confidence": 0.4,
|
|
77
|
+
"status": "active",
|
|
78
|
+
"related_files": ["cache.ts"],
|
|
79
|
+
"tags": ["redis", "caching"],
|
|
80
|
+
"source": { "chat_file": "chat_042.md" },
|
|
81
|
+
"hash": "e4a91b7a9f..."
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
**Types:** `decision` ยท `proposed_idea` ยท `rejected_idea` ยท `open_question` ยท `bug` ยท `resolved_bug` ยท `architecture_note` ยท `file_change`
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Key Design Decisions
|
|
90
|
+
|
|
91
|
+
### Duplicate Prevention (Idempotency)
|
|
92
|
+
OS file watchers fire multiple times per save. Every file event is fingerprinted:
|
|
93
|
+
```
|
|
94
|
+
key = SHA-256(absolute_path + "|" + last_modified_ms)
|
|
95
|
+
```
|
|
96
|
+
Key is stored in `processed_keys.json`. Only recorded **after** successful processing โ so failures auto-retry.
|
|
97
|
+
|
|
98
|
+
### Memory Drift Prevention
|
|
99
|
+
LLMs compress uncertainty. *"Maybe use Redis"* becomes *"Project migrated to Redis."*
|
|
100
|
+
|
|
101
|
+
Fixes:
|
|
102
|
+
- Strict type schema โ `decision` requires explicit commitment from both sides
|
|
103
|
+
- Every memory stores the **exact source quote** (`original_text`)
|
|
104
|
+
- `--require-approval` flag for human-in-the-loop on high-risk memories
|
|
105
|
+
- `status: outdated` for contradicted memories + archival system
|
|
106
|
+
|
|
107
|
+
### 3-Layer Hybrid Search
|
|
108
|
+
1. **LanceDB vector search** โ cosine similarity, 0.70 threshold
|
|
109
|
+
2. **Metadata filtering** โ type, date (natural language via chrono-node), file
|
|
110
|
+
3. **MiniSearch keyword fallback** โ if vector search returns nothing
|
|
111
|
+
4. **Raw dump fallback** โ if everything else fails, `memory dump` bypasses the AI layer entirely
|
|
112
|
+
|
|
113
|
+
### Never Summarize a Summary
|
|
114
|
+
Memories are always generated from **original raw logs**, never from previous summaries. Prevents information entropy across multi-agent handoffs.
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Build Phases
|
|
119
|
+
|
|
120
|
+
- [x] **Phase 1** โ File watcher shell + idempotency
|
|
121
|
+
- [x] **Phase 2** โ Gemini summarization pipeline + structured schema
|
|
122
|
+
- [x] **Phase 3** โ LanceDB vector store + semantic search
|
|
123
|
+
- [x] **Phase 4** โ Integrity (SHA-256 hashes, fallback dump, approval mode, archival)
|
|
124
|
+
- [x] **Phase 5** โ MCP Server (wrap as plug-and-play tool for any MCP-compatible agent)
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Setup
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
git clone https://github.com/sankolte/Baby-Daemon.git
|
|
132
|
+
cd Baby-Daemon
|
|
133
|
+
npm install
|
|
134
|
+
cp .env.example .env
|
|
135
|
+
# Add your GEMINI_API_KEY to .env
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Watch your logs folder
|
|
140
|
+
node bin/memory-watch.js ./logs
|
|
141
|
+
|
|
142
|
+
# Or if installed globally via npm link:
|
|
143
|
+
memory-watch ./logs
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Project Structure
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
โโโ mcp-server.js โ MCP server entry point (Phase 5)
|
|
152
|
+
โโโ bin/
|
|
153
|
+
โ โโโ memory-watch.js โ Start the daemon
|
|
154
|
+
โ โโโ memory.js โ Search, dump, archive
|
|
155
|
+
โโโ src/
|
|
156
|
+
โ โโโ watcher.js โ chokidar + pipeline orchestration
|
|
157
|
+
โ โโโ summarizer.js โ Gemini call + JSON schema enforcement
|
|
158
|
+
โ โโโ vectorStore.js โ LanceDB, embeddings cache, MiniSearch fallback
|
|
159
|
+
โ โโโ memoryStore.js โ JSONL read/write
|
|
160
|
+
โ โโโ idempotency.js โ SHA-256 key generation + persistence
|
|
161
|
+
โ โโโ config.js โ Gemini SDK init
|
|
162
|
+
โโโ memory.jsonl โ Flat structured memory store (gitignored)
|
|
163
|
+
โโโ .lancedb/ โ Local vector DB (gitignored)
|
|
164
|
+
โโโ claude_desktop_config.example.json โ Example MCP config
|
|
165
|
+
โโโ .env.example โ Environment variable template
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Phase 5 โ MCP Server
|
|
171
|
+
|
|
172
|
+
Baby Daemon is now available as an **MCP (Model Context Protocol) server**. Any MCP-compatible AI host can use it natively โ no CLI required.
|
|
173
|
+
|
|
174
|
+
### Available MCP Tools
|
|
175
|
+
|
|
176
|
+
| Tool | Description |
|
|
177
|
+
|------|-------------|
|
|
178
|
+
| `memory_search` | Semantic + keyword search with filters (type, date, file, limit) |
|
|
179
|
+
| `memory_store` | Push raw text through the summarization pipeline and store |
|
|
180
|
+
| `memory_dump` | Dump all stored memories with optional filters |
|
|
181
|
+
| `memory_archive` | Move old memories to archive table |
|
|
182
|
+
| `memory_read` | Full project knowledge briefing grouped by category |
|
|
183
|
+
|
|
184
|
+
**Resource:** `memory://status` โ system health, counts, LanceDB status
|
|
185
|
+
**Prompt:** `continue_from_memory` โ context-rich prompt to resume work from previous sessions
|
|
186
|
+
|
|
187
|
+
### Setup for Claude Desktop
|
|
188
|
+
|
|
189
|
+
Add to `%APPDATA%/Claude/claude_desktop_config.json`:
|
|
190
|
+
|
|
191
|
+
```json
|
|
192
|
+
{
|
|
193
|
+
"mcpServers": {
|
|
194
|
+
"baby-daemon": {
|
|
195
|
+
"command": "node",
|
|
196
|
+
"args": ["C:\\path\\to\\proj101\\mcp-server.js"]
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Restart Claude Desktop โ Baby Daemon tools appear automatically.
|
|
203
|
+
|
|
204
|
+
### Setup for Cursor / Cline / Other MCP Hosts
|
|
205
|
+
|
|
206
|
+
Most MCP hosts use a similar JSON config. Point it to:
|
|
207
|
+
```
|
|
208
|
+
command: node
|
|
209
|
+
args: ["<absolute-path-to>/mcp-server.js"]
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Testing with MCP Inspector
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
npx @modelcontextprotocol/inspector node mcp-server.js
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Opens a web UI where you can interactively test all tools, read resources, and invoke prompts.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## License
|
|
223
|
+
|
|
224
|
+
MIT
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* bin/baby-daemon.js
|
|
5
|
+
* โโโโโโโโโโโโโโโโโโ
|
|
6
|
+
* The main entry command for Baby Daemon.
|
|
7
|
+
*
|
|
8
|
+
* When a user installs globally (npm install -g baby-daemon),
|
|
9
|
+
* they can run: baby-daemon
|
|
10
|
+
*
|
|
11
|
+
* This shows:
|
|
12
|
+
* - Quick status (is API key set? are there memories?)
|
|
13
|
+
* - Available commands
|
|
14
|
+
* - MCP setup instructions
|
|
15
|
+
* - First-time setup help
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import fs from 'fs';
|
|
19
|
+
import path from 'path';
|
|
20
|
+
import { fileURLToPath } from 'url';
|
|
21
|
+
import dotenv from 'dotenv';
|
|
22
|
+
|
|
23
|
+
// Load .env from current working directory (where the user runs the command)
|
|
24
|
+
dotenv.config({ path: path.join(process.cwd(), '.env') });
|
|
25
|
+
|
|
26
|
+
// Also try loading from the package directory (for global installs)
|
|
27
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
const PACKAGE_ROOT = path.join(__dirname, '..');
|
|
29
|
+
dotenv.config({ path: path.join(PACKAGE_ROOT, '.env') });
|
|
30
|
+
|
|
31
|
+
// CLI Styling
|
|
32
|
+
const R = '\x1b[0m'; // Reset
|
|
33
|
+
const B = '\x1b[1m'; // Bold
|
|
34
|
+
const D = '\x1b[2m'; // Dim
|
|
35
|
+
const C = '\x1b[36m'; // Cyan
|
|
36
|
+
const G = '\x1b[32m'; // Green
|
|
37
|
+
const Y = '\x1b[33m'; // Yellow
|
|
38
|
+
const M = '\x1b[35m'; // Magenta
|
|
39
|
+
const RED = '\x1b[31m'; // Red
|
|
40
|
+
|
|
41
|
+
const args = process.argv.slice(2);
|
|
42
|
+
const command = args[0]?.toLowerCase();
|
|
43
|
+
|
|
44
|
+
if (command === 'setup') {
|
|
45
|
+
handleSetup();
|
|
46
|
+
} else if (command === 'mcp-config') {
|
|
47
|
+
handleMcpConfig();
|
|
48
|
+
} else {
|
|
49
|
+
handleDefault();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
53
|
+
// DEFAULT: Show status + available commands
|
|
54
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
55
|
+
|
|
56
|
+
function handleDefault() {
|
|
57
|
+
const hasApiKey = !!process.env.GEMINI_API_KEY;
|
|
58
|
+
const memoryFile = path.join(process.cwd(), 'memory.jsonl');
|
|
59
|
+
const hasMemories = fs.existsSync(memoryFile);
|
|
60
|
+
let memoryCount = 0;
|
|
61
|
+
if (hasMemories) {
|
|
62
|
+
try {
|
|
63
|
+
const content = fs.readFileSync(memoryFile, 'utf-8');
|
|
64
|
+
memoryCount = content.split('\n').filter(l => l.trim()).length;
|
|
65
|
+
} catch { /* ignore */ }
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
console.log(`
|
|
69
|
+
${B}${C}๐ง Baby Daemon${R} ${D}v0.1.0${R}
|
|
70
|
+
${D}AI memory system for coding agents${R}
|
|
71
|
+
|
|
72
|
+
${B}STATUS:${R}
|
|
73
|
+
API Key : ${hasApiKey ? `${G}โ Set${R}` : `${RED}โ Not set${R} ${D}(run: baby-daemon setup)${R}`}
|
|
74
|
+
Memories : ${hasMemories ? `${G}${memoryCount} stored${R}` : `${Y}None yet${R}`}
|
|
75
|
+
Directory : ${D}${process.cwd()}${R}
|
|
76
|
+
|
|
77
|
+
${B}COMMANDS:${R}
|
|
78
|
+
${C}memory-watch ${D}<folder>${R} Watch a folder for AI chat logs
|
|
79
|
+
${C}memory search ${D}<query>${R} Search stored memories (semantic + keyword)
|
|
80
|
+
${C}memory read${R} View all active memories by category
|
|
81
|
+
${C}memory dump${R} Dump raw memory data
|
|
82
|
+
${C}memory archive${R} Archive old memories
|
|
83
|
+
|
|
84
|
+
${B}SETUP:${R}
|
|
85
|
+
${C}baby-daemon setup${R} First-time setup guide
|
|
86
|
+
${C}baby-daemon mcp-config${R} Show MCP server config for Claude/Cursor
|
|
87
|
+
|
|
88
|
+
${B}MCP SERVER:${R}
|
|
89
|
+
${D}For AI hosts (Claude Desktop, Cursor, Cline):${R}
|
|
90
|
+
${C}baby-daemon mcp-config${R} ${D}โ shows the JSON config to copy${R}
|
|
91
|
+
`);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
95
|
+
// SETUP: First-time setup guide
|
|
96
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
97
|
+
|
|
98
|
+
function handleSetup() {
|
|
99
|
+
const hasApiKey = !!process.env.GEMINI_API_KEY;
|
|
100
|
+
const envExists = fs.existsSync(path.join(process.cwd(), '.env'));
|
|
101
|
+
|
|
102
|
+
console.log(`
|
|
103
|
+
${B}${C}๐ง Baby Daemon โ Setup Guide${R}
|
|
104
|
+
|
|
105
|
+
${B}Step 1: Get a Gemini API Key (free)${R}
|
|
106
|
+
${D}Go to:${R} ${C}https://aistudio.google.com/apikey${R}
|
|
107
|
+
${D}Click "Create API key" โ copy it${R}
|
|
108
|
+
|
|
109
|
+
${B}Step 2: Create a .env file${R}
|
|
110
|
+
${D}In your project root, create a file called${R} ${C}.env${R} ${D}with:${R}
|
|
111
|
+
|
|
112
|
+
${G}GEMINI_API_KEY=your_api_key_here${R}
|
|
113
|
+
|
|
114
|
+
${envExists ? ` ${G}โ .env file found in current directory${R}` : ` ${Y}โ No .env file found in ${process.cwd()}${R}`}
|
|
115
|
+
${hasApiKey ? ` ${G}โ API key is loaded${R}` : ` ${RED}โ API key not detected yet${R}`}
|
|
116
|
+
|
|
117
|
+
${B}Step 3: Create a logs folder${R}
|
|
118
|
+
${D}This is where your AI agent chat logs go:${R}
|
|
119
|
+
|
|
120
|
+
${C}mkdir logs${R}
|
|
121
|
+
|
|
122
|
+
${B}Step 4: Start watching${R}
|
|
123
|
+
|
|
124
|
+
${C}memory-watch ./logs${R}
|
|
125
|
+
|
|
126
|
+
${D}Baby Daemon will now watch for new/changed files in ./logs,
|
|
127
|
+
extract structured memories via Gemini, and store them for search.${R}
|
|
128
|
+
|
|
129
|
+
${B}Step 5 (Optional): Connect to Claude Desktop / Cursor${R}
|
|
130
|
+
|
|
131
|
+
${C}baby-daemon mcp-config${R}
|
|
132
|
+
`);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
136
|
+
// MCP-CONFIG: Show copy-paste MCP configuration
|
|
137
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
138
|
+
|
|
139
|
+
function handleMcpConfig() {
|
|
140
|
+
// Find the mcp-server.js path
|
|
141
|
+
const mcpServerPath = path.join(PACKAGE_ROOT, 'mcp-server.js');
|
|
142
|
+
const mcpServerExists = fs.existsSync(mcpServerPath);
|
|
143
|
+
|
|
144
|
+
// Format path for JSON (escape backslashes for Windows)
|
|
145
|
+
const escapedPath = mcpServerPath.replace(/\\/g, '\\\\');
|
|
146
|
+
|
|
147
|
+
console.log(`
|
|
148
|
+
${B}${C}๐ง Baby Daemon โ MCP Server Configuration${R}
|
|
149
|
+
|
|
150
|
+
${mcpServerExists ? `${G}โ MCP server found at:${R}` : `${RED}โ MCP server not found at:${R}`}
|
|
151
|
+
${D}${mcpServerPath}${R}
|
|
152
|
+
|
|
153
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
154
|
+
|
|
155
|
+
${B}${M}Claude Desktop${R}
|
|
156
|
+
${D}Add this to:${R} ${C}%APPDATA%\\Claude\\claude_desktop_config.json${R}
|
|
157
|
+
${D}(Mac: ~/Library/Application Support/Claude/claude_desktop_config.json)${R}
|
|
158
|
+
|
|
159
|
+
${G}{
|
|
160
|
+
"mcpServers": {
|
|
161
|
+
"baby-daemon": {
|
|
162
|
+
"command": "node",
|
|
163
|
+
"args": ["${escapedPath}"]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}${R}
|
|
167
|
+
|
|
168
|
+
${D}Then restart Claude Desktop.${R}
|
|
169
|
+
|
|
170
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
171
|
+
|
|
172
|
+
${B}${M}Cursor${R}
|
|
173
|
+
${D}Go to: Settings โ MCP โ Add Server${R}
|
|
174
|
+
${D}Command:${R} ${C}node${R}
|
|
175
|
+
${D}Args:${R} ${C}${mcpServerPath}${R}
|
|
176
|
+
|
|
177
|
+
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
178
|
+
|
|
179
|
+
${B}AVAILABLE TOOLS (auto-discovered by AI host):${R}
|
|
180
|
+
${C}memory_search${R} ${D}โ Semantic search across all stored memories${R}
|
|
181
|
+
${C}memory_store${R} ${D}โ Push text through summarization pipeline${R}
|
|
182
|
+
${C}memory_read${R} ${D}โ Full project knowledge briefing${R}
|
|
183
|
+
${C}memory_dump${R} ${D}โ Raw memory dump with filters${R}
|
|
184
|
+
${C}memory_archive${R} ${D}โ Archive old memories${R}
|
|
185
|
+
|
|
186
|
+
${B}RESOURCE:${R} ${C}memory://status${R} ${D}โ System health dashboard${R}
|
|
187
|
+
${B}PROMPT:${R} ${C}continue_from_memory${R} ${D}โ Context-rich session bootstrap${R}
|
|
188
|
+
`);
|
|
189
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* memory-watch.js (the CLI entry point)
|
|
4
|
+
* โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
5
|
+
* WHAT THIS FILE DOES:
|
|
6
|
+
* This is the file that runs when you type `memory-watch` in the terminal.
|
|
7
|
+
* It reads the command-line arguments, validates them, and calls startWatcher().
|
|
8
|
+
* It's intentionally tiny โ a CLI entry point should ONLY parse args and delegate.
|
|
9
|
+
* All real logic lives in src/watcher.js.
|
|
10
|
+
*
|
|
11
|
+
* CONCEPT: #!/usr/bin/env node (the "shebang" line)
|
|
12
|
+
* The very first line starting with #! is called a "shebang" (or hashbang).
|
|
13
|
+
* On Unix/Mac, when you run a script file directly, the OS reads this line
|
|
14
|
+
* to know WHICH program should execute the file.
|
|
15
|
+
* #!/usr/bin/env node means: "find 'node' in the PATH and run this file with it"
|
|
16
|
+
* On Windows this line is ignored (Node handles it differently via the bin field
|
|
17
|
+
* in package.json), but we still include it for cross-platform compatibility.
|
|
18
|
+
*
|
|
19
|
+
* CONCEPT: process.argv
|
|
20
|
+
* Every Node.js process has a global 'process' object with useful info.
|
|
21
|
+
* process.argv is an array of command-line arguments:
|
|
22
|
+
* process.argv[0] = path to node executable (e.g., "C:/nodejs/node.exe")
|
|
23
|
+
* process.argv[1] = path to the script being run (e.g., "C:/proj101/bin/memory-watch.js")
|
|
24
|
+
* process.argv[2] = FIRST argument YOU passed (e.g., "./logs")
|
|
25
|
+
* process.argv[3] = second argument (if any)
|
|
26
|
+
* So when you run: memory-watch ./logs
|
|
27
|
+
* process.argv = ['node', 'memory-watch.js', './logs']
|
|
28
|
+
* And process.argv[2] = './logs'
|
|
29
|
+
*
|
|
30
|
+
* CONCEPT: ES Module imports
|
|
31
|
+
* We use: import { startWatcher } from '../src/watcher.js';
|
|
32
|
+
* This is the modern JS module system (ESM).
|
|
33
|
+
* The older system (CommonJS) used: const { startWatcher } = require('../src/watcher');
|
|
34
|
+
* We use ESM because we set "type": "module" in package.json.
|
|
35
|
+
* Key difference: ESM is static (imports resolved at parse time), CJS is dynamic.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
import { startWatcher } from '../src/watcher.js';
|
|
39
|
+
|
|
40
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
41
|
+
// PARSE ARGUMENTS
|
|
42
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
43
|
+
|
|
44
|
+
const args = process.argv.slice(2);
|
|
45
|
+
// .slice(2) removes the first two items (node path + script path)
|
|
46
|
+
// leaving only the arguments the user actually typed
|
|
47
|
+
|
|
48
|
+
// Show help if user runs: memory-watch --help or memory-watch -h
|
|
49
|
+
if (args.includes('--help') || args.includes('-h')) {
|
|
50
|
+
printHelp();
|
|
51
|
+
process.exit(0);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// The watch path is the first real argument
|
|
55
|
+
const requireApproval = args.includes('--require-approval') || args.includes('-a');
|
|
56
|
+
const watchPath = args.find(arg => !arg.startsWith('-'));
|
|
57
|
+
|
|
58
|
+
if (!watchPath) {
|
|
59
|
+
console.error('\n โ Error: No folder path provided.\n');
|
|
60
|
+
printHelp();
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
65
|
+
// START THE WATCHER
|
|
66
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
67
|
+
|
|
68
|
+
startWatcher(watchPath, { requireApproval });
|
|
69
|
+
|
|
70
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
71
|
+
// HELP TEXT
|
|
72
|
+
// โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
73
|
+
|
|
74
|
+
function printHelp() {
|
|
75
|
+
console.log(`
|
|
76
|
+
Baby Daemon โ memory-watch (Phase 3)
|
|
77
|
+
|
|
78
|
+
USAGE:
|
|
79
|
+
memory-watch <folder-path> [options]
|
|
80
|
+
|
|
81
|
+
OPTIONS:
|
|
82
|
+
-a, --require-approval Prompt to confirm or reject each extracted memory
|
|
83
|
+
|
|
84
|
+
EXAMPLES:
|
|
85
|
+
memory-watch ./logs
|
|
86
|
+
memory-watch ./logs --require-approval
|
|
87
|
+
memory-watch . (watch current folder)
|
|
88
|
+
|
|
89
|
+
WHAT IT DOES:
|
|
90
|
+
Watches <folder-path> for new and modified files.
|
|
91
|
+
Extracts structured memories via Gemini API.
|
|
92
|
+
Saves memories to memory.jsonl and syncs with LanceDB vector database.
|
|
93
|
+
Skips duplicates using idempotency fingerprints.
|
|
94
|
+
|
|
95
|
+
STOP:
|
|
96
|
+
Press Ctrl+C to stop the watcher gracefully.
|
|
97
|
+
`);
|
|
98
|
+
}
|