@aman_asmuei/amem 0.7.1 → 0.8.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 +24 -3
- package/dist/cli.js +246 -68
- package/dist/cli.js.map +1 -1
- package/dist/dashboard.d.ts +2 -0
- package/dist/dashboard.js +563 -0
- package/dist/dashboard.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,7 +73,15 @@ No cloud. No API keys. Everything stays on your machine.
|
|
|
73
73
|
npm install -g @aman_asmuei/amem
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
-
### 2. Connect
|
|
76
|
+
### 2. Connect (auto)
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
amem-cli init # Auto-detects and configures all installed AI tools
|
|
80
|
+
amem-cli rules # Generates auto-extraction rules so your AI uses amem proactively
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
<details>
|
|
84
|
+
<summary><strong>Or configure manually</strong></summary>
|
|
77
85
|
|
|
78
86
|
<details open>
|
|
79
87
|
<summary><strong>Claude Code</strong> (one command)</summary>
|
|
@@ -110,6 +118,8 @@ Or add to `~/.claude/settings.json`:
|
|
|
110
118
|
|
|
111
119
|
</details>
|
|
112
120
|
|
|
121
|
+
</details>
|
|
122
|
+
|
|
113
123
|
### 3. Use
|
|
114
124
|
|
|
115
125
|
Restart your AI tool — you'll see **23 tools**, **6 resources**, and **2 prompts** ready to go.
|
|
@@ -118,6 +128,14 @@ Restart your AI tool — you'll see **23 tools**, **6 resources**, and **2 promp
|
|
|
118
128
|
|
|
119
129
|
## Features
|
|
120
130
|
|
|
131
|
+
### v0.8.0
|
|
132
|
+
|
|
133
|
+
| | Feature | Description |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| **NEW** | `amem init` | Auto-detect and configure Claude Code, Cursor, Windsurf, GitHub Copilot in one command |
|
|
136
|
+
| **NEW** | `amem rules` | Generate auto-extraction rules so your AI uses amem proactively (CLAUDE.md, .cursorrules, etc.) |
|
|
137
|
+
| **NEW** | `amem dashboard` | Beautiful dark-themed web dashboard — memory list, knowledge graph, stats, reminders, log |
|
|
138
|
+
|
|
121
139
|
### v0.7.0
|
|
122
140
|
|
|
123
141
|
| | Feature | Description |
|
|
@@ -449,6 +467,9 @@ score = relevance × recency × confidence × importance
|
|
|
449
467
|
## CLI
|
|
450
468
|
|
|
451
469
|
```bash
|
|
470
|
+
amem-cli init # Auto-configure AI tools
|
|
471
|
+
amem-cli rules # Generate auto-extraction rules
|
|
472
|
+
amem-cli dashboard # Open web dashboard
|
|
452
473
|
amem-cli recall "authentication" # Semantic search
|
|
453
474
|
amem-cli stats # Statistics
|
|
454
475
|
amem-cli list # List all memories
|
|
@@ -478,7 +499,7 @@ amem-cli forget abc12345 # Delete by short ID
|
|
|
478
499
|
| Database | SQLite + WAL + FTS5 |
|
|
479
500
|
| Embeddings | HuggingFace Xenova/all-MiniLM-L6-v2 (local, 80MB) |
|
|
480
501
|
| Validation | Zod 3.25+ with `.strict()` schemas |
|
|
481
|
-
| Testing | Vitest —
|
|
502
|
+
| Testing | Vitest — 262 tests across 17 suites |
|
|
482
503
|
| CI/CD | GitHub Actions → npm publish on release |
|
|
483
504
|
|
|
484
505
|
---
|
|
@@ -489,7 +510,7 @@ amem-cli forget abc12345 # Delete by short ID
|
|
|
489
510
|
git clone https://github.com/amanasmuei/amem.git
|
|
490
511
|
cd amem && npm install
|
|
491
512
|
npm run build # zero TS errors
|
|
492
|
-
npm test #
|
|
513
|
+
npm test # 262 tests pass
|
|
493
514
|
```
|
|
494
515
|
|
|
495
516
|
PRs must pass CI before merge. See [Issues](https://github.com/amanasmuei/amem/issues) for open tasks.
|
package/dist/cli.js
CHANGED
|
@@ -8,47 +8,99 @@ import os from "node:os";
|
|
|
8
8
|
import fs from "node:fs";
|
|
9
9
|
const AMEM_DIR = process.env.AMEM_DIR || path.join(os.homedir(), ".amem");
|
|
10
10
|
const DB_PATH = process.env.AMEM_DB || path.join(AMEM_DIR, "memory.db");
|
|
11
|
+
const AI_TOOLS = [
|
|
12
|
+
{ name: "Claude Code", configDir: path.join(os.homedir(), ".claude"), configFile: "settings.json", configKey: "mcpServers" },
|
|
13
|
+
{ name: "Cursor", configDir: path.join(os.homedir(), ".cursor"), configFile: "mcp.json", configKey: "mcpServers" },
|
|
14
|
+
{ name: "Windsurf", configDir: path.join(os.homedir(), ".windsurf"), configFile: "mcp.json", configKey: "mcpServers" },
|
|
15
|
+
{ name: "GitHub Copilot CLI", configDir: path.join(os.homedir(), ".github-copilot"), configFile: "mcp.json", configKey: "mcpServers" },
|
|
16
|
+
];
|
|
17
|
+
const RULES_TARGETS = [
|
|
18
|
+
{ name: "Claude Code", configDir: path.join(os.homedir(), ".claude"), rulesFile: "CLAUDE.md" },
|
|
19
|
+
{ name: "Cursor", configDir: path.join(os.homedir(), ".cursor"), rulesFile: ".cursorrules" },
|
|
20
|
+
{ name: "Windsurf", configDir: path.join(os.homedir(), ".windsurf"), rulesFile: ".windsurfrules" },
|
|
21
|
+
{ name: "GitHub Copilot", configDir: path.join(os.homedir(), ".github-copilot"), rulesFile: ".github/copilot-instructions.md", dirInProject: true },
|
|
22
|
+
];
|
|
23
|
+
function getFlag(args, long, short) {
|
|
24
|
+
for (let i = 0; i < args.length; i++) {
|
|
25
|
+
if ((args[i] === long || args[i] === short) && args[i + 1]) {
|
|
26
|
+
return args[i + 1];
|
|
27
|
+
}
|
|
28
|
+
if (args[i].startsWith(long + "=")) {
|
|
29
|
+
return args[i].slice(long.length + 1);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
// ── Command dispatch ────────────────────────────────────
|
|
11
35
|
const args = process.argv.slice(2);
|
|
12
36
|
const command = args[0];
|
|
13
37
|
if (!command || command === "help" || command === "--help" || command === "-h") {
|
|
14
38
|
printHelp();
|
|
15
39
|
process.exit(0);
|
|
16
40
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
process.exit(
|
|
41
|
+
// ── Commands that don't need a database ─────────────────
|
|
42
|
+
if (command === "init") {
|
|
43
|
+
handleInit(args.slice(1));
|
|
44
|
+
process.exit(0);
|
|
21
45
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
case "export":
|
|
33
|
-
handleExport(args.slice(1));
|
|
34
|
-
break;
|
|
35
|
-
case "forget":
|
|
36
|
-
case "delete":
|
|
37
|
-
handleForget(args.slice(1));
|
|
38
|
-
break;
|
|
39
|
-
case "list":
|
|
40
|
-
case "ls":
|
|
41
|
-
handleList(args.slice(1));
|
|
42
|
-
break;
|
|
43
|
-
default:
|
|
44
|
-
console.error(`Unknown command: ${command}`);
|
|
45
|
-
printHelp();
|
|
46
|
-
process.exit(1);
|
|
46
|
+
if (command === "rules") {
|
|
47
|
+
handleRules(args.slice(1));
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
// ── Commands that need a database ───────────────────────
|
|
51
|
+
if (command === "dashboard") {
|
|
52
|
+
if (!fs.existsSync(DB_PATH)) {
|
|
53
|
+
console.error(`No memory database found at ${DB_PATH}`);
|
|
54
|
+
console.error("Run 'amem init' first, or start the Amem MCP server.");
|
|
55
|
+
process.exit(1);
|
|
47
56
|
}
|
|
57
|
+
const { startDashboard } = await import("./dashboard.js");
|
|
58
|
+
const db = createDatabase(DB_PATH);
|
|
59
|
+
const portArg = args.find(a => a.startsWith("--port="));
|
|
60
|
+
const port = portArg ? parseInt(portArg.split("=")[1], 10) : 3333;
|
|
61
|
+
startDashboard(db, port);
|
|
62
|
+
// Dashboard keeps running — don't close db
|
|
48
63
|
}
|
|
49
|
-
|
|
50
|
-
|
|
64
|
+
else {
|
|
65
|
+
if (!fs.existsSync(DB_PATH)) {
|
|
66
|
+
console.error(`No memory database found at ${DB_PATH}`);
|
|
67
|
+
console.error("Start the Amem MCP server first, or set AMEM_DB to your database path.");
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
const db = createDatabase(DB_PATH);
|
|
71
|
+
try {
|
|
72
|
+
switch (command) {
|
|
73
|
+
case "recall":
|
|
74
|
+
case "search":
|
|
75
|
+
await handleRecall(db, args.slice(1));
|
|
76
|
+
break;
|
|
77
|
+
case "stats":
|
|
78
|
+
handleStats(db);
|
|
79
|
+
break;
|
|
80
|
+
case "export":
|
|
81
|
+
handleExport(db, args.slice(1));
|
|
82
|
+
break;
|
|
83
|
+
case "forget":
|
|
84
|
+
case "delete":
|
|
85
|
+
handleForget(db, args.slice(1));
|
|
86
|
+
break;
|
|
87
|
+
case "list":
|
|
88
|
+
case "ls":
|
|
89
|
+
handleList(db, args.slice(1));
|
|
90
|
+
break;
|
|
91
|
+
default:
|
|
92
|
+
console.error(`Unknown command: ${command}`);
|
|
93
|
+
printHelp();
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
finally {
|
|
98
|
+
db.close();
|
|
99
|
+
}
|
|
51
100
|
}
|
|
101
|
+
// ═══════════════════════════════════════════════════════════
|
|
102
|
+
// HELP
|
|
103
|
+
// ═══════════════════════════════════════════════════════════
|
|
52
104
|
function printHelp() {
|
|
53
105
|
console.log(`
|
|
54
106
|
amem — The memory layer for AI coding tools
|
|
@@ -56,12 +108,19 @@ amem — The memory layer for AI coding tools
|
|
|
56
108
|
USAGE
|
|
57
109
|
amem <command> [options]
|
|
58
110
|
|
|
59
|
-
|
|
111
|
+
SETUP
|
|
112
|
+
init Auto-configure amem for detected AI tools
|
|
113
|
+
rules [--tool NAME] Generate auto-extraction rules for AI tools
|
|
114
|
+
dashboard [--port=N] Open the memory dashboard in your browser (default: 3333)
|
|
115
|
+
|
|
116
|
+
MEMORY
|
|
60
117
|
recall <query> Search memories semantically
|
|
61
118
|
stats Show memory statistics
|
|
62
119
|
export [--file path] Export all memories as markdown
|
|
63
120
|
list [--type TYPE] List memories, optionally filtered by type
|
|
64
121
|
forget <id> Delete a memory by ID
|
|
122
|
+
|
|
123
|
+
OTHER
|
|
65
124
|
help Show this help
|
|
66
125
|
|
|
67
126
|
MEMORY TYPES
|
|
@@ -73,6 +132,9 @@ MEMORY TYPES
|
|
|
73
132
|
fact General knowledge (lowest priority)
|
|
74
133
|
|
|
75
134
|
EXAMPLES
|
|
135
|
+
amem init
|
|
136
|
+
amem rules
|
|
137
|
+
amem dashboard
|
|
76
138
|
amem recall "authentication approach"
|
|
77
139
|
amem stats
|
|
78
140
|
amem list --type correction
|
|
@@ -80,7 +142,147 @@ EXAMPLES
|
|
|
80
142
|
amem forget abc12345
|
|
81
143
|
`.trim());
|
|
82
144
|
}
|
|
83
|
-
|
|
145
|
+
// ═══════════════════════════════════════════════════════════
|
|
146
|
+
// INIT — Auto-configure AI tools
|
|
147
|
+
// ═══════════════════════════════════════════════════════════
|
|
148
|
+
function handleInit(args) {
|
|
149
|
+
const toolFilter = getFlag(args, "--tool", "-t");
|
|
150
|
+
let configured = 0;
|
|
151
|
+
let skipped = 0;
|
|
152
|
+
console.log("Detecting AI tools...\n");
|
|
153
|
+
for (const tool of AI_TOOLS) {
|
|
154
|
+
if (toolFilter && !tool.name.toLowerCase().includes(toolFilter.toLowerCase()))
|
|
155
|
+
continue;
|
|
156
|
+
if (!fs.existsSync(tool.configDir)) {
|
|
157
|
+
console.log(` \u2717 ${tool.name} — not installed`);
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
const configPath = path.join(tool.configDir, tool.configFile);
|
|
161
|
+
let config = {};
|
|
162
|
+
if (fs.existsSync(configPath)) {
|
|
163
|
+
try {
|
|
164
|
+
config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
console.log(` \u2717 ${tool.name} — could not parse ${tool.configFile}`);
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
const servers = (config[tool.configKey] ?? {});
|
|
172
|
+
if (servers.amem) {
|
|
173
|
+
console.log(` \u2713 ${tool.name} — already configured`);
|
|
174
|
+
skipped++;
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
servers.amem = {
|
|
178
|
+
command: "npx",
|
|
179
|
+
args: ["-y", "@aman_asmuei/amem"],
|
|
180
|
+
};
|
|
181
|
+
config[tool.configKey] = servers;
|
|
182
|
+
fs.mkdirSync(path.dirname(configPath), { recursive: true });
|
|
183
|
+
fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
184
|
+
console.log(` \u2713 ${tool.name} — configured (${configPath})`);
|
|
185
|
+
configured++;
|
|
186
|
+
}
|
|
187
|
+
console.log();
|
|
188
|
+
if (configured > 0) {
|
|
189
|
+
console.log(`Configured ${configured} tool${configured > 1 ? "s" : ""}. Restart your AI tools to activate amem.`);
|
|
190
|
+
}
|
|
191
|
+
else if (skipped > 0) {
|
|
192
|
+
console.log("All detected tools are already configured.");
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
console.log("No supported AI tools detected. Install Claude Code, Cursor, Windsurf, or GitHub Copilot CLI first.");
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
// ═══════════════════════════════════════════════════════════
|
|
199
|
+
// RULES — Generate auto-extraction rules
|
|
200
|
+
// ═══════════════════════════════════════════════════════════
|
|
201
|
+
function getRulesContent() {
|
|
202
|
+
return `# Amem — Persistent Memory Rules
|
|
203
|
+
|
|
204
|
+
You have access to **amem**, a persistent memory system via MCP. Use it proactively.
|
|
205
|
+
|
|
206
|
+
## Session Start
|
|
207
|
+
1. Call \`memory_inject\` with the current task topic — surfaces corrections (hard constraints) and decisions
|
|
208
|
+
2. Call \`reminder_check\` — shows overdue and upcoming reminders
|
|
209
|
+
3. Call \`memory_context\` for broader background if needed
|
|
210
|
+
|
|
211
|
+
## During Conversation
|
|
212
|
+
- **User corrects you** → \`memory_store\` as \`correction\` (confidence: 1.0)
|
|
213
|
+
- **Architecture decision made** → \`memory_store\` as \`decision\` (confidence: 0.9)
|
|
214
|
+
- **Coding pattern observed** → \`memory_store\` as \`pattern\` (confidence: 0.7)
|
|
215
|
+
- **Tool/style preference expressed** → \`memory_store\` as \`preference\` (confidence: 0.8)
|
|
216
|
+
- **Codebase location revealed** → \`memory_store\` as \`topology\` (confidence: 0.7)
|
|
217
|
+
- **Project fact established** → \`memory_store\` as \`fact\` (confidence: 0.6)
|
|
218
|
+
|
|
219
|
+
## Every ~10 Exchanges
|
|
220
|
+
Call \`memory_extract\` with a batch of memories from the conversation so far.
|
|
221
|
+
|
|
222
|
+
## Before Ending
|
|
223
|
+
Call \`memory_extract\` to capture any remaining insights.
|
|
224
|
+
|
|
225
|
+
## Rules
|
|
226
|
+
- **Corrections override everything** — always check for them before acting
|
|
227
|
+
- **Be specific** — "Uses Tailwind with custom theme in src/styles" not "Has CSS"
|
|
228
|
+
- **Be self-contained** — each memory should make sense without conversation context
|
|
229
|
+
- **Never store** — API keys, passwords, ephemeral task details, or exact file contents
|
|
230
|
+
- **Check before storing** — use \`memory_recall\` to avoid duplicates
|
|
231
|
+
- **Link related memories** — use \`memory_relate\` to build the knowledge graph
|
|
232
|
+
- **Reference naturally** — say "I remember you prefer X" not "My memory database says..."
|
|
233
|
+
`.trimEnd();
|
|
234
|
+
}
|
|
235
|
+
function handleRules(args) {
|
|
236
|
+
const toolFilter = getFlag(args, "--tool", "-t");
|
|
237
|
+
const customPath = getFlag(args, "--path", "-p");
|
|
238
|
+
if (customPath) {
|
|
239
|
+
const dir = path.dirname(customPath);
|
|
240
|
+
if (dir !== ".")
|
|
241
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
242
|
+
fs.writeFileSync(customPath, getRulesContent() + "\n");
|
|
243
|
+
console.log(`\u2713 Rules written to ${customPath}`);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
let written = 0;
|
|
247
|
+
console.log("Generating amem rules...\n");
|
|
248
|
+
for (const target of RULES_TARGETS) {
|
|
249
|
+
if (toolFilter && !target.name.toLowerCase().includes(toolFilter.toLowerCase()))
|
|
250
|
+
continue;
|
|
251
|
+
if (!fs.existsSync(target.configDir)) {
|
|
252
|
+
console.log(` \u2717 ${target.name} — not installed`);
|
|
253
|
+
continue;
|
|
254
|
+
}
|
|
255
|
+
const rulesPath = target.dirInProject
|
|
256
|
+
? path.resolve(target.rulesFile)
|
|
257
|
+
: path.resolve(target.rulesFile);
|
|
258
|
+
// Don't overwrite existing rules files — append amem section
|
|
259
|
+
if (fs.existsSync(rulesPath)) {
|
|
260
|
+
const existing = fs.readFileSync(rulesPath, "utf-8");
|
|
261
|
+
if (existing.includes("amem") || existing.includes("memory_inject")) {
|
|
262
|
+
console.log(` \u2713 ${target.name} — already has amem rules (${target.rulesFile})`);
|
|
263
|
+
continue;
|
|
264
|
+
}
|
|
265
|
+
fs.writeFileSync(rulesPath, existing + "\n\n" + getRulesContent() + "\n");
|
|
266
|
+
console.log(` \u2713 ${target.name} — appended to ${target.rulesFile}`);
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
const dir = path.dirname(rulesPath);
|
|
270
|
+
if (dir !== ".")
|
|
271
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
272
|
+
fs.writeFileSync(rulesPath, getRulesContent() + "\n");
|
|
273
|
+
console.log(` \u2713 ${target.name} — created ${target.rulesFile}`);
|
|
274
|
+
}
|
|
275
|
+
written++;
|
|
276
|
+
}
|
|
277
|
+
console.log();
|
|
278
|
+
if (written > 0) {
|
|
279
|
+
console.log(`Generated rules for ${written} tool${written > 1 ? "s" : ""}. Your AI will now use amem proactively.`);
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
console.log("No rules written. Use --path to write to a custom location.");
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
async function handleRecall(db, args) {
|
|
84
286
|
const query = args.join(" ");
|
|
85
287
|
if (!query) {
|
|
86
288
|
console.error("Usage: amem recall <query>");
|
|
@@ -110,9 +312,9 @@ async function handleRecall(args) {
|
|
|
110
312
|
}
|
|
111
313
|
console.log(`${results.length} memories found.`);
|
|
112
314
|
}
|
|
113
|
-
function handleStats() {
|
|
315
|
+
function handleStats(db) {
|
|
114
316
|
const stats = db.getStats();
|
|
115
|
-
const
|
|
317
|
+
const confStats = db.getConfidenceStats();
|
|
116
318
|
console.log("Amem Memory Statistics\n");
|
|
117
319
|
console.log(` Total memories: ${stats.total}`);
|
|
118
320
|
console.log(` Database: ${DB_PATH}`);
|
|
@@ -130,34 +332,16 @@ function handleStats() {
|
|
|
130
332
|
}
|
|
131
333
|
}
|
|
132
334
|
console.log();
|
|
133
|
-
// Confidence distribution
|
|
134
|
-
const highConf = all.filter(m => m.confidence >= 0.8).length;
|
|
135
|
-
const medConf = all.filter(m => m.confidence >= 0.5 && m.confidence < 0.8).length;
|
|
136
|
-
const lowConf = all.filter(m => m.confidence < 0.5).length;
|
|
137
335
|
console.log(" Confidence:");
|
|
138
|
-
console.log(` High (\u226580%) ${
|
|
139
|
-
console.log(` Medium (50-79%) ${
|
|
140
|
-
console.log(` Low (<50%) ${
|
|
336
|
+
console.log(` High (\u226580%) ${confStats.high}`);
|
|
337
|
+
console.log(` Medium (50-79%) ${confStats.medium}`);
|
|
338
|
+
console.log(` Low (<50%) ${confStats.low}`);
|
|
141
339
|
console.log();
|
|
142
|
-
|
|
143
|
-
const withEmbeddings = db.getAllWithEmbeddings().length;
|
|
340
|
+
const withEmbeddings = db.getEmbeddingCount();
|
|
144
341
|
console.log(` Embeddings: ${withEmbeddings}/${stats.total} memories have embeddings`);
|
|
145
|
-
// Age stats
|
|
146
|
-
if (all.length > 0) {
|
|
147
|
-
const oldest = Math.min(...all.map(m => m.createdAt));
|
|
148
|
-
const newest = Math.max(...all.map(m => m.createdAt));
|
|
149
|
-
console.log(` Oldest memory: ${formatAge(oldest)}`);
|
|
150
|
-
console.log(` Newest memory: ${formatAge(newest)}`);
|
|
151
|
-
}
|
|
152
342
|
}
|
|
153
|
-
function handleExport(args) {
|
|
154
|
-
|
|
155
|
-
for (let i = 0; i < args.length; i++) {
|
|
156
|
-
if ((args[i] === "--file" || args[i] === "-f") && args[i + 1]) {
|
|
157
|
-
outputPath = args[i + 1];
|
|
158
|
-
break;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
343
|
+
function handleExport(db, args) {
|
|
344
|
+
const outputPath = getFlag(args, "--file", "-f");
|
|
161
345
|
const all = db.getAll();
|
|
162
346
|
if (all.length === 0) {
|
|
163
347
|
console.log("No memories to export.");
|
|
@@ -186,14 +370,8 @@ function handleExport(args) {
|
|
|
186
370
|
process.stdout.write(md);
|
|
187
371
|
}
|
|
188
372
|
}
|
|
189
|
-
function handleList(args) {
|
|
190
|
-
|
|
191
|
-
for (let i = 0; i < args.length; i++) {
|
|
192
|
-
if ((args[i] === "--type" || args[i] === "-t") && args[i + 1]) {
|
|
193
|
-
typeFilter = args[i + 1];
|
|
194
|
-
break;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
373
|
+
function handleList(db, args) {
|
|
374
|
+
const typeFilter = getFlag(args, "--type", "-t");
|
|
197
375
|
let memories;
|
|
198
376
|
if (typeFilter) {
|
|
199
377
|
const validTypes = Object.values(MemoryType);
|
|
@@ -217,7 +395,7 @@ function handleList(args) {
|
|
|
217
395
|
}
|
|
218
396
|
console.log(`\n${memories.length} memories.`);
|
|
219
397
|
}
|
|
220
|
-
function handleForget(args) {
|
|
398
|
+
function handleForget(db, args) {
|
|
221
399
|
const id = args[0];
|
|
222
400
|
if (!id) {
|
|
223
401
|
console.error("Usage: amem forget <memory-id>");
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,563 @@
|
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import { execFile } from "node:child_process";
|
|
3
|
+
import { MemoryType } from "./memory.js";
|
|
4
|
+
// ---------------------------------------------------------------------------
|
|
5
|
+
// HTML Dashboard — single-page app with embedded CSS + JS
|
|
6
|
+
// All user-facing strings are escaped via the esc() helper which uses
|
|
7
|
+
// textContent assignment (safe against XSS) before reading innerHTML.
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
const DASHBOARD_HTML = `<!DOCTYPE html>
|
|
10
|
+
<html lang="en">
|
|
11
|
+
<head>
|
|
12
|
+
<meta charset="utf-8"/>
|
|
13
|
+
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
|
14
|
+
<title>amem dashboard</title>
|
|
15
|
+
<style>
|
|
16
|
+
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
|
|
17
|
+
:root{
|
|
18
|
+
--bg:#0d1117;--card:#161b22;--border:#30363d;--text:#c9d1d9;--muted:#8b949e;
|
|
19
|
+
--correction:#f85149;--decision:#58a6ff;--pattern:#bc8cff;
|
|
20
|
+
--preference:#3fb950;--topology:#d2a8ff;--fact:#8b949e;
|
|
21
|
+
--radius:8px;
|
|
22
|
+
}
|
|
23
|
+
html{font-size:14px}
|
|
24
|
+
body{background:var(--bg);color:var(--text);font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;line-height:1.5;min-width:1024px}
|
|
25
|
+
code,.mono{font-family:'JetBrains Mono','Fira Code',monospace;font-size:0.85em}
|
|
26
|
+
a{color:var(--decision);text-decoration:none}
|
|
27
|
+
|
|
28
|
+
/* layout */
|
|
29
|
+
.dashboard{display:grid;grid-template-columns:1fr 1fr;gap:16px;padding:24px;max-width:1440px;margin:0 auto}
|
|
30
|
+
.full{grid-column:1/-1}
|
|
31
|
+
|
|
32
|
+
/* header */
|
|
33
|
+
.header{display:flex;align-items:center;justify-content:space-between;padding:20px 24px;background:var(--card);border:1px solid var(--border);border-radius:var(--radius)}
|
|
34
|
+
.header h1{font-size:1.4rem;font-weight:600;letter-spacing:-0.02em}
|
|
35
|
+
.header h1 span{color:var(--decision);font-weight:700}
|
|
36
|
+
.stat-pills{display:flex;gap:12px}
|
|
37
|
+
.pill{background:var(--bg);border:1px solid var(--border);border-radius:20px;padding:4px 14px;font-size:0.85rem;white-space:nowrap}
|
|
38
|
+
.pill b{color:var(--decision)}
|
|
39
|
+
|
|
40
|
+
/* cards */
|
|
41
|
+
.card{background:var(--card);border:1px solid var(--border);border-radius:var(--radius);padding:20px;overflow:hidden}
|
|
42
|
+
.card h2{font-size:1rem;font-weight:600;margin-bottom:14px;color:var(--muted);text-transform:uppercase;letter-spacing:0.05em;font-size:0.75rem}
|
|
43
|
+
|
|
44
|
+
/* bars */
|
|
45
|
+
.bar-row{display:flex;align-items:center;gap:10px;margin-bottom:8px;font-size:0.85rem}
|
|
46
|
+
.bar-label{width:90px;text-align:right;color:var(--muted);flex-shrink:0}
|
|
47
|
+
.bar-track{flex:1;height:22px;background:var(--bg);border-radius:4px;overflow:hidden;position:relative}
|
|
48
|
+
.bar-fill{height:100%;border-radius:4px;transition:width .4s ease}
|
|
49
|
+
.bar-value{width:40px;text-align:right;font-weight:600;flex-shrink:0}
|
|
50
|
+
|
|
51
|
+
/* confidence bars */
|
|
52
|
+
.conf-bar{display:flex;gap:8px;align-items:center;margin-bottom:8px}
|
|
53
|
+
.conf-bar .label{width:70px;text-align:right;font-size:0.8rem;color:var(--muted)}
|
|
54
|
+
.conf-bar .track{flex:1;height:26px;background:var(--bg);border-radius:4px;overflow:hidden}
|
|
55
|
+
.conf-bar .fill{height:100%;border-radius:4px;display:flex;align-items:center;padding-left:10px;font-size:0.8rem;font-weight:600;color:#fff;transition:width .4s ease}
|
|
56
|
+
.conf-high{background:var(--preference)}
|
|
57
|
+
.conf-med{background:var(--decision)}
|
|
58
|
+
.conf-low{background:var(--correction)}
|
|
59
|
+
|
|
60
|
+
/* memory list */
|
|
61
|
+
.mem-controls{display:flex;gap:10px;margin-bottom:14px}
|
|
62
|
+
.mem-controls input,.mem-controls select{background:var(--bg);border:1px solid var(--border);color:var(--text);border-radius:6px;padding:8px 12px;font-size:0.85rem;outline:none}
|
|
63
|
+
.mem-controls input:focus,.mem-controls select:focus{border-color:var(--decision)}
|
|
64
|
+
.mem-controls input{flex:1}
|
|
65
|
+
.mem-list{max-height:420px;overflow-y:auto;display:flex;flex-direction:column;gap:8px}
|
|
66
|
+
.mem-list::-webkit-scrollbar{width:6px}
|
|
67
|
+
.mem-list::-webkit-scrollbar-track{background:transparent}
|
|
68
|
+
.mem-list::-webkit-scrollbar-thumb{background:var(--border);border-radius:3px}
|
|
69
|
+
.mem-card{background:var(--bg);border:1px solid var(--border);border-radius:6px;padding:12px 14px}
|
|
70
|
+
.mem-card .mem-head{display:flex;align-items:center;gap:8px;margin-bottom:4px}
|
|
71
|
+
.type-badge{display:inline-block;padding:2px 8px;border-radius:10px;font-size:0.7rem;font-weight:700;text-transform:uppercase;letter-spacing:0.04em;color:#fff}
|
|
72
|
+
.mem-card .mem-content{font-size:0.9rem;margin-bottom:6px;line-height:1.5}
|
|
73
|
+
.mem-card .mem-meta{display:flex;gap:14px;font-size:0.75rem;color:var(--muted);flex-wrap:wrap}
|
|
74
|
+
.mem-card .mem-meta .tag{background:var(--card);border:1px solid var(--border);border-radius:4px;padding:1px 6px}
|
|
75
|
+
|
|
76
|
+
/* knowledge graph */
|
|
77
|
+
#graph-svg{width:100%;height:360px;border-radius:6px;background:var(--bg)}
|
|
78
|
+
|
|
79
|
+
/* reminders */
|
|
80
|
+
.reminder-list{max-height:360px;overflow-y:auto;display:flex;flex-direction:column;gap:6px}
|
|
81
|
+
.reminder-item{display:flex;align-items:flex-start;gap:8px;font-size:0.85rem;padding:8px 10px;background:var(--bg);border-radius:6px;border:1px solid var(--border)}
|
|
82
|
+
.reminder-status{flex-shrink:0;padding:2px 8px;border-radius:4px;font-size:0.7rem;font-weight:700;text-transform:uppercase}
|
|
83
|
+
.status-overdue{background:var(--correction);color:#fff}
|
|
84
|
+
.status-today{background:var(--decision);color:#fff}
|
|
85
|
+
.status-upcoming{background:var(--preference);color:#fff}
|
|
86
|
+
.status-completed{background:var(--border);color:var(--muted)}
|
|
87
|
+
.reminder-content{flex:1}
|
|
88
|
+
|
|
89
|
+
/* log */
|
|
90
|
+
.log-list{max-height:300px;overflow-y:auto;display:flex;flex-direction:column;gap:4px}
|
|
91
|
+
.log-entry{display:flex;gap:10px;font-size:0.85rem;padding:6px 10px;background:var(--bg);border-radius:4px}
|
|
92
|
+
.log-role{flex-shrink:0;width:70px;font-weight:600;text-align:right}
|
|
93
|
+
.log-role.user{color:var(--decision)}
|
|
94
|
+
.log-role.assistant{color:var(--preference)}
|
|
95
|
+
.log-role.system{color:var(--muted)}
|
|
96
|
+
.log-content{flex:1;word-break:break-word}
|
|
97
|
+
.log-time{flex-shrink:0;color:var(--muted);font-size:0.75rem;white-space:nowrap}
|
|
98
|
+
|
|
99
|
+
.empty{color:var(--muted);font-style:italic;font-size:0.85rem;padding:20px 0;text-align:center}
|
|
100
|
+
</style>
|
|
101
|
+
</head>
|
|
102
|
+
<body>
|
|
103
|
+
<div class="dashboard">
|
|
104
|
+
<!-- Header -->
|
|
105
|
+
<div class="header full" id="header">
|
|
106
|
+
<h1><span>amem</span> dashboard</h1>
|
|
107
|
+
<div class="stat-pills" id="stat-pills"></div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<!-- Type breakdown -->
|
|
111
|
+
<div class="card" id="type-card">
|
|
112
|
+
<h2>Memory Types</h2>
|
|
113
|
+
<div id="type-bars"></div>
|
|
114
|
+
</div>
|
|
115
|
+
|
|
116
|
+
<!-- Confidence distribution -->
|
|
117
|
+
<div class="card" id="conf-card">
|
|
118
|
+
<h2>Confidence Distribution</h2>
|
|
119
|
+
<div id="conf-bars"></div>
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<!-- Memory list -->
|
|
123
|
+
<div class="card full" id="mem-section">
|
|
124
|
+
<h2>Memories</h2>
|
|
125
|
+
<div class="mem-controls">
|
|
126
|
+
<input type="text" id="mem-search" placeholder="Search memories..."/>
|
|
127
|
+
<select id="mem-type">
|
|
128
|
+
<option value="">All types</option>
|
|
129
|
+
<option value="correction">correction</option>
|
|
130
|
+
<option value="decision">decision</option>
|
|
131
|
+
<option value="pattern">pattern</option>
|
|
132
|
+
<option value="preference">preference</option>
|
|
133
|
+
<option value="topology">topology</option>
|
|
134
|
+
<option value="fact">fact</option>
|
|
135
|
+
</select>
|
|
136
|
+
</div>
|
|
137
|
+
<div class="mem-list" id="mem-list"></div>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<!-- Knowledge graph -->
|
|
141
|
+
<div class="card" id="graph-card">
|
|
142
|
+
<h2>Knowledge Graph</h2>
|
|
143
|
+
<svg id="graph-svg"></svg>
|
|
144
|
+
</div>
|
|
145
|
+
|
|
146
|
+
<!-- Reminders -->
|
|
147
|
+
<div class="card" id="reminder-card">
|
|
148
|
+
<h2>Reminders</h2>
|
|
149
|
+
<div class="reminder-list" id="reminder-list"></div>
|
|
150
|
+
</div>
|
|
151
|
+
|
|
152
|
+
<!-- Recent log -->
|
|
153
|
+
<div class="card full" id="log-card">
|
|
154
|
+
<h2>Recent Log</h2>
|
|
155
|
+
<div class="log-list" id="log-list"></div>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
|
|
159
|
+
<script>
|
|
160
|
+
// All dynamic text is escaped via esc() which uses textContent (XSS-safe).
|
|
161
|
+
(function(){
|
|
162
|
+
var TYPE_COLORS = {
|
|
163
|
+
correction:'#f85149',decision:'#58a6ff',pattern:'#bc8cff',
|
|
164
|
+
preference:'#3fb950',topology:'#d2a8ff',fact:'#8b949e'
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
var allMemories = [];
|
|
168
|
+
|
|
169
|
+
// -- Helpers --
|
|
170
|
+
function timeAgo(ts){
|
|
171
|
+
var s = Math.floor((Date.now()-ts)/1000);
|
|
172
|
+
if(s<60) return s+'s ago';
|
|
173
|
+
var m=Math.floor(s/60); if(m<60) return m+'m ago';
|
|
174
|
+
var h=Math.floor(m/60); if(h<24) return h+'h ago';
|
|
175
|
+
var d=Math.floor(h/24); if(d<30) return d+'d ago';
|
|
176
|
+
return new Date(ts).toLocaleDateString();
|
|
177
|
+
}
|
|
178
|
+
// XSS-safe escaping: assigns to textContent then reads back as HTML-encoded
|
|
179
|
+
function esc(s){var d=document.createElement('div');d.textContent=s;return d.innerHTML}
|
|
180
|
+
function $(id){return document.getElementById(id)}
|
|
181
|
+
|
|
182
|
+
// Safe DOM update helper — sets sanitized HTML built from escaped strings
|
|
183
|
+
function setHTML(el, html){ el.innerHTML = html; }
|
|
184
|
+
|
|
185
|
+
// -- Rendering --
|
|
186
|
+
function renderStats(stats){
|
|
187
|
+
var pills=$('stat-pills');
|
|
188
|
+
setHTML(pills,
|
|
189
|
+
'<div class="pill"><b>'+stats.total+'</b> memories</div>'+
|
|
190
|
+
'<div class="pill"><b>'+stats.embeddings+'</b> embeddings</div>'+
|
|
191
|
+
'<div class="pill"><b>'+(stats.confidence.high+stats.confidence.medium+stats.confidence.low)+'</b> scored</div>');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function renderTypeBars(byType){
|
|
195
|
+
var el=$('type-bars');
|
|
196
|
+
var max=Math.max(1,Math.max.apply(null,Object.keys(byType).map(function(k){return byType[k]})));
|
|
197
|
+
setHTML(el, Object.keys(byType).map(function(key){
|
|
198
|
+
var val=byType[key];
|
|
199
|
+
var pct=Math.round(val/max*100);
|
|
200
|
+
return '<div class="bar-row">'+
|
|
201
|
+
'<span class="bar-label">'+esc(key)+'</span>'+
|
|
202
|
+
'<div class="bar-track"><div class="bar-fill" style="width:'+pct+'%;background:'+(TYPE_COLORS[key]||'#8b949e')+'"></div></div>'+
|
|
203
|
+
'<span class="bar-value">'+val+'</span></div>';
|
|
204
|
+
}).join(''));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function renderConfBars(conf){
|
|
208
|
+
var total=Math.max(1,conf.high+conf.medium+conf.low);
|
|
209
|
+
function bar(label,val,cls){
|
|
210
|
+
var pct=Math.round(val/total*100);
|
|
211
|
+
return '<div class="conf-bar"><span class="label">'+esc(label)+'</span>'+
|
|
212
|
+
'<div class="track"><div class="fill '+cls+'" style="width:'+pct+'%">'+val+' ('+pct+'%)</div></div></div>';
|
|
213
|
+
}
|
|
214
|
+
setHTML($('conf-bars'), bar('High',conf.high,'conf-high')+bar('Medium',conf.medium,'conf-med')+bar('Low',conf.low,'conf-low'));
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function renderMemories(memories){
|
|
218
|
+
var el=$('mem-list');
|
|
219
|
+
if(!memories.length){setHTML(el,'<div class="empty">No memories found</div>');return}
|
|
220
|
+
setHTML(el, memories.slice(0,50).map(function(m){
|
|
221
|
+
var color=TYPE_COLORS[m.type]||'#8b949e';
|
|
222
|
+
var tags=(m.tags||[]).map(function(t){return '<span class="tag">#'+esc(t)+'</span>'}).join(' ');
|
|
223
|
+
return '<div class="mem-card">'+
|
|
224
|
+
'<div class="mem-head">'+
|
|
225
|
+
'<span class="type-badge" style="background:'+color+'">'+esc(m.type)+'</span>'+
|
|
226
|
+
'<code class="mono" style="color:var(--muted);font-size:0.7rem">'+esc(m.id.slice(0,8))+'</code>'+
|
|
227
|
+
'</div>'+
|
|
228
|
+
'<div class="mem-content">'+esc(m.content)+'</div>'+
|
|
229
|
+
'<div class="mem-meta">'+
|
|
230
|
+
'<span>Confidence: '+Math.round(m.confidence*100)+'%</span>'+
|
|
231
|
+
'<span>'+timeAgo(m.createdAt)+'</span>'+
|
|
232
|
+
'<span>Accessed '+m.accessCount+'x</span>'+
|
|
233
|
+
(m.scope?'<span>Scope: '+esc(m.scope)+'</span>':'')+
|
|
234
|
+
(tags?' '+tags:'')+
|
|
235
|
+
'</div></div>';
|
|
236
|
+
}).join(''));
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function filterMemories(){
|
|
240
|
+
var q=($('mem-search').value||'').toLowerCase();
|
|
241
|
+
var t=$('mem-type').value;
|
|
242
|
+
var list=allMemories;
|
|
243
|
+
if(q) list=list.filter(function(m){return m.content.toLowerCase().indexOf(q)!==-1});
|
|
244
|
+
if(t) list=list.filter(function(m){return m.type===t});
|
|
245
|
+
renderMemories(list);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// -- Knowledge Graph (simple force-directed) --
|
|
249
|
+
function renderGraph(data){
|
|
250
|
+
var svg=$('graph-svg');
|
|
251
|
+
var W=svg.clientWidth||600, H=svg.clientHeight||360;
|
|
252
|
+
var nodes=data.nodes, edges=data.edges;
|
|
253
|
+
if(!nodes.length){setHTML(svg,'<text x="'+W/2+'" y="'+H/2+'" fill="#8b949e" text-anchor="middle" font-size="14">No graph data</text>');return}
|
|
254
|
+
|
|
255
|
+
// assign random positions
|
|
256
|
+
var i,j;
|
|
257
|
+
for(i=0;i<nodes.length;i++){
|
|
258
|
+
nodes[i].x=W*0.2+Math.random()*W*0.6;
|
|
259
|
+
nodes[i].y=H*0.2+Math.random()*H*0.6;
|
|
260
|
+
nodes[i].vx=0;nodes[i].vy=0;
|
|
261
|
+
}
|
|
262
|
+
var nodeMap={};
|
|
263
|
+
for(i=0;i<nodes.length;i++) nodeMap[nodes[i].id]=nodes[i];
|
|
264
|
+
|
|
265
|
+
// force simulation
|
|
266
|
+
var REPULSION=3000, SPRING=0.02, DAMPING=0.85, DT=1;
|
|
267
|
+
for(var iter=0;iter<80;iter++){
|
|
268
|
+
// repulsion between all pairs
|
|
269
|
+
for(i=0;i<nodes.length;i++){
|
|
270
|
+
for(j=i+1;j<nodes.length;j++){
|
|
271
|
+
var dx=nodes[j].x-nodes[i].x, dy=nodes[j].y-nodes[i].y;
|
|
272
|
+
var dist2=dx*dx+dy*dy+1;
|
|
273
|
+
var f=REPULSION/dist2;
|
|
274
|
+
var d=Math.sqrt(dist2);
|
|
275
|
+
var fx=f*dx/d, fy=f*dy/d;
|
|
276
|
+
nodes[i].vx-=fx;nodes[i].vy-=fy;
|
|
277
|
+
nodes[j].vx+=fx;nodes[j].vy+=fy;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
// attraction along edges
|
|
281
|
+
for(i=0;i<edges.length;i++){
|
|
282
|
+
var a=nodeMap[edges[i].from],b=nodeMap[edges[i].to];
|
|
283
|
+
if(!a||!b) continue;
|
|
284
|
+
var edx=b.x-a.x,edy=b.y-a.y;
|
|
285
|
+
var efx=SPRING*edx,efy=SPRING*edy;
|
|
286
|
+
a.vx+=efx;a.vy+=efy;b.vx-=efx;b.vy-=efy;
|
|
287
|
+
}
|
|
288
|
+
// center gravity
|
|
289
|
+
for(i=0;i<nodes.length;i++){
|
|
290
|
+
nodes[i].vx+=(W/2-nodes[i].x)*0.001;
|
|
291
|
+
nodes[i].vy+=(H/2-nodes[i].y)*0.001;
|
|
292
|
+
}
|
|
293
|
+
// integrate
|
|
294
|
+
for(i=0;i<nodes.length;i++){
|
|
295
|
+
nodes[i].vx*=DAMPING;nodes[i].vy*=DAMPING;
|
|
296
|
+
nodes[i].x+=nodes[i].vx*DT;nodes[i].y+=nodes[i].vy*DT;
|
|
297
|
+
nodes[i].x=Math.max(30,Math.min(W-30,nodes[i].x));
|
|
298
|
+
nodes[i].y=Math.max(30,Math.min(H-30,nodes[i].y));
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// render SVG elements (all text escaped via esc())
|
|
303
|
+
var html='';
|
|
304
|
+
for(i=0;i<edges.length;i++){
|
|
305
|
+
var ea=nodeMap[edges[i].from],eb=nodeMap[edges[i].to];
|
|
306
|
+
if(!ea||!eb) continue;
|
|
307
|
+
var mx=(ea.x+eb.x)/2,my=(ea.y+eb.y)/2;
|
|
308
|
+
html+='<line x1="'+ea.x+'" y1="'+ea.y+'" x2="'+eb.x+'" y2="'+eb.y+'" stroke="#30363d" stroke-width="'+(1+edges[i].strength*2)+'"/>';
|
|
309
|
+
if(edges[i].type) html+='<text x="'+mx+'" y="'+(my-4)+'" fill="#8b949e" font-size="9" text-anchor="middle">'+esc(edges[i].type)+'</text>';
|
|
310
|
+
}
|
|
311
|
+
for(i=0;i<nodes.length;i++){
|
|
312
|
+
var color=TYPE_COLORS[nodes[i].type]||'#8b949e';
|
|
313
|
+
html+='<circle cx="'+nodes[i].x+'" cy="'+nodes[i].y+'" r="8" fill="'+color+'" stroke="#0d1117" stroke-width="2"/>';
|
|
314
|
+
html+='<text x="'+nodes[i].x+'" y="'+(nodes[i].y+20)+'" fill="'+color+'" font-size="10" text-anchor="middle" font-family="-apple-system,sans-serif">'+esc(nodes[i].label.slice(0,24))+'</text>';
|
|
315
|
+
}
|
|
316
|
+
setHTML(svg, html);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// -- Reminders --
|
|
320
|
+
function renderReminders(reminders){
|
|
321
|
+
var el=$('reminder-list');
|
|
322
|
+
if(!reminders.length){setHTML(el,'<div class="empty">No reminders</div>');return}
|
|
323
|
+
setHTML(el, reminders.map(function(r){
|
|
324
|
+
var status=r.completed?'completed':(r.status||'upcoming');
|
|
325
|
+
var cls='status-'+status;
|
|
326
|
+
return '<div class="reminder-item">'+
|
|
327
|
+
'<span class="reminder-status '+cls+'">'+esc(status)+'</span>'+
|
|
328
|
+
'<span class="reminder-content">'+esc(r.content)+'</span>'+
|
|
329
|
+
'</div>';
|
|
330
|
+
}).join(''));
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// -- Log --
|
|
334
|
+
function renderLog(entries){
|
|
335
|
+
var el=$('log-list');
|
|
336
|
+
if(!entries.length){setHTML(el,'<div class="empty">No log entries</div>');return}
|
|
337
|
+
setHTML(el, entries.map(function(e){
|
|
338
|
+
var preview=e.content.length>200?e.content.slice(0,200)+'...':e.content;
|
|
339
|
+
return '<div class="log-entry">'+
|
|
340
|
+
'<span class="log-role '+esc(e.role)+'">'+esc(e.role)+'</span>'+
|
|
341
|
+
'<span class="log-content">'+esc(preview)+'</span>'+
|
|
342
|
+
'<span class="log-time">'+timeAgo(e.timestamp)+'</span>'+
|
|
343
|
+
'</div>';
|
|
344
|
+
}).join(''));
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// -- Data fetching --
|
|
348
|
+
function fetchJSON(url){
|
|
349
|
+
return fetch(url).then(function(r){
|
|
350
|
+
if(!r.ok) throw new Error(r.status+' '+r.statusText);
|
|
351
|
+
return r.json();
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
function loadAll(){
|
|
356
|
+
fetchJSON('/api/stats').then(function(s){
|
|
357
|
+
renderStats(s);
|
|
358
|
+
renderTypeBars(s.byType);
|
|
359
|
+
renderConfBars(s.confidence);
|
|
360
|
+
}).catch(function(){});
|
|
361
|
+
|
|
362
|
+
fetchJSON('/api/memories?limit=200').then(function(m){
|
|
363
|
+
allMemories=m;
|
|
364
|
+
filterMemories();
|
|
365
|
+
}).catch(function(){});
|
|
366
|
+
|
|
367
|
+
fetchJSON('/api/graph').then(renderGraph).catch(function(){});
|
|
368
|
+
fetchJSON('/api/reminders').then(renderReminders).catch(function(){});
|
|
369
|
+
fetchJSON('/api/log?limit=30').then(renderLog).catch(function(){});
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// -- Event listeners --
|
|
373
|
+
var debounce;
|
|
374
|
+
$('mem-search').addEventListener('input',function(){
|
|
375
|
+
clearTimeout(debounce);
|
|
376
|
+
debounce=setTimeout(filterMemories,300);
|
|
377
|
+
});
|
|
378
|
+
$('mem-type').addEventListener('change',filterMemories);
|
|
379
|
+
|
|
380
|
+
// -- Init --
|
|
381
|
+
loadAll();
|
|
382
|
+
setInterval(loadAll,30000);
|
|
383
|
+
})();
|
|
384
|
+
</script>
|
|
385
|
+
</body>
|
|
386
|
+
</html>`;
|
|
387
|
+
// ---------------------------------------------------------------------------
|
|
388
|
+
// HTTP Server + API routes
|
|
389
|
+
// ---------------------------------------------------------------------------
|
|
390
|
+
function jsonResponse(res, data, status = 200) {
|
|
391
|
+
const body = JSON.stringify(data);
|
|
392
|
+
res.writeHead(status, {
|
|
393
|
+
"Content-Type": "application/json",
|
|
394
|
+
"Content-Length": Buffer.byteLength(body),
|
|
395
|
+
"Cache-Control": "no-store",
|
|
396
|
+
});
|
|
397
|
+
res.end(body);
|
|
398
|
+
}
|
|
399
|
+
function htmlResponse(res, html) {
|
|
400
|
+
res.writeHead(200, {
|
|
401
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
402
|
+
"Content-Length": Buffer.byteLength(html),
|
|
403
|
+
});
|
|
404
|
+
res.end(html);
|
|
405
|
+
}
|
|
406
|
+
function errorResponse(res, message, status = 500) {
|
|
407
|
+
jsonResponse(res, { error: message }, status);
|
|
408
|
+
}
|
|
409
|
+
function parseQuery(url) {
|
|
410
|
+
const idx = url.indexOf("?");
|
|
411
|
+
if (idx === -1)
|
|
412
|
+
return {};
|
|
413
|
+
const params = {};
|
|
414
|
+
url
|
|
415
|
+
.slice(idx + 1)
|
|
416
|
+
.split("&")
|
|
417
|
+
.forEach((pair) => {
|
|
418
|
+
const [k, v] = pair.split("=");
|
|
419
|
+
if (k)
|
|
420
|
+
params[decodeURIComponent(k)] = decodeURIComponent(v || "");
|
|
421
|
+
});
|
|
422
|
+
return params;
|
|
423
|
+
}
|
|
424
|
+
// ---------------------------------------------------------------------------
|
|
425
|
+
// Route handlers
|
|
426
|
+
// ---------------------------------------------------------------------------
|
|
427
|
+
function handleStats(db, res) {
|
|
428
|
+
const stats = db.getStats();
|
|
429
|
+
const confidence = db.getConfidenceStats();
|
|
430
|
+
const embeddings = db.getEmbeddingCount();
|
|
431
|
+
// Ensure all memory types appear in byType even if count is 0
|
|
432
|
+
const byType = {};
|
|
433
|
+
for (const t of Object.values(MemoryType)) {
|
|
434
|
+
byType[t] = stats.byType[t] ?? 0;
|
|
435
|
+
}
|
|
436
|
+
jsonResponse(res, {
|
|
437
|
+
total: stats.total,
|
|
438
|
+
byType,
|
|
439
|
+
confidence,
|
|
440
|
+
embeddings,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
function handleMemories(db, res, query) {
|
|
444
|
+
const limit = Math.min(500, Math.max(1, parseInt(query.limit || "50", 10) || 50));
|
|
445
|
+
let memories = db.getAll();
|
|
446
|
+
if (query.search) {
|
|
447
|
+
const term = query.search.toLowerCase();
|
|
448
|
+
memories = memories.filter((m) => m.content.toLowerCase().includes(term));
|
|
449
|
+
}
|
|
450
|
+
if (query.type) {
|
|
451
|
+
memories = memories.filter((m) => m.type === query.type);
|
|
452
|
+
}
|
|
453
|
+
const result = memories.slice(0, limit).map((m) => ({
|
|
454
|
+
id: m.id,
|
|
455
|
+
content: m.content,
|
|
456
|
+
type: m.type,
|
|
457
|
+
tags: m.tags,
|
|
458
|
+
confidence: m.confidence,
|
|
459
|
+
accessCount: m.accessCount,
|
|
460
|
+
createdAt: m.createdAt,
|
|
461
|
+
lastAccessed: m.lastAccessed,
|
|
462
|
+
scope: m.scope,
|
|
463
|
+
}));
|
|
464
|
+
jsonResponse(res, result);
|
|
465
|
+
}
|
|
466
|
+
function handleGraph(db, res) {
|
|
467
|
+
const memories = db.getAll();
|
|
468
|
+
const relations = db.getAllRelations();
|
|
469
|
+
const nodes = memories.map((m) => ({
|
|
470
|
+
id: m.id,
|
|
471
|
+
label: m.content.length > 40 ? m.content.slice(0, 40) + "..." : m.content,
|
|
472
|
+
type: m.type,
|
|
473
|
+
}));
|
|
474
|
+
const memoryIds = new Set(memories.map((m) => m.id));
|
|
475
|
+
const edges = relations
|
|
476
|
+
.filter((r) => memoryIds.has(r.fromId) && memoryIds.has(r.toId))
|
|
477
|
+
.map((r) => ({
|
|
478
|
+
from: r.fromId,
|
|
479
|
+
to: r.toId,
|
|
480
|
+
type: r.relationshipType,
|
|
481
|
+
strength: r.strength,
|
|
482
|
+
}));
|
|
483
|
+
jsonResponse(res, { nodes, edges });
|
|
484
|
+
}
|
|
485
|
+
function handleReminders(db, res) {
|
|
486
|
+
const reminders = db.listReminders(true);
|
|
487
|
+
const active = db.checkReminders();
|
|
488
|
+
const statusMap = new Map(active.map((r) => [r.id, r.status]));
|
|
489
|
+
const result = reminders.map((r) => ({
|
|
490
|
+
id: r.id,
|
|
491
|
+
content: r.content,
|
|
492
|
+
dueAt: r.dueAt,
|
|
493
|
+
completed: r.completed,
|
|
494
|
+
scope: r.scope,
|
|
495
|
+
status: r.completed
|
|
496
|
+
? "completed"
|
|
497
|
+
: (statusMap.get(r.id) ?? "upcoming"),
|
|
498
|
+
}));
|
|
499
|
+
jsonResponse(res, result);
|
|
500
|
+
}
|
|
501
|
+
function handleLog(db, res, query) {
|
|
502
|
+
const limit = Math.min(200, Math.max(1, parseInt(query.limit || "30", 10) || 30));
|
|
503
|
+
const entries = db.getRecentLog(limit);
|
|
504
|
+
jsonResponse(res, entries.map((e) => ({
|
|
505
|
+
id: e.id,
|
|
506
|
+
role: e.role,
|
|
507
|
+
content: e.content,
|
|
508
|
+
timestamp: e.timestamp,
|
|
509
|
+
sessionId: e.sessionId,
|
|
510
|
+
})));
|
|
511
|
+
}
|
|
512
|
+
// ---------------------------------------------------------------------------
|
|
513
|
+
// Public API
|
|
514
|
+
// ---------------------------------------------------------------------------
|
|
515
|
+
export function startDashboard(db, port) {
|
|
516
|
+
const server = http.createServer((req, res) => {
|
|
517
|
+
const url = req.url || "/";
|
|
518
|
+
const pathname = url.split("?")[0];
|
|
519
|
+
const query = parseQuery(url);
|
|
520
|
+
try {
|
|
521
|
+
switch (pathname) {
|
|
522
|
+
case "/":
|
|
523
|
+
htmlResponse(res, DASHBOARD_HTML);
|
|
524
|
+
break;
|
|
525
|
+
case "/api/stats":
|
|
526
|
+
handleStats(db, res);
|
|
527
|
+
break;
|
|
528
|
+
case "/api/memories":
|
|
529
|
+
handleMemories(db, res, query);
|
|
530
|
+
break;
|
|
531
|
+
case "/api/graph":
|
|
532
|
+
handleGraph(db, res);
|
|
533
|
+
break;
|
|
534
|
+
case "/api/reminders":
|
|
535
|
+
handleReminders(db, res);
|
|
536
|
+
break;
|
|
537
|
+
case "/api/log":
|
|
538
|
+
handleLog(db, res, query);
|
|
539
|
+
break;
|
|
540
|
+
default:
|
|
541
|
+
errorResponse(res, "Not found", 404);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
catch (err) {
|
|
545
|
+
const message = err instanceof Error ? err.message : "Internal server error";
|
|
546
|
+
errorResponse(res, message, 500);
|
|
547
|
+
}
|
|
548
|
+
});
|
|
549
|
+
server.listen(port, () => {
|
|
550
|
+
const dashboardUrl = `http://localhost:${port}`;
|
|
551
|
+
console.log(`\namem dashboard running at ${dashboardUrl}\n`);
|
|
552
|
+
// Open browser using execFile (safe — no shell interpolation)
|
|
553
|
+
const cmd = process.platform === "darwin"
|
|
554
|
+
? "open"
|
|
555
|
+
: process.platform === "win32"
|
|
556
|
+
? "start"
|
|
557
|
+
: "xdg-open";
|
|
558
|
+
execFile(cmd, [dashboardUrl], () => {
|
|
559
|
+
/* ignore errors in headless environments */
|
|
560
|
+
});
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
//# sourceMappingURL=dashboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dashboard.js","sourceRoot":"","sources":["../src/dashboard.ts"],"names":[],"mappings":"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"}
|