moltmind 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/LICENSE +21 -0
- package/README.md +112 -0
- package/dist/db.d.ts +45 -0
- package/dist/db.js +381 -0
- package/dist/db.js.map +1 -0
- package/dist/diagnostics.d.ts +25 -0
- package/dist/diagnostics.js +29 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/embeddings.d.ts +14 -0
- package/dist/embeddings.js +91 -0
- package/dist/embeddings.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +97 -0
- package/dist/index.js.map +1 -0
- package/dist/metrics.d.ts +38 -0
- package/dist/metrics.js +105 -0
- package/dist/metrics.js.map +1 -0
- package/dist/tools/mm_delete.d.ts +6 -0
- package/dist/tools/mm_delete.js +9 -0
- package/dist/tools/mm_delete.js.map +1 -0
- package/dist/tools/mm_feedback.d.ts +8 -0
- package/dist/tools/mm_feedback.js +6 -0
- package/dist/tools/mm_feedback.js.map +1 -0
- package/dist/tools/mm_handoff_create.d.ts +9 -0
- package/dist/tools/mm_handoff_create.js +16 -0
- package/dist/tools/mm_handoff_create.js.map +1 -0
- package/dist/tools/mm_handoff_load.d.ts +1 -0
- package/dist/tools/mm_handoff_load.js +9 -0
- package/dist/tools/mm_handoff_load.js.map +1 -0
- package/dist/tools/mm_init.d.ts +5 -0
- package/dist/tools/mm_init.js +6 -0
- package/dist/tools/mm_init.js.map +1 -0
- package/dist/tools/mm_metrics.d.ts +1 -0
- package/dist/tools/mm_metrics.js +6 -0
- package/dist/tools/mm_metrics.js.map +1 -0
- package/dist/tools/mm_read.d.ts +3 -0
- package/dist/tools/mm_read.js +24 -0
- package/dist/tools/mm_read.js.map +1 -0
- package/dist/tools/mm_recall.d.ts +11 -0
- package/dist/tools/mm_recall.js +71 -0
- package/dist/tools/mm_recall.js.map +1 -0
- package/dist/tools/mm_status.d.ts +1 -0
- package/dist/tools/mm_status.js +18 -0
- package/dist/tools/mm_status.js.map +1 -0
- package/dist/tools/mm_store.d.ts +12 -0
- package/dist/tools/mm_store.js +20 -0
- package/dist/tools/mm_store.js.map +1 -0
- package/dist/tools/mm_update.d.ts +10 -0
- package/dist/tools/mm_update.js +42 -0
- package/dist/tools/mm_update.js.map +1 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Arivoli Murugan
|
|
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,112 @@
|
|
|
1
|
+
# MoltMind
|
|
2
|
+
|
|
3
|
+
Persistent semantic memory for AI agents. One install, zero config, runs 100% locally.
|
|
4
|
+
|
|
5
|
+
MoltMind is an [MCP](https://modelcontextprotocol.io) server that gives your AI agent long-term memory. It stores learnings, decisions, error fixes, and handoff context across sessions using local SQLite and embeddings — no API keys, no cloud, no accounts needed.
|
|
6
|
+
|
|
7
|
+
## Quick Start
|
|
8
|
+
|
|
9
|
+
**Claude Code:**
|
|
10
|
+
```bash
|
|
11
|
+
npx -y moltmind # downloads and verifies
|
|
12
|
+
claude mcp add moltmind -- npx -y moltmind
|
|
13
|
+
# Restart Claude Code, then run /mcp to verify
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Cursor / Windsurf / Cline:**
|
|
17
|
+
Add to your MCP config:
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"mcpServers": {
|
|
21
|
+
"moltmind": {
|
|
22
|
+
"command": "npx",
|
|
23
|
+
"args": ["-y", "moltmind"]
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Tools
|
|
30
|
+
|
|
31
|
+
MoltMind provides 11 tools that your agent can use:
|
|
32
|
+
|
|
33
|
+
| Tool | Description |
|
|
34
|
+
|------|-------------|
|
|
35
|
+
| `mm_store` | Store a memory (learning, error fix, decision, plan, or raw note) |
|
|
36
|
+
| `mm_recall` | Search memories using natural language — hybrid semantic + keyword search |
|
|
37
|
+
| `mm_read` | Read a specific memory by ID |
|
|
38
|
+
| `mm_update` | Update title, content, tags, or type of an existing memory |
|
|
39
|
+
| `mm_delete` | Archive a memory (soft delete) |
|
|
40
|
+
| `mm_status` | Server health dashboard: DB stats, health score, uptime |
|
|
41
|
+
| `mm_init` | Create a project-local memory vault in the current directory |
|
|
42
|
+
| `mm_handoff_create` | Create a structured handoff for agent-to-agent context transfer |
|
|
43
|
+
| `mm_handoff_load` | Load the most recent handoff to resume context |
|
|
44
|
+
| `mm_feedback` | Report bugs, request features, or flag friction |
|
|
45
|
+
| `mm_metrics` | Full adoption and health metrics dashboard |
|
|
46
|
+
|
|
47
|
+
## How It Works
|
|
48
|
+
|
|
49
|
+
### Memory Storage
|
|
50
|
+
Memories are stored in a local SQLite database with full-text search (FTS5). Each memory has a type (`learning`, `error`, `decision`, `plan`, `raw`), tags, metadata, and a tier (`hot`, `warm`, `cold`, `archived`).
|
|
51
|
+
|
|
52
|
+
### Hybrid Search
|
|
53
|
+
When you use `mm_recall`, MoltMind runs two searches in parallel:
|
|
54
|
+
- **Semantic search** (weight: 0.7) — embeds your query with a local transformer model and finds similar memories by meaning
|
|
55
|
+
- **Keyword search** (weight: 0.3) — uses SQLite FTS5 for exact and partial word matches
|
|
56
|
+
|
|
57
|
+
Results are merged, deduplicated, and ranked by combined score. If the embedding model isn't available, it falls back to keyword-only search.
|
|
58
|
+
|
|
59
|
+
### Local Embeddings
|
|
60
|
+
MoltMind uses [Xenova/all-MiniLM-L6-v2](https://huggingface.co/Xenova/all-MiniLM-L6-v2) (~22MB) to generate 384-dimensional embeddings. The model downloads automatically on first use and is cached at `~/.moltmind/models/`.
|
|
61
|
+
|
|
62
|
+
### Memory Tiers
|
|
63
|
+
- **hot** — actively used, high relevance
|
|
64
|
+
- **warm** — less frequently accessed
|
|
65
|
+
- **cold** — rarely accessed but retained
|
|
66
|
+
- **archived** — soft-deleted, excluded from search
|
|
67
|
+
|
|
68
|
+
### Handoffs
|
|
69
|
+
`mm_handoff_create` captures structured context (goal, current state, next action, constraints, unknowns, artifacts, stop conditions) so a future session or different agent can pick up exactly where you left off.
|
|
70
|
+
|
|
71
|
+
### Diagnostics & Metrics
|
|
72
|
+
Every tool call is logged locally with latency and success/failure. `mm_status` shows a health score, and `mm_metrics` provides a full dashboard of adoption data, per-tool usage stats, and error rates. All data stays on your machine.
|
|
73
|
+
|
|
74
|
+
## Data Storage
|
|
75
|
+
|
|
76
|
+
| Path | Purpose |
|
|
77
|
+
|------|---------|
|
|
78
|
+
| `~/.moltmind/memory.db` | Global memory vault |
|
|
79
|
+
| `./.moltmind/memory.db` | Project-local vault (created by `mm_init`) |
|
|
80
|
+
| `~/.moltmind/models/` | Cached embedding model |
|
|
81
|
+
| `~/.moltmind/instance_id` | Anonymous instance identifier |
|
|
82
|
+
|
|
83
|
+
## Architecture
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
Agent (Claude Code / Cursor / any MCP client)
|
|
87
|
+
│
|
|
88
|
+
▼ (STDIO JSON-RPC)
|
|
89
|
+
┌─────────────────────────────────────┐
|
|
90
|
+
│ MCP Server (src/index.ts) │
|
|
91
|
+
│ 11 tools with zod validation │
|
|
92
|
+
│ withDiagnostics() on every call │
|
|
93
|
+
├─────────────────────────────────────┤
|
|
94
|
+
│ Embeddings │ Diagnostics │
|
|
95
|
+
│ MiniLM-L6-v2 │ Health score │
|
|
96
|
+
│ 384-dim vectors │ Feedback │
|
|
97
|
+
│ Graceful fallback │ Metrics │
|
|
98
|
+
├─────────────────────────────────────┤
|
|
99
|
+
│ SQLite + WAL + FTS5 │
|
|
100
|
+
│ Schema v2 with migrations │
|
|
101
|
+
└─────────────────────────────────────┘
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Requirements
|
|
105
|
+
|
|
106
|
+
- Node.js 18+
|
|
107
|
+
- No API keys required
|
|
108
|
+
- No internet required after first embedding model download
|
|
109
|
+
|
|
110
|
+
## License
|
|
111
|
+
|
|
112
|
+
MIT
|
package/dist/db.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import type { Memory, MemoryTier, Handoff } from "./types.js";
|
|
3
|
+
export declare function getDb(): Database.Database;
|
|
4
|
+
export declare function getDbSchemaVersion(): number;
|
|
5
|
+
export declare function closeDb(): void;
|
|
6
|
+
export declare function insertMemory(memory: Omit<Memory, "id" | "created_at" | "updated_at" | "accessed_at" | "access_count" | "decay_score"> & Partial<Pick<Memory, "id" | "created_at" | "updated_at" | "accessed_at" | "access_count" | "decay_score">>): Memory;
|
|
7
|
+
export declare function getMemory(id: string): Memory | null;
|
|
8
|
+
export declare function updateMemory(id: string, updates: Partial<Pick<Memory, "type" | "title" | "content" | "tags" | "metadata" | "embedding" | "tier" | "decay_score">>): Memory | null;
|
|
9
|
+
export declare function deleteMemory(id: string): boolean;
|
|
10
|
+
export declare function searchMemoriesFTS(query: string, limit?: number): Memory[];
|
|
11
|
+
export declare function getAllMemories(tier?: MemoryTier, limit?: number, includeArchived?: boolean): Memory[];
|
|
12
|
+
export declare function getMemoryStats(): {
|
|
13
|
+
total: number;
|
|
14
|
+
by_type: Record<string, number>;
|
|
15
|
+
by_tier: Record<string, number>;
|
|
16
|
+
};
|
|
17
|
+
export declare function insertHandoff(handoff: Omit<Handoff, "id" | "created_at"> & Partial<Pick<Handoff, "id" | "created_at">>): Handoff;
|
|
18
|
+
export declare function getLatestHandoff(): Handoff | null;
|
|
19
|
+
export declare function insertDiagnostic(toolName: string, success: boolean, latencyMs: number, errorMessage: string | null): void;
|
|
20
|
+
export declare function getDiagnosticsSummary(): Array<{
|
|
21
|
+
tool_name: string;
|
|
22
|
+
calls: number;
|
|
23
|
+
errors: number;
|
|
24
|
+
avg_latency_ms: number;
|
|
25
|
+
}>;
|
|
26
|
+
export declare function getRecentDiagnostics(limit?: number): Array<{
|
|
27
|
+
id: string;
|
|
28
|
+
tool_name: string;
|
|
29
|
+
success: number;
|
|
30
|
+
latency_ms: number;
|
|
31
|
+
error_message: string | null;
|
|
32
|
+
created_at: string;
|
|
33
|
+
}>;
|
|
34
|
+
export declare function getHealthScoreFromDb(): number;
|
|
35
|
+
export declare function insertFeedback(type: "bug" | "feature_request" | "friction", message: string, toolName?: string | null): void;
|
|
36
|
+
export declare function getRecentFeedback(limit?: number): Array<{
|
|
37
|
+
id: string;
|
|
38
|
+
type: string;
|
|
39
|
+
message: string;
|
|
40
|
+
tool_name: string | null;
|
|
41
|
+
created_at: string;
|
|
42
|
+
}>;
|
|
43
|
+
export declare function getMetric(key: string): string | null;
|
|
44
|
+
export declare function setMetric(key: string, value: string): void;
|
|
45
|
+
export declare function initProjectVault(): string;
|
package/dist/db.js
ADDED
|
@@ -0,0 +1,381 @@
|
|
|
1
|
+
import Database from "better-sqlite3";
|
|
2
|
+
import { mkdirSync, existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { homedir } from "node:os";
|
|
5
|
+
import crypto from "node:crypto";
|
|
6
|
+
const GLOBAL_DIR = join(homedir(), ".moltmind");
|
|
7
|
+
const GLOBAL_DB_PATH = join(GLOBAL_DIR, "memory.db");
|
|
8
|
+
const PROJECT_DIR = ".moltmind";
|
|
9
|
+
const PROJECT_DB_PATH = join(PROJECT_DIR, "memory.db");
|
|
10
|
+
let db = null;
|
|
11
|
+
function resolveDbPath() {
|
|
12
|
+
if (existsSync(PROJECT_DB_PATH)) {
|
|
13
|
+
return PROJECT_DB_PATH;
|
|
14
|
+
}
|
|
15
|
+
return GLOBAL_DB_PATH;
|
|
16
|
+
}
|
|
17
|
+
function ensureDir(dirPath) {
|
|
18
|
+
mkdirSync(dirPath, { recursive: true });
|
|
19
|
+
}
|
|
20
|
+
function getSchemaVersion(database) {
|
|
21
|
+
// Create meta table if it doesn't exist
|
|
22
|
+
database.exec("CREATE TABLE IF NOT EXISTS meta (key TEXT PRIMARY KEY, value TEXT)");
|
|
23
|
+
const row = database.prepare("SELECT value FROM meta WHERE key = 'schema_version'").get();
|
|
24
|
+
return row ? parseInt(row.value, 10) : 0;
|
|
25
|
+
}
|
|
26
|
+
function setSchemaVersion(database, version) {
|
|
27
|
+
database.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES ('schema_version', ?)").run(String(version));
|
|
28
|
+
}
|
|
29
|
+
function migrateV1(database) {
|
|
30
|
+
database.exec(`
|
|
31
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
32
|
+
id TEXT PRIMARY KEY,
|
|
33
|
+
type TEXT NOT NULL,
|
|
34
|
+
title TEXT NOT NULL,
|
|
35
|
+
content TEXT NOT NULL,
|
|
36
|
+
tags TEXT NOT NULL DEFAULT '[]',
|
|
37
|
+
metadata TEXT NOT NULL DEFAULT '{}',
|
|
38
|
+
embedding BLOB,
|
|
39
|
+
tier TEXT NOT NULL DEFAULT 'hot',
|
|
40
|
+
created_at TEXT NOT NULL,
|
|
41
|
+
updated_at TEXT NOT NULL,
|
|
42
|
+
accessed_at TEXT NOT NULL,
|
|
43
|
+
access_count INTEGER NOT NULL DEFAULT 0,
|
|
44
|
+
decay_score REAL NOT NULL DEFAULT 1.0
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
CREATE TABLE IF NOT EXISTS handoffs (
|
|
48
|
+
id TEXT PRIMARY KEY,
|
|
49
|
+
goal TEXT NOT NULL,
|
|
50
|
+
current_state TEXT NOT NULL,
|
|
51
|
+
next_action TEXT NOT NULL,
|
|
52
|
+
constraints TEXT NOT NULL DEFAULT '[]',
|
|
53
|
+
known_unknowns TEXT NOT NULL DEFAULT '[]',
|
|
54
|
+
artifacts TEXT NOT NULL DEFAULT '[]',
|
|
55
|
+
stop_conditions TEXT NOT NULL DEFAULT '[]',
|
|
56
|
+
session_id TEXT NOT NULL,
|
|
57
|
+
created_at TEXT NOT NULL
|
|
58
|
+
);
|
|
59
|
+
|
|
60
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
|
|
61
|
+
title,
|
|
62
|
+
content,
|
|
63
|
+
content=memories,
|
|
64
|
+
content_rowid=rowid
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
|
|
68
|
+
INSERT INTO memories_fts(rowid, title, content)
|
|
69
|
+
VALUES (new.rowid, new.title, new.content);
|
|
70
|
+
END;
|
|
71
|
+
|
|
72
|
+
CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
|
|
73
|
+
INSERT INTO memories_fts(memories_fts, rowid, title, content)
|
|
74
|
+
VALUES ('delete', old.rowid, old.title, old.content);
|
|
75
|
+
END;
|
|
76
|
+
|
|
77
|
+
CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN
|
|
78
|
+
INSERT INTO memories_fts(memories_fts, rowid, title, content)
|
|
79
|
+
VALUES ('delete', old.rowid, old.title, old.content);
|
|
80
|
+
INSERT INTO memories_fts(rowid, title, content)
|
|
81
|
+
VALUES (new.rowid, new.title, new.content);
|
|
82
|
+
END;
|
|
83
|
+
`);
|
|
84
|
+
}
|
|
85
|
+
function migrateV2(database) {
|
|
86
|
+
database.exec(`
|
|
87
|
+
CREATE TABLE IF NOT EXISTS diagnostics (
|
|
88
|
+
id TEXT PRIMARY KEY,
|
|
89
|
+
tool_name TEXT NOT NULL,
|
|
90
|
+
success INTEGER NOT NULL,
|
|
91
|
+
latency_ms REAL NOT NULL,
|
|
92
|
+
error_message TEXT,
|
|
93
|
+
created_at TEXT NOT NULL
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
CREATE TABLE IF NOT EXISTS feedback (
|
|
97
|
+
id TEXT PRIMARY KEY,
|
|
98
|
+
type TEXT NOT NULL CHECK(type IN ('bug','feature_request','friction')),
|
|
99
|
+
message TEXT NOT NULL,
|
|
100
|
+
tool_name TEXT,
|
|
101
|
+
created_at TEXT NOT NULL
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
CREATE TABLE IF NOT EXISTS metrics (
|
|
105
|
+
key TEXT PRIMARY KEY,
|
|
106
|
+
value TEXT NOT NULL,
|
|
107
|
+
updated_at TEXT NOT NULL
|
|
108
|
+
);
|
|
109
|
+
`);
|
|
110
|
+
}
|
|
111
|
+
const migrations = [
|
|
112
|
+
migrateV1,
|
|
113
|
+
migrateV2,
|
|
114
|
+
];
|
|
115
|
+
function migrate(database) {
|
|
116
|
+
const currentVersion = getSchemaVersion(database);
|
|
117
|
+
for (let i = currentVersion; i < migrations.length; i++) {
|
|
118
|
+
const txn = database.transaction(() => {
|
|
119
|
+
migrations[i](database);
|
|
120
|
+
setSchemaVersion(database, i + 1);
|
|
121
|
+
});
|
|
122
|
+
txn();
|
|
123
|
+
console.error(`MoltMind: migrated database to schema v${i + 1}`);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
export function getDb() {
|
|
127
|
+
if (db)
|
|
128
|
+
return db;
|
|
129
|
+
const dbPath = resolveDbPath();
|
|
130
|
+
const dir = dbPath === PROJECT_DB_PATH ? PROJECT_DIR : GLOBAL_DIR;
|
|
131
|
+
ensureDir(dir);
|
|
132
|
+
db = new Database(dbPath);
|
|
133
|
+
db.pragma("journal_mode = WAL");
|
|
134
|
+
migrate(db);
|
|
135
|
+
return db;
|
|
136
|
+
}
|
|
137
|
+
export function getDbSchemaVersion() {
|
|
138
|
+
const database = getDb();
|
|
139
|
+
return getSchemaVersion(database);
|
|
140
|
+
}
|
|
141
|
+
export function closeDb() {
|
|
142
|
+
if (db) {
|
|
143
|
+
db.close();
|
|
144
|
+
db = null;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
function rowToMemory(row) {
|
|
148
|
+
return {
|
|
149
|
+
id: row.id,
|
|
150
|
+
type: row.type,
|
|
151
|
+
title: row.title,
|
|
152
|
+
content: row.content,
|
|
153
|
+
tags: JSON.parse(row.tags),
|
|
154
|
+
metadata: JSON.parse(row.metadata),
|
|
155
|
+
embedding: row.embedding ?? null,
|
|
156
|
+
tier: row.tier,
|
|
157
|
+
created_at: row.created_at,
|
|
158
|
+
updated_at: row.updated_at,
|
|
159
|
+
accessed_at: row.accessed_at,
|
|
160
|
+
access_count: row.access_count,
|
|
161
|
+
decay_score: row.decay_score,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function rowToHandoff(row) {
|
|
165
|
+
return {
|
|
166
|
+
id: row.id,
|
|
167
|
+
goal: row.goal,
|
|
168
|
+
current_state: row.current_state,
|
|
169
|
+
next_action: row.next_action,
|
|
170
|
+
constraints: JSON.parse(row.constraints),
|
|
171
|
+
known_unknowns: JSON.parse(row.known_unknowns),
|
|
172
|
+
artifacts: JSON.parse(row.artifacts),
|
|
173
|
+
stop_conditions: JSON.parse(row.stop_conditions),
|
|
174
|
+
session_id: row.session_id,
|
|
175
|
+
created_at: row.created_at,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function getMemoryRaw(id) {
|
|
179
|
+
const database = getDb();
|
|
180
|
+
const row = database.prepare("SELECT * FROM memories WHERE id = ?").get(id);
|
|
181
|
+
if (!row)
|
|
182
|
+
return null;
|
|
183
|
+
return rowToMemory(row);
|
|
184
|
+
}
|
|
185
|
+
export function insertMemory(memory) {
|
|
186
|
+
const database = getDb();
|
|
187
|
+
const now = new Date().toISOString();
|
|
188
|
+
const id = memory.id ?? crypto.randomUUID();
|
|
189
|
+
const stmt = database.prepare(`
|
|
190
|
+
INSERT INTO memories (id, type, title, content, tags, metadata, embedding, tier, created_at, updated_at, accessed_at, access_count, decay_score)
|
|
191
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
192
|
+
`);
|
|
193
|
+
stmt.run(id, memory.type, memory.title, memory.content, JSON.stringify(memory.tags), JSON.stringify(memory.metadata), memory.embedding ?? null, memory.tier ?? "hot", memory.created_at ?? now, memory.updated_at ?? now, memory.accessed_at ?? now, memory.access_count ?? 0, memory.decay_score ?? 1.0);
|
|
194
|
+
return getMemoryRaw(id);
|
|
195
|
+
}
|
|
196
|
+
export function getMemory(id) {
|
|
197
|
+
const database = getDb();
|
|
198
|
+
const exists = database.prepare("SELECT id FROM memories WHERE id = ?").get(id);
|
|
199
|
+
if (!exists)
|
|
200
|
+
return null;
|
|
201
|
+
// Update accessed_at and access_count, then read the updated row
|
|
202
|
+
database.prepare("UPDATE memories SET accessed_at = ?, access_count = access_count + 1 WHERE id = ?").run(new Date().toISOString(), id);
|
|
203
|
+
const row = database.prepare("SELECT * FROM memories WHERE id = ?").get(id);
|
|
204
|
+
return rowToMemory(row);
|
|
205
|
+
}
|
|
206
|
+
export function updateMemory(id, updates) {
|
|
207
|
+
const database = getDb();
|
|
208
|
+
const existing = database.prepare("SELECT * FROM memories WHERE id = ?").get(id);
|
|
209
|
+
if (!existing)
|
|
210
|
+
return null;
|
|
211
|
+
const fields = [];
|
|
212
|
+
const values = [];
|
|
213
|
+
if (updates.type !== undefined) {
|
|
214
|
+
fields.push("type = ?");
|
|
215
|
+
values.push(updates.type);
|
|
216
|
+
}
|
|
217
|
+
if (updates.title !== undefined) {
|
|
218
|
+
fields.push("title = ?");
|
|
219
|
+
values.push(updates.title);
|
|
220
|
+
}
|
|
221
|
+
if (updates.content !== undefined) {
|
|
222
|
+
fields.push("content = ?");
|
|
223
|
+
values.push(updates.content);
|
|
224
|
+
}
|
|
225
|
+
if (updates.tags !== undefined) {
|
|
226
|
+
fields.push("tags = ?");
|
|
227
|
+
values.push(JSON.stringify(updates.tags));
|
|
228
|
+
}
|
|
229
|
+
if (updates.metadata !== undefined) {
|
|
230
|
+
fields.push("metadata = ?");
|
|
231
|
+
values.push(JSON.stringify(updates.metadata));
|
|
232
|
+
}
|
|
233
|
+
if (updates.embedding !== undefined) {
|
|
234
|
+
fields.push("embedding = ?");
|
|
235
|
+
values.push(updates.embedding);
|
|
236
|
+
}
|
|
237
|
+
if (updates.tier !== undefined) {
|
|
238
|
+
fields.push("tier = ?");
|
|
239
|
+
values.push(updates.tier);
|
|
240
|
+
}
|
|
241
|
+
if (updates.decay_score !== undefined) {
|
|
242
|
+
fields.push("decay_score = ?");
|
|
243
|
+
values.push(updates.decay_score);
|
|
244
|
+
}
|
|
245
|
+
if (fields.length === 0)
|
|
246
|
+
return rowToMemory(existing);
|
|
247
|
+
fields.push("updated_at = ?");
|
|
248
|
+
values.push(new Date().toISOString());
|
|
249
|
+
values.push(id);
|
|
250
|
+
database.prepare(`UPDATE memories SET ${fields.join(", ")} WHERE id = ?`).run(...values);
|
|
251
|
+
return getMemory(id);
|
|
252
|
+
}
|
|
253
|
+
export function deleteMemory(id) {
|
|
254
|
+
const database = getDb();
|
|
255
|
+
const existing = database.prepare("SELECT id FROM memories WHERE id = ?").get(id);
|
|
256
|
+
if (!existing)
|
|
257
|
+
return false;
|
|
258
|
+
database.prepare("UPDATE memories SET tier = 'archived', updated_at = ? WHERE id = ?").run(new Date().toISOString(), id);
|
|
259
|
+
return true;
|
|
260
|
+
}
|
|
261
|
+
export function searchMemoriesFTS(query, limit = 10) {
|
|
262
|
+
const database = getDb();
|
|
263
|
+
const rows = database.prepare(`
|
|
264
|
+
SELECT m.* FROM memories m
|
|
265
|
+
JOIN memories_fts fts ON m.rowid = fts.rowid
|
|
266
|
+
WHERE memories_fts MATCH ?
|
|
267
|
+
ORDER BY rank
|
|
268
|
+
LIMIT ?
|
|
269
|
+
`).all(query, limit);
|
|
270
|
+
return rows.map(rowToMemory);
|
|
271
|
+
}
|
|
272
|
+
export function getAllMemories(tier, limit = 100, includeArchived = false) {
|
|
273
|
+
const database = getDb();
|
|
274
|
+
if (tier) {
|
|
275
|
+
const rows = database.prepare("SELECT * FROM memories WHERE tier = ? ORDER BY updated_at DESC LIMIT ?").all(tier, limit);
|
|
276
|
+
return rows.map(rowToMemory);
|
|
277
|
+
}
|
|
278
|
+
if (includeArchived) {
|
|
279
|
+
const rows = database.prepare("SELECT * FROM memories ORDER BY updated_at DESC LIMIT ?").all(limit);
|
|
280
|
+
return rows.map(rowToMemory);
|
|
281
|
+
}
|
|
282
|
+
const rows = database.prepare("SELECT * FROM memories WHERE tier != 'archived' ORDER BY updated_at DESC LIMIT ?").all(limit);
|
|
283
|
+
return rows.map(rowToMemory);
|
|
284
|
+
}
|
|
285
|
+
export function getMemoryStats() {
|
|
286
|
+
const database = getDb();
|
|
287
|
+
const total = database.prepare("SELECT COUNT(*) as count FROM memories").get().count;
|
|
288
|
+
const typeRows = database.prepare("SELECT type, COUNT(*) as count FROM memories GROUP BY type").all();
|
|
289
|
+
const by_type = {};
|
|
290
|
+
for (const row of typeRows) {
|
|
291
|
+
by_type[row.type] = row.count;
|
|
292
|
+
}
|
|
293
|
+
const tierRows = database.prepare("SELECT tier, COUNT(*) as count FROM memories GROUP BY tier").all();
|
|
294
|
+
const by_tier = {};
|
|
295
|
+
for (const row of tierRows) {
|
|
296
|
+
by_tier[row.tier] = row.count;
|
|
297
|
+
}
|
|
298
|
+
return { total, by_type, by_tier };
|
|
299
|
+
}
|
|
300
|
+
export function insertHandoff(handoff) {
|
|
301
|
+
const database = getDb();
|
|
302
|
+
const now = new Date().toISOString();
|
|
303
|
+
const id = handoff.id ?? crypto.randomUUID();
|
|
304
|
+
database.prepare(`
|
|
305
|
+
INSERT INTO handoffs (id, goal, current_state, next_action, constraints, known_unknowns, artifacts, stop_conditions, session_id, created_at)
|
|
306
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
307
|
+
`).run(id, handoff.goal, handoff.current_state, handoff.next_action, JSON.stringify(handoff.constraints), JSON.stringify(handoff.known_unknowns), JSON.stringify(handoff.artifacts), JSON.stringify(handoff.stop_conditions), handoff.session_id, handoff.created_at ?? now);
|
|
308
|
+
return getLatestHandoff();
|
|
309
|
+
}
|
|
310
|
+
export function getLatestHandoff() {
|
|
311
|
+
const database = getDb();
|
|
312
|
+
const row = database.prepare("SELECT * FROM handoffs ORDER BY created_at DESC LIMIT 1").get();
|
|
313
|
+
if (!row)
|
|
314
|
+
return null;
|
|
315
|
+
return rowToHandoff(row);
|
|
316
|
+
}
|
|
317
|
+
// --- Diagnostics ---
|
|
318
|
+
export function insertDiagnostic(toolName, success, latencyMs, errorMessage) {
|
|
319
|
+
const database = getDb();
|
|
320
|
+
database.prepare(`
|
|
321
|
+
INSERT INTO diagnostics (id, tool_name, success, latency_ms, error_message, created_at)
|
|
322
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
323
|
+
`).run(crypto.randomUUID(), toolName, success ? 1 : 0, latencyMs, errorMessage, new Date().toISOString());
|
|
324
|
+
}
|
|
325
|
+
export function getDiagnosticsSummary() {
|
|
326
|
+
const database = getDb();
|
|
327
|
+
return database.prepare(`
|
|
328
|
+
SELECT
|
|
329
|
+
tool_name,
|
|
330
|
+
COUNT(*) as calls,
|
|
331
|
+
SUM(CASE WHEN success = 0 THEN 1 ELSE 0 END) as errors,
|
|
332
|
+
AVG(latency_ms) as avg_latency_ms
|
|
333
|
+
FROM diagnostics
|
|
334
|
+
GROUP BY tool_name
|
|
335
|
+
ORDER BY calls DESC
|
|
336
|
+
`).all();
|
|
337
|
+
}
|
|
338
|
+
export function getRecentDiagnostics(limit = 20) {
|
|
339
|
+
const database = getDb();
|
|
340
|
+
return database.prepare("SELECT * FROM diagnostics ORDER BY created_at DESC LIMIT ?").all(limit);
|
|
341
|
+
}
|
|
342
|
+
export function getHealthScoreFromDb() {
|
|
343
|
+
const database = getDb();
|
|
344
|
+
const rows = database.prepare("SELECT success FROM diagnostics ORDER BY created_at DESC LIMIT 100").all();
|
|
345
|
+
if (rows.length === 0)
|
|
346
|
+
return 1.0;
|
|
347
|
+
const successes = rows.filter((r) => r.success === 1).length;
|
|
348
|
+
return successes / rows.length;
|
|
349
|
+
}
|
|
350
|
+
// --- Feedback ---
|
|
351
|
+
export function insertFeedback(type, message, toolName = null) {
|
|
352
|
+
const database = getDb();
|
|
353
|
+
database.prepare(`
|
|
354
|
+
INSERT INTO feedback (id, type, message, tool_name, created_at)
|
|
355
|
+
VALUES (?, ?, ?, ?, ?)
|
|
356
|
+
`).run(crypto.randomUUID(), type, message, toolName, new Date().toISOString());
|
|
357
|
+
}
|
|
358
|
+
export function getRecentFeedback(limit = 10) {
|
|
359
|
+
const database = getDb();
|
|
360
|
+
return database.prepare("SELECT * FROM feedback ORDER BY created_at DESC LIMIT ?").all(limit);
|
|
361
|
+
}
|
|
362
|
+
// --- Metrics key/value ---
|
|
363
|
+
export function getMetric(key) {
|
|
364
|
+
const database = getDb();
|
|
365
|
+
const row = database.prepare("SELECT value FROM metrics WHERE key = ?").get(key);
|
|
366
|
+
return row ? row.value : null;
|
|
367
|
+
}
|
|
368
|
+
export function setMetric(key, value) {
|
|
369
|
+
const database = getDb();
|
|
370
|
+
database.prepare("INSERT OR REPLACE INTO metrics (key, value, updated_at) VALUES (?, ?, ?)").run(key, value, new Date().toISOString());
|
|
371
|
+
}
|
|
372
|
+
export function initProjectVault() {
|
|
373
|
+
ensureDir(PROJECT_DIR);
|
|
374
|
+
// Close existing connection and reopen with project DB
|
|
375
|
+
closeDb();
|
|
376
|
+
db = new Database(PROJECT_DB_PATH);
|
|
377
|
+
db.pragma("journal_mode = WAL");
|
|
378
|
+
migrate(db);
|
|
379
|
+
return PROJECT_DB_PATH;
|
|
380
|
+
}
|
|
381
|
+
//# sourceMappingURL=db.js.map
|
package/dist/db.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface ToolResult {
|
|
2
|
+
content: Array<{
|
|
3
|
+
type: "text";
|
|
4
|
+
text: string;
|
|
5
|
+
}>;
|
|
6
|
+
}
|
|
7
|
+
export declare function withDiagnostics(toolName: string, handler: () => Promise<ToolResult>): Promise<ToolResult>;
|
|
8
|
+
export declare function getHealthScore(): number;
|
|
9
|
+
export declare function getRecentDiagnostics(limit?: number): Array<{
|
|
10
|
+
id: string;
|
|
11
|
+
tool_name: string;
|
|
12
|
+
success: number;
|
|
13
|
+
latency_ms: number;
|
|
14
|
+
error_message: string | null;
|
|
15
|
+
created_at: string;
|
|
16
|
+
}>;
|
|
17
|
+
export declare function submitFeedback(type: "bug" | "feature_request" | "friction", message: string, toolName?: string | null): void;
|
|
18
|
+
export declare function getRecentFeedback(limit?: number): Array<{
|
|
19
|
+
id: string;
|
|
20
|
+
type: string;
|
|
21
|
+
message: string;
|
|
22
|
+
tool_name: string | null;
|
|
23
|
+
created_at: string;
|
|
24
|
+
}>;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { insertDiagnostic, getHealthScoreFromDb, getRecentDiagnostics as getRecentDiagnosticsDb, insertFeedback as insertFeedbackDb, getRecentFeedback as getRecentFeedbackDb, } from "./db.js";
|
|
2
|
+
export async function withDiagnostics(toolName, handler) {
|
|
3
|
+
const start = performance.now();
|
|
4
|
+
try {
|
|
5
|
+
const result = await handler();
|
|
6
|
+
insertDiagnostic(toolName, true, performance.now() - start, null);
|
|
7
|
+
return result;
|
|
8
|
+
}
|
|
9
|
+
catch (err) {
|
|
10
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
11
|
+
insertDiagnostic(toolName, false, performance.now() - start, msg);
|
|
12
|
+
return {
|
|
13
|
+
content: [{ type: "text", text: JSON.stringify({ success: false, message: msg }) }],
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export function getHealthScore() {
|
|
18
|
+
return getHealthScoreFromDb();
|
|
19
|
+
}
|
|
20
|
+
export function getRecentDiagnostics(limit = 20) {
|
|
21
|
+
return getRecentDiagnosticsDb(limit);
|
|
22
|
+
}
|
|
23
|
+
export function submitFeedback(type, message, toolName = null) {
|
|
24
|
+
insertFeedbackDb(type, message, toolName);
|
|
25
|
+
}
|
|
26
|
+
export function getRecentFeedback(limit = 10) {
|
|
27
|
+
return getRecentFeedbackDb(limit);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=diagnostics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,IAAI,sBAAsB,EAC9C,cAAc,IAAI,gBAAgB,EAClC,iBAAiB,IAAI,mBAAmB,GACzC,MAAM,SAAS,CAAC;AAMjB,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,QAAgB,EAChB,OAAkC;IAElC,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,OAAO,EAAE,CAAC;QAC/B,gBAAgB,CAAC,QAAQ,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC;QAClE,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,GAAG,EAAE,GAAG,KAAK,EAAE,GAAG,CAAC,CAAC;QAClE,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;SAC7F,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,oBAAoB,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,QAAgB,EAAE;IAQrD,OAAO,sBAAsB,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,cAAc,CAC5B,IAA4C,EAC5C,OAAe,EACf,WAA0B,IAAI;IAE9B,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE;IAOlD,OAAO,mBAAmB,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function embed(text: string): Promise<Float32Array | null>;
|
|
2
|
+
export declare function cosineSimilarity(a: Float32Array, b: Float32Array): number;
|
|
3
|
+
export declare function semanticSearch(query: string, memories: Array<{
|
|
4
|
+
id: string;
|
|
5
|
+
embedding: Buffer;
|
|
6
|
+
}>): Promise<Array<{
|
|
7
|
+
id: string;
|
|
8
|
+
score: number;
|
|
9
|
+
}>>;
|
|
10
|
+
export declare function embeddingToBuffer(embedding: Float32Array): Buffer;
|
|
11
|
+
export declare function bufferToEmbedding(buffer: Buffer): Float32Array;
|
|
12
|
+
export declare function isModelReady(): boolean;
|
|
13
|
+
export declare function _resetForTesting(): void;
|
|
14
|
+
export declare function _setModelFailed(): void;
|