agent-recall 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 +169 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +75 -0
- package/dist/cli.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/memory.d.ts +32 -0
- package/dist/memory.d.ts.map +1 -0
- package/dist/memory.js +219 -0
- package/dist/memory.js.map +1 -0
- package/dist/schema.d.ts +4 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +73 -0
- package/dist/schema.js.map +1 -0
- package/dist/search.d.ts +7 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +145 -0
- package/dist/search.js.map +1 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +208 -0
- package/dist/server.js.map +1 -0
- package/dist/types.d.ts +38 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +13 -0
- package/dist/types.js.map +1 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Michael Onyek
|
|
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,169 @@
|
|
|
1
|
+
# agent-recall
|
|
2
|
+
|
|
3
|
+
Your AI coding assistant forgets everything between sessions. Fix it in one command.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/agent-recall)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
## Quick Start
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npx agent-recall
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
That's it. Your AI assistant now has persistent memory.
|
|
15
|
+
|
|
16
|
+
## Setup (30 seconds)
|
|
17
|
+
|
|
18
|
+
Add agent-recall to your AI tool's MCP config:
|
|
19
|
+
|
|
20
|
+
### Claude Desktop
|
|
21
|
+
|
|
22
|
+
Edit `~/Library/Application Support/Claude/claude_desktop_config.json` (Mac) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows):
|
|
23
|
+
|
|
24
|
+
```json
|
|
25
|
+
{
|
|
26
|
+
"mcpServers": {
|
|
27
|
+
"agent-recall": {
|
|
28
|
+
"command": "npx",
|
|
29
|
+
"args": ["-y", "agent-recall"]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Cursor
|
|
36
|
+
|
|
37
|
+
Edit `.cursor/mcp.json` in your project root:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"mcpServers": {
|
|
42
|
+
"agent-recall": {
|
|
43
|
+
"command": "npx",
|
|
44
|
+
"args": ["-y", "agent-recall"]
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Windsurf / Any MCP Client
|
|
51
|
+
|
|
52
|
+
Same pattern — point the MCP config at `npx agent-recall`.
|
|
53
|
+
|
|
54
|
+
Restart your AI tool. Done.
|
|
55
|
+
|
|
56
|
+
## What Your Agent Gets
|
|
57
|
+
|
|
58
|
+
Six tools that make it remember:
|
|
59
|
+
|
|
60
|
+
### `remember` — Store anything worth keeping
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
remember({ content: "The webpack config needs resolve.extensions for .tsx files" })
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Auto-categorises** — you don't pick a type. The system infers it:
|
|
67
|
+
- "error", "bug", "fix", "crash" → **bug**
|
|
68
|
+
- "always", "never", "prefer", "must" → **decision**
|
|
69
|
+
- "config", "setting", "port", "path" → **setting**
|
|
70
|
+
- "step 1", "then", "workflow" → **procedure**
|
|
71
|
+
- "prefers", "told me", "corrected" → **feedback**
|
|
72
|
+
- Everything else → **context**
|
|
73
|
+
|
|
74
|
+
### `recall` — Get context for what you're doing
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
recall({ query: "webpack build errors", max_tokens: 2000 })
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Returns the most relevant memories **fitted to your token budget**. Ranked by text relevance, recency, access frequency, and confidence. This is the killer feature — one call loads exactly what the agent needs.
|
|
81
|
+
|
|
82
|
+
### `search` — Find something specific
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
search({ query: "loudnorm", type: "bug" })
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### `forget` — Remove outdated memories
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
forget({ id: "memory-uuid-here" })
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `save_state` — Save working state before session ends
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
save_state({ summary: "Refactoring auth. Changed files: ... Blocked on: ..." })
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### `load_state` — Pick up where you left off
|
|
101
|
+
|
|
102
|
+
```
|
|
103
|
+
load_state({})
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
The next session starts with full context of what the previous session was doing.
|
|
107
|
+
|
|
108
|
+
## How It Works
|
|
109
|
+
|
|
110
|
+
- **SQLite + FTS5** — instant full-text search, zero infrastructure
|
|
111
|
+
- **Auto-project detection** — reads your git repo name or package.json, scopes memories automatically
|
|
112
|
+
- **Token budgeting** — `recall()` fits results to your context window
|
|
113
|
+
- **WAL mode** — safe for concurrent reads
|
|
114
|
+
- **~/.agent-recall/memory.db** — one file, portable, inspectable
|
|
115
|
+
|
|
116
|
+
No vector database. No embeddings model. No API keys. No cloud.
|
|
117
|
+
|
|
118
|
+
## Why Not...
|
|
119
|
+
|
|
120
|
+
| Feature | mcp-memory | remember-mcp | agent-recall |
|
|
121
|
+
|---------|------------|--------------|--------------|
|
|
122
|
+
| Install | npm + 200MB embeddings | npm | **`npx` (zero install)** |
|
|
123
|
+
| Search | Vector (slow, heavy) | None | **FTS5 (instant)** |
|
|
124
|
+
| Token budget | No | No | **Yes** |
|
|
125
|
+
| Auto-typing | No | No | **Yes** |
|
|
126
|
+
| Session state | No | No | **Yes** |
|
|
127
|
+
| Auto-project | No | No | **Yes** |
|
|
128
|
+
| Dependencies | 5 + transformer model | 2 | **3** |
|
|
129
|
+
| Works offline | No (needs model) | Yes | **Yes** |
|
|
130
|
+
|
|
131
|
+
## CLI
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
npx agent-recall # start MCP server (default)
|
|
135
|
+
npx agent-recall search "webpack" # search from terminal
|
|
136
|
+
npx agent-recall recall "auth" # context-budgeted recall
|
|
137
|
+
npx agent-recall stats # memory count + size
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Programmatic API
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
import { Memory } from "agent-recall";
|
|
144
|
+
|
|
145
|
+
const mem = new Memory();
|
|
146
|
+
|
|
147
|
+
mem.remember("Never run migrations on Friday.");
|
|
148
|
+
mem.search("migration");
|
|
149
|
+
mem.recall("deployment checklist", { max_tokens: 2000 });
|
|
150
|
+
|
|
151
|
+
mem.saveState("Deploying v2.1. Database migrated. Waiting on CDN invalidation.");
|
|
152
|
+
mem.loadState(); // Next session picks up here
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
## Memory Types
|
|
156
|
+
|
|
157
|
+
| Type | Auto-detected when content contains | Example |
|
|
158
|
+
|------|-------------------------------------|---------|
|
|
159
|
+
| `bug` | error, fix, crash, fail | "CSS grid breaks in Safari 16" |
|
|
160
|
+
| `decision` | always, never, prefer, must | "Never use any in TypeScript" |
|
|
161
|
+
| `setting` | config, port, version, path | "API runs on port 3001 in dev" |
|
|
162
|
+
| `procedure` | step, first, then, workflow | "Deploy: build → test → push → tag" |
|
|
163
|
+
| `feedback` | prefers, told me, corrected | "User prefers functional components" |
|
|
164
|
+
| `context` | *(default)* | "This repo uses pnpm monorepo" |
|
|
165
|
+
| `session` | *(via save_state)* | Working state between sessions |
|
|
166
|
+
|
|
167
|
+
## License
|
|
168
|
+
|
|
169
|
+
MIT
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const memory_1 = require("./memory");
|
|
6
|
+
const server_1 = require("./server");
|
|
7
|
+
const program = new commander_1.Command();
|
|
8
|
+
program
|
|
9
|
+
.name("agent-recall")
|
|
10
|
+
.description("Your AI coding assistant forgets everything between sessions. Fix it in one command.")
|
|
11
|
+
.version("0.1.0");
|
|
12
|
+
program
|
|
13
|
+
.command("serve", { isDefault: true })
|
|
14
|
+
.description("Start the MCP memory server")
|
|
15
|
+
.option("--db <path>", "Database path")
|
|
16
|
+
.option("--project <name>", "Project scope")
|
|
17
|
+
.action(async (opts) => {
|
|
18
|
+
await (0, server_1.startServer)({ dbPath: opts.db, project: opts.project });
|
|
19
|
+
});
|
|
20
|
+
program
|
|
21
|
+
.command("search <query>")
|
|
22
|
+
.description("Search memories")
|
|
23
|
+
.option("--type <type>", "Filter by type")
|
|
24
|
+
.option("--limit <n>", "Max results", "10")
|
|
25
|
+
.option("--db <path>", "Database path")
|
|
26
|
+
.action((query, opts) => {
|
|
27
|
+
const mem = new memory_1.Memory({ dbPath: opts.db });
|
|
28
|
+
const results = mem.search(query, {
|
|
29
|
+
type: opts.type,
|
|
30
|
+
limit: parseInt(opts.limit),
|
|
31
|
+
});
|
|
32
|
+
if (results.length === 0) {
|
|
33
|
+
console.log("No results.");
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
for (const r of results) {
|
|
37
|
+
const score = r.rank != null ? ` (score: ${r.rank.toFixed(3)})` : "";
|
|
38
|
+
console.log(`\n [${r.type}] ${r.title}${score}`);
|
|
39
|
+
console.log(` id: ${r.id}`);
|
|
40
|
+
console.log(` ${r.content.slice(0, 120).replace(/\n/g, " ")}...`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
mem.close();
|
|
44
|
+
});
|
|
45
|
+
program
|
|
46
|
+
.command("recall <query>")
|
|
47
|
+
.description("Get context-budgeted memories")
|
|
48
|
+
.option("--tokens <n>", "Max token budget", "4000")
|
|
49
|
+
.option("--db <path>", "Database path")
|
|
50
|
+
.action((query, opts) => {
|
|
51
|
+
const mem = new memory_1.Memory({ dbPath: opts.db });
|
|
52
|
+
const context = mem.recall(query, { max_tokens: parseInt(opts.tokens) });
|
|
53
|
+
console.log(context || "No relevant memories found.");
|
|
54
|
+
mem.close();
|
|
55
|
+
});
|
|
56
|
+
program
|
|
57
|
+
.command("stats")
|
|
58
|
+
.description("Show memory statistics")
|
|
59
|
+
.option("--db <path>", "Database path")
|
|
60
|
+
.action((opts) => {
|
|
61
|
+
const mem = new memory_1.Memory({ dbPath: opts.db });
|
|
62
|
+
const s = mem.stats();
|
|
63
|
+
console.log(`Total memories: ${s.total}`);
|
|
64
|
+
console.log(`Database size: ${s.db_size_kb} KB`);
|
|
65
|
+
console.log(`Project: ${mem.project}`);
|
|
66
|
+
if (Object.keys(s.by_type).length) {
|
|
67
|
+
console.log("By type:");
|
|
68
|
+
for (const [t, c] of Object.entries(s.by_type).sort()) {
|
|
69
|
+
console.log(` ${t}: ${c}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
mem.close();
|
|
73
|
+
});
|
|
74
|
+
program.parse();
|
|
75
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Memory } from "./memory";
|
|
2
|
+
export { startServer } from "./server";
|
|
3
|
+
export { inferType, generateTitle } from "./search";
|
|
4
|
+
export type { MemoryRecord, MemoryType, AddOptions, SearchOptions, RecallOptions } from "./types";
|
|
5
|
+
export { MEMORY_TYPES } from "./types";
|
|
6
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACpD,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClG,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MEMORY_TYPES = exports.generateTitle = exports.inferType = exports.startServer = exports.Memory = void 0;
|
|
4
|
+
var memory_1 = require("./memory");
|
|
5
|
+
Object.defineProperty(exports, "Memory", { enumerable: true, get: function () { return memory_1.Memory; } });
|
|
6
|
+
var server_1 = require("./server");
|
|
7
|
+
Object.defineProperty(exports, "startServer", { enumerable: true, get: function () { return server_1.startServer; } });
|
|
8
|
+
var search_1 = require("./search");
|
|
9
|
+
Object.defineProperty(exports, "inferType", { enumerable: true, get: function () { return search_1.inferType; } });
|
|
10
|
+
Object.defineProperty(exports, "generateTitle", { enumerable: true, get: function () { return search_1.generateTitle; } });
|
|
11
|
+
var types_1 = require("./types");
|
|
12
|
+
Object.defineProperty(exports, "MEMORY_TYPES", { enumerable: true, get: function () { return types_1.MEMORY_TYPES; } });
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,mCAAkC;AAAzB,gGAAA,MAAM,OAAA;AACf,mCAAuC;AAA9B,qGAAA,WAAW,OAAA;AACpB,mCAAoD;AAA3C,mGAAA,SAAS,OAAA;AAAE,uGAAA,aAAa,OAAA;AAEjC,iCAAuC;AAA9B,qGAAA,YAAY,OAAA"}
|
package/dist/memory.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { MemoryRecord, MemoryType, AddOptions, SearchOptions, RecallOptions } from "./types";
|
|
2
|
+
export declare class Memory {
|
|
3
|
+
private db;
|
|
4
|
+
readonly project: string;
|
|
5
|
+
readonly dbPath: string;
|
|
6
|
+
constructor(options?: {
|
|
7
|
+
dbPath?: string;
|
|
8
|
+
project?: string;
|
|
9
|
+
cwd?: string;
|
|
10
|
+
});
|
|
11
|
+
remember(content: string, options?: AddOptions): MemoryRecord;
|
|
12
|
+
add(type: MemoryType, title: string, content: string, options?: AddOptions): MemoryRecord;
|
|
13
|
+
get(id: string): MemoryRecord | null;
|
|
14
|
+
update(id: string, updates: Partial<Pick<MemoryRecord, "title" | "content" | "tags" | "type" | "confidence">>): MemoryRecord | null;
|
|
15
|
+
forget(id: string): boolean;
|
|
16
|
+
search(query: string, options?: SearchOptions): MemoryRecord[];
|
|
17
|
+
recall(query: string, options?: RecallOptions): string;
|
|
18
|
+
list(options?: {
|
|
19
|
+
type?: MemoryType;
|
|
20
|
+
limit?: number;
|
|
21
|
+
since?: string;
|
|
22
|
+
}): MemoryRecord[];
|
|
23
|
+
saveState(summary: string, tags?: string[]): MemoryRecord;
|
|
24
|
+
loadState(): MemoryRecord | null;
|
|
25
|
+
stats(): {
|
|
26
|
+
total: number;
|
|
27
|
+
by_type: Record<string, number>;
|
|
28
|
+
db_size_kb: number;
|
|
29
|
+
};
|
|
30
|
+
close(): void;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAyClG,qBAAa,MAAM;IACjB,OAAO,CAAC,EAAE,CAAoB;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBAEZ,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAO;IAc7E,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe,GAAG,YAAY;IAMjE,GAAG,CACD,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,UAAe,GACvB,YAAY;IAoCf,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAcpC,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,GAAG,YAAY,CAAC,CAAC,GAAG,YAAY,GAAG,IAAI;IAuBnI,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAK3B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,YAAY,EAAE;IAIlE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,MAAM;IAI1D,IAAI,CAAC,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,UAAU,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,YAAY,EAAE;IAuBzF,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,EAAyB,GAAG,YAAY;IAY/E,SAAS,IAAI,YAAY,GAAG,IAAI;IAiBhC,KAAK,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE;IAY/E,KAAK,IAAI,IAAI;CAGd"}
|
package/dist/memory.js
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Memory = void 0;
|
|
7
|
+
const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
|
|
8
|
+
const crypto_1 = require("crypto");
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = require("path");
|
|
11
|
+
const os_1 = require("os");
|
|
12
|
+
const child_process_1 = require("child_process");
|
|
13
|
+
const schema_1 = require("./schema");
|
|
14
|
+
const search_1 = require("./search");
|
|
15
|
+
const types_1 = require("./types");
|
|
16
|
+
function detectProject(cwd) {
|
|
17
|
+
// 1. Git repo name
|
|
18
|
+
try {
|
|
19
|
+
const gitRoot = (0, child_process_1.execSync)("git rev-parse --show-toplevel", {
|
|
20
|
+
cwd,
|
|
21
|
+
encoding: "utf-8",
|
|
22
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
23
|
+
}).trim();
|
|
24
|
+
return (0, path_1.basename)(gitRoot);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// Not a git repo
|
|
28
|
+
}
|
|
29
|
+
// 2. package.json name
|
|
30
|
+
const pkgPath = (0, path_1.join)(cwd, "package.json");
|
|
31
|
+
if ((0, fs_1.existsSync)(pkgPath)) {
|
|
32
|
+
try {
|
|
33
|
+
const pkg = JSON.parse((0, fs_1.readFileSync)(pkgPath, "utf-8"));
|
|
34
|
+
if (pkg.name)
|
|
35
|
+
return pkg.name.replace(/^@[^/]+\//, "");
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// Invalid package.json
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// 3. Directory basename
|
|
42
|
+
return (0, path_1.basename)(cwd);
|
|
43
|
+
}
|
|
44
|
+
function defaultDbPath(cwd) {
|
|
45
|
+
// Project-local override
|
|
46
|
+
const localDir = (0, path_1.join)(cwd, ".agent-recall");
|
|
47
|
+
if ((0, fs_1.existsSync)(localDir))
|
|
48
|
+
return (0, path_1.join)(localDir, "memory.db");
|
|
49
|
+
// Global default
|
|
50
|
+
const globalDir = (0, path_1.join)((0, os_1.homedir)(), ".agent-recall");
|
|
51
|
+
return (0, path_1.join)(globalDir, "memory.db");
|
|
52
|
+
}
|
|
53
|
+
class Memory {
|
|
54
|
+
db;
|
|
55
|
+
project;
|
|
56
|
+
dbPath;
|
|
57
|
+
constructor(options = {}) {
|
|
58
|
+
const cwd = options.cwd ?? process.cwd();
|
|
59
|
+
this.project = options.project ?? detectProject(cwd);
|
|
60
|
+
this.dbPath = options.dbPath ?? defaultDbPath(cwd);
|
|
61
|
+
// Ensure directory exists
|
|
62
|
+
const dir = (0, path_1.join)(this.dbPath, "..");
|
|
63
|
+
const { mkdirSync } = require("fs");
|
|
64
|
+
mkdirSync(dir, { recursive: true });
|
|
65
|
+
this.db = new better_sqlite3_1.default(this.dbPath);
|
|
66
|
+
(0, schema_1.initDb)(this.db);
|
|
67
|
+
}
|
|
68
|
+
remember(content, options = {}) {
|
|
69
|
+
const type = options.type ?? (0, search_1.inferType)(content);
|
|
70
|
+
const title = options.title ?? (0, search_1.generateTitle)(content);
|
|
71
|
+
return this.add(type, title, content, options);
|
|
72
|
+
}
|
|
73
|
+
add(type, title, content, options = {}) {
|
|
74
|
+
if (!types_1.MEMORY_TYPES.includes(type)) {
|
|
75
|
+
throw new Error(`Invalid type '${type}'. Must be one of: ${types_1.MEMORY_TYPES.join(", ")}`);
|
|
76
|
+
}
|
|
77
|
+
const id = (0, crypto_1.randomUUID)();
|
|
78
|
+
const now = new Date().toISOString();
|
|
79
|
+
const tags = options.tags?.join(",") ?? "";
|
|
80
|
+
const project = options.project ?? this.project;
|
|
81
|
+
this.db
|
|
82
|
+
.prepare(`INSERT INTO memories
|
|
83
|
+
(id, type, title, content, tags, source, project, confidence,
|
|
84
|
+
supersedes, created_at, updated_at, accessed_at, access_count)
|
|
85
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)`)
|
|
86
|
+
.run(id, type, title, content, tags, options.source ?? "api", project, options.confidence ?? 1.0, options.supersedes ?? "", now, now, now);
|
|
87
|
+
return {
|
|
88
|
+
id, type, title, content,
|
|
89
|
+
tags: options.tags ?? [],
|
|
90
|
+
source: options.source ?? "api",
|
|
91
|
+
project,
|
|
92
|
+
confidence: options.confidence ?? 1.0,
|
|
93
|
+
supersedes: options.supersedes ?? "",
|
|
94
|
+
created_at: now, updated_at: now, accessed_at: now,
|
|
95
|
+
access_count: 0,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
get(id) {
|
|
99
|
+
const row = this.db.prepare("SELECT * FROM memories WHERE id = ?").get(id);
|
|
100
|
+
if (!row)
|
|
101
|
+
return null;
|
|
102
|
+
this.db
|
|
103
|
+
.prepare("UPDATE memories SET accessed_at = ?, access_count = access_count + 1 WHERE id = ?")
|
|
104
|
+
.run(new Date().toISOString(), id);
|
|
105
|
+
return {
|
|
106
|
+
...row,
|
|
107
|
+
tags: row.tags ? row.tags.split(",").map((t) => t.trim()).filter(Boolean) : [],
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
update(id, updates) {
|
|
111
|
+
const record = this.get(id);
|
|
112
|
+
if (!record)
|
|
113
|
+
return null;
|
|
114
|
+
const sets = [];
|
|
115
|
+
const values = [];
|
|
116
|
+
if (updates.title !== undefined) {
|
|
117
|
+
sets.push("title = ?");
|
|
118
|
+
values.push(updates.title);
|
|
119
|
+
}
|
|
120
|
+
if (updates.content !== undefined) {
|
|
121
|
+
sets.push("content = ?");
|
|
122
|
+
values.push(updates.content);
|
|
123
|
+
}
|
|
124
|
+
if (updates.tags !== undefined) {
|
|
125
|
+
sets.push("tags = ?");
|
|
126
|
+
values.push(updates.tags.join(","));
|
|
127
|
+
}
|
|
128
|
+
if (updates.type !== undefined) {
|
|
129
|
+
sets.push("type = ?");
|
|
130
|
+
values.push(updates.type);
|
|
131
|
+
}
|
|
132
|
+
if (updates.confidence !== undefined) {
|
|
133
|
+
sets.push("confidence = ?");
|
|
134
|
+
values.push(updates.confidence);
|
|
135
|
+
}
|
|
136
|
+
if (sets.length === 0)
|
|
137
|
+
return record;
|
|
138
|
+
sets.push("updated_at = ?");
|
|
139
|
+
values.push(new Date().toISOString());
|
|
140
|
+
values.push(id);
|
|
141
|
+
this.db.prepare(`UPDATE memories SET ${sets.join(", ")} WHERE id = ?`).run(...values);
|
|
142
|
+
return this.get(id);
|
|
143
|
+
}
|
|
144
|
+
forget(id) {
|
|
145
|
+
const result = this.db.prepare("DELETE FROM memories WHERE id = ?").run(id);
|
|
146
|
+
return result.changes > 0;
|
|
147
|
+
}
|
|
148
|
+
search(query, options = {}) {
|
|
149
|
+
return (0, search_1.ftsSearch)(this.db, query, { ...options, project: options.project ?? this.project });
|
|
150
|
+
}
|
|
151
|
+
recall(query, options = {}) {
|
|
152
|
+
return (0, search_1.recall)(this.db, query, options, this.project);
|
|
153
|
+
}
|
|
154
|
+
list(options = {}) {
|
|
155
|
+
const { type, limit = 50, since } = options;
|
|
156
|
+
const conditions = [];
|
|
157
|
+
const params = [];
|
|
158
|
+
conditions.push("project = ?");
|
|
159
|
+
params.push(this.project);
|
|
160
|
+
if (type) {
|
|
161
|
+
conditions.push("type = ?");
|
|
162
|
+
params.push(type);
|
|
163
|
+
}
|
|
164
|
+
if (since) {
|
|
165
|
+
conditions.push("created_at >= ?");
|
|
166
|
+
params.push(since);
|
|
167
|
+
}
|
|
168
|
+
params.push(limit);
|
|
169
|
+
const rows = this.db
|
|
170
|
+
.prepare(`SELECT * FROM memories WHERE ${conditions.join(" AND ")} ORDER BY updated_at DESC LIMIT ?`)
|
|
171
|
+
.all(...params);
|
|
172
|
+
return rows.map((row) => ({
|
|
173
|
+
...row,
|
|
174
|
+
tags: row.tags ? row.tags.split(",").map((t) => t.trim()).filter(Boolean) : [],
|
|
175
|
+
}));
|
|
176
|
+
}
|
|
177
|
+
saveState(summary, tags = ["session", "state"]) {
|
|
178
|
+
const prev = this.db
|
|
179
|
+
.prepare("SELECT id FROM memories WHERE type = 'session' AND project = ? ORDER BY created_at DESC LIMIT 1")
|
|
180
|
+
.get(this.project);
|
|
181
|
+
return this.add("session", `Session state — ${this.project}`, summary, {
|
|
182
|
+
tags,
|
|
183
|
+
source: "session",
|
|
184
|
+
supersedes: prev?.id ?? "",
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
loadState() {
|
|
188
|
+
const row = this.db
|
|
189
|
+
.prepare("SELECT * FROM memories WHERE type = 'session' AND project = ? ORDER BY created_at DESC LIMIT 1")
|
|
190
|
+
.get(this.project);
|
|
191
|
+
if (!row)
|
|
192
|
+
return null;
|
|
193
|
+
this.db
|
|
194
|
+
.prepare("UPDATE memories SET accessed_at = ?, access_count = access_count + 1 WHERE id = ?")
|
|
195
|
+
.run(new Date().toISOString(), row.id);
|
|
196
|
+
return {
|
|
197
|
+
...row,
|
|
198
|
+
tags: row.tags ? row.tags.split(",").map((t) => t.trim()).filter(Boolean) : [],
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
stats() {
|
|
202
|
+
const total = this.db.prepare("SELECT COUNT(*) as c FROM memories").get().c;
|
|
203
|
+
const by_type = {};
|
|
204
|
+
const rows = this.db.prepare("SELECT type, COUNT(*) as c FROM memories GROUP BY type").all();
|
|
205
|
+
for (const row of rows)
|
|
206
|
+
by_type[row.type] = row.c;
|
|
207
|
+
let db_size_kb = 0;
|
|
208
|
+
try {
|
|
209
|
+
db_size_kb = Math.round((0, fs_1.statSync)(this.dbPath).size / 1024 * 10) / 10;
|
|
210
|
+
}
|
|
211
|
+
catch { }
|
|
212
|
+
return { total, by_type, db_size_kb };
|
|
213
|
+
}
|
|
214
|
+
close() {
|
|
215
|
+
this.db.close();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
exports.Memory = Memory;
|
|
219
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"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"}
|
package/dist/schema.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,eAAO,MAAM,cAAc,IAAI,CAAC;AAuDhC,wBAAgB,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,QAAQ,GAAG,IAAI,CAgBlD"}
|
package/dist/schema.js
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SCHEMA_VERSION = void 0;
|
|
4
|
+
exports.initDb = initDb;
|
|
5
|
+
exports.SCHEMA_VERSION = 1;
|
|
6
|
+
const SCHEMA_SQL = `
|
|
7
|
+
CREATE TABLE IF NOT EXISTS memories (
|
|
8
|
+
id TEXT PRIMARY KEY,
|
|
9
|
+
type TEXT NOT NULL,
|
|
10
|
+
title TEXT NOT NULL,
|
|
11
|
+
content TEXT NOT NULL,
|
|
12
|
+
tags TEXT DEFAULT '',
|
|
13
|
+
source TEXT DEFAULT '',
|
|
14
|
+
project TEXT DEFAULT '',
|
|
15
|
+
confidence REAL DEFAULT 1.0,
|
|
16
|
+
supersedes TEXT DEFAULT '',
|
|
17
|
+
created_at TEXT NOT NULL,
|
|
18
|
+
updated_at TEXT NOT NULL,
|
|
19
|
+
accessed_at TEXT NOT NULL,
|
|
20
|
+
access_count INTEGER DEFAULT 0
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
|
|
24
|
+
CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project);
|
|
25
|
+
CREATE INDEX IF NOT EXISTS idx_memories_created ON memories(created_at);
|
|
26
|
+
|
|
27
|
+
CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
|
|
28
|
+
title,
|
|
29
|
+
content,
|
|
30
|
+
tags,
|
|
31
|
+
content=memories,
|
|
32
|
+
content_rowid=rowid,
|
|
33
|
+
tokenize='porter unicode61'
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
|
|
37
|
+
INSERT INTO memories_fts(rowid, title, content, tags)
|
|
38
|
+
VALUES (new.rowid, new.title, new.content, new.tags);
|
|
39
|
+
END;
|
|
40
|
+
|
|
41
|
+
CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
|
|
42
|
+
INSERT INTO memories_fts(memories_fts, rowid, title, content, tags)
|
|
43
|
+
VALUES ('delete', old.rowid, old.title, old.content, old.tags);
|
|
44
|
+
END;
|
|
45
|
+
|
|
46
|
+
CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN
|
|
47
|
+
INSERT INTO memories_fts(memories_fts, rowid, title, content, tags)
|
|
48
|
+
VALUES ('delete', old.rowid, old.title, old.content, old.tags);
|
|
49
|
+
INSERT INTO memories_fts(rowid, title, content, tags)
|
|
50
|
+
VALUES (new.rowid, new.title, new.content, new.tags);
|
|
51
|
+
END;
|
|
52
|
+
|
|
53
|
+
CREATE TABLE IF NOT EXISTS schema_version (
|
|
54
|
+
version INTEGER PRIMARY KEY,
|
|
55
|
+
applied_at TEXT NOT NULL
|
|
56
|
+
);
|
|
57
|
+
`;
|
|
58
|
+
function initDb(db) {
|
|
59
|
+
db.pragma("journal_mode = WAL");
|
|
60
|
+
try {
|
|
61
|
+
const row = db
|
|
62
|
+
.prepare("SELECT MAX(version) as v FROM schema_version")
|
|
63
|
+
.get();
|
|
64
|
+
if (row?.v && row.v >= exports.SCHEMA_VERSION)
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// Table doesn't exist yet
|
|
69
|
+
}
|
|
70
|
+
db.exec(SCHEMA_SQL);
|
|
71
|
+
db.prepare("INSERT OR REPLACE INTO schema_version (version, applied_at) VALUES (?, datetime('now'))").run(exports.SCHEMA_VERSION);
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":";;;AAyDA,wBAgBC;AAvEY,QAAA,cAAc,GAAG,CAAC,CAAC;AAEhC,MAAM,UAAU,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmDlB,CAAC;AAEF,SAAgB,MAAM,CAAC,EAAqB;IAC1C,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAEhC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,EAAE;aACX,OAAO,CAAC,8CAA8C,CAAC;aACvD,GAAG,EAA+B,CAAC;QACtC,IAAI,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,sBAAc;YAAE,OAAO;IAChD,CAAC;IAAC,MAAM,CAAC;QACP,0BAA0B;IAC5B,CAAC;IAED,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACpB,EAAE,CAAC,OAAO,CACR,yFAAyF,CAC1F,CAAC,GAAG,CAAC,sBAAc,CAAC,CAAC;AACxB,CAAC"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type Database from "better-sqlite3";
|
|
2
|
+
import type { MemoryRecord, MemoryType, SearchOptions, RecallOptions } from "./types";
|
|
3
|
+
export declare function inferType(content: string): MemoryType;
|
|
4
|
+
export declare function generateTitle(content: string): string;
|
|
5
|
+
export declare function ftsSearch(db: Database.Database, query: string, options?: SearchOptions): MemoryRecord[];
|
|
6
|
+
export declare function recall(db: Database.Database, query: string, options?: RecallOptions, project?: string): string;
|
|
7
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAUtF,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAKrD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIrD;AAmCD,wBAAgB,SAAS,CACvB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,YAAY,EAAE,CAgEhB;AAWD,wBAAgB,MAAM,CACpB,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,EAC3B,OAAO,GAAE,MAAW,GACnB,MAAM,CAwBR"}
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.inferType = inferType;
|
|
4
|
+
exports.generateTitle = generateTitle;
|
|
5
|
+
exports.ftsSearch = ftsSearch;
|
|
6
|
+
exports.recall = recall;
|
|
7
|
+
const TYPE_PATTERNS = [
|
|
8
|
+
[/\b(error|bug|broke|fix|crash|fail|exception|traceback|stack\s?trace)\b/i, "bug"],
|
|
9
|
+
[/\b(always|never|prefer|don'?t|must|banned|rule|avoid)\b/i, "decision"],
|
|
10
|
+
[/\b(config|setting|speed|port|version|path|env|variable|flag)\b/i, "setting"],
|
|
11
|
+
[/\b(step\s?\d|first|then|workflow|pipeline|run|execute|deploy)\b/i, "procedure"],
|
|
12
|
+
[/\b(likes?|prefers?|told me|said|corrected|feedback|wants)\b/i, "feedback"],
|
|
13
|
+
];
|
|
14
|
+
function inferType(content) {
|
|
15
|
+
for (const [pattern, type] of TYPE_PATTERNS) {
|
|
16
|
+
if (pattern.test(content))
|
|
17
|
+
return type;
|
|
18
|
+
}
|
|
19
|
+
return "context";
|
|
20
|
+
}
|
|
21
|
+
function generateTitle(content) {
|
|
22
|
+
const firstSentence = content.split(/[.!?\n]/)[0]?.trim() ?? "";
|
|
23
|
+
if (firstSentence.length > 0 && firstSentence.length <= 120)
|
|
24
|
+
return firstSentence;
|
|
25
|
+
return content.slice(0, 80).trim() + "...";
|
|
26
|
+
}
|
|
27
|
+
function rowToRecord(row, rank) {
|
|
28
|
+
return {
|
|
29
|
+
id: row.id,
|
|
30
|
+
type: row.type,
|
|
31
|
+
title: row.title,
|
|
32
|
+
content: row.content,
|
|
33
|
+
tags: row.tags ? row.tags.split(",").map((t) => t.trim()).filter(Boolean) : [],
|
|
34
|
+
source: row.source,
|
|
35
|
+
project: row.project,
|
|
36
|
+
confidence: row.confidence,
|
|
37
|
+
supersedes: row.supersedes,
|
|
38
|
+
created_at: row.created_at,
|
|
39
|
+
updated_at: row.updated_at,
|
|
40
|
+
accessed_at: row.accessed_at,
|
|
41
|
+
access_count: row.access_count,
|
|
42
|
+
rank,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function recencyScore(accessedAt) {
|
|
46
|
+
try {
|
|
47
|
+
const delta = (Date.now() - new Date(accessedAt).getTime()) / 1000;
|
|
48
|
+
return Math.pow(2, -delta / (7 * 86400)); // 7-day half-life
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return 0.5;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function frequencyScore(accessCount) {
|
|
55
|
+
if (accessCount <= 0)
|
|
56
|
+
return 0;
|
|
57
|
+
return Math.min(1.0, Math.log1p(accessCount) / Math.log1p(100));
|
|
58
|
+
}
|
|
59
|
+
function ftsSearch(db, query, options = {}) {
|
|
60
|
+
const { type, tags, project, limit = 10 } = options;
|
|
61
|
+
const terms = query.replace(/"/g, '""').split(/\s+/).filter(Boolean);
|
|
62
|
+
if (terms.length === 0)
|
|
63
|
+
return [];
|
|
64
|
+
const ftsQuery = terms.map((t) => `"${t}"`).join(" OR ");
|
|
65
|
+
let conditions = "";
|
|
66
|
+
const params = [ftsQuery];
|
|
67
|
+
if (type) {
|
|
68
|
+
conditions += " AND m.type = ?";
|
|
69
|
+
params.push(type);
|
|
70
|
+
}
|
|
71
|
+
if (project) {
|
|
72
|
+
conditions += " AND m.project = ?";
|
|
73
|
+
params.push(project);
|
|
74
|
+
}
|
|
75
|
+
if (tags?.length) {
|
|
76
|
+
for (const tag of tags) {
|
|
77
|
+
conditions += " AND m.tags LIKE ?";
|
|
78
|
+
params.push(`%${tag}%`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
params.push(limit * 5);
|
|
82
|
+
const sql = `
|
|
83
|
+
SELECT m.*, fts.rank as fts_rank
|
|
84
|
+
FROM memories_fts fts
|
|
85
|
+
JOIN memories m ON m.rowid = fts.rowid
|
|
86
|
+
WHERE memories_fts MATCH ?
|
|
87
|
+
${conditions}
|
|
88
|
+
ORDER BY fts.rank
|
|
89
|
+
LIMIT ?
|
|
90
|
+
`;
|
|
91
|
+
let rows;
|
|
92
|
+
try {
|
|
93
|
+
rows = db.prepare(sql).all(...params);
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
const scored = rows.map((row) => {
|
|
99
|
+
const ftsRank = -row.fts_rank;
|
|
100
|
+
const recency = recencyScore(row.accessed_at);
|
|
101
|
+
const frequency = frequencyScore(row.access_count);
|
|
102
|
+
const confidence = row.confidence;
|
|
103
|
+
const composite = ftsRank * 0.4 + recency * 0.2 + frequency * 0.2 + confidence * 0.2;
|
|
104
|
+
return { row, score: composite };
|
|
105
|
+
});
|
|
106
|
+
scored.sort((a, b) => b.score - a.score);
|
|
107
|
+
const now = new Date().toISOString();
|
|
108
|
+
const results = scored.slice(0, limit).map(({ row, score }) => {
|
|
109
|
+
db.prepare("UPDATE memories SET accessed_at = ?, access_count = access_count + 1 WHERE id = ?").run(now, row.id);
|
|
110
|
+
return rowToRecord(row, Math.round(score * 10000) / 10000);
|
|
111
|
+
});
|
|
112
|
+
return results;
|
|
113
|
+
}
|
|
114
|
+
function formatRecord(record, format) {
|
|
115
|
+
if (format === "markdown") {
|
|
116
|
+
const parts = [`### [${record.type}] ${record.title}`, record.content];
|
|
117
|
+
if (record.tags.length)
|
|
118
|
+
parts.push(`*tags: ${record.tags.join(", ")}*`);
|
|
119
|
+
return parts.join("\n");
|
|
120
|
+
}
|
|
121
|
+
return `[${record.type}] ${record.title}\n${record.content}`;
|
|
122
|
+
}
|
|
123
|
+
function recall(db, query, options = {}, project = "") {
|
|
124
|
+
const { max_tokens = 4000, format = "markdown" } = options;
|
|
125
|
+
const tokenCount = (text) => Math.ceil(text.length / 4);
|
|
126
|
+
const candidates = ftsSearch(db, query, { project, limit: 50 });
|
|
127
|
+
if (candidates.length === 0)
|
|
128
|
+
return "";
|
|
129
|
+
const selected = [];
|
|
130
|
+
let usedTokens = 0;
|
|
131
|
+
for (const record of candidates) {
|
|
132
|
+
const formatted = formatRecord(record, format);
|
|
133
|
+
const tokens = tokenCount(formatted);
|
|
134
|
+
if (usedTokens + tokens > max_tokens)
|
|
135
|
+
continue;
|
|
136
|
+
selected.push(formatted);
|
|
137
|
+
usedTokens += tokens;
|
|
138
|
+
}
|
|
139
|
+
if (selected.length === 0) {
|
|
140
|
+
return formatRecord(candidates[0], format).slice(0, max_tokens * 4);
|
|
141
|
+
}
|
|
142
|
+
const separator = format === "markdown" ? "\n\n---\n\n" : "\n\n";
|
|
143
|
+
return selected.join(separator);
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AASA,wBAAsB,WAAW,CAAC,OAAO,GAAE;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;CACb,GAAG,OAAO,CAAC,IAAI,CAAC,CA0NrB"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.startServer = startServer;
|
|
4
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
7
|
+
const memory_1 = require("./memory");
|
|
8
|
+
const types_1 = require("./types");
|
|
9
|
+
async function startServer(options = {}) {
|
|
10
|
+
const mem = new memory_1.Memory(options);
|
|
11
|
+
const server = new index_js_1.Server({ name: "agent-recall", version: "0.1.0" }, { capabilities: { tools: {} } });
|
|
12
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => ({
|
|
13
|
+
tools: [
|
|
14
|
+
{
|
|
15
|
+
name: "remember",
|
|
16
|
+
description: "Remember something for future sessions. Use when you learn a bug fix, user preference, decision, setting, or procedure worth keeping. The system auto-detects the category — just provide the content.",
|
|
17
|
+
inputSchema: {
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
content: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "What to remember. Be specific — include the fix, the setting value, the decision rationale.",
|
|
23
|
+
},
|
|
24
|
+
type: {
|
|
25
|
+
type: "string",
|
|
26
|
+
enum: [...types_1.MEMORY_TYPES],
|
|
27
|
+
description: "Optional category override. Auto-detected if omitted.",
|
|
28
|
+
},
|
|
29
|
+
title: {
|
|
30
|
+
type: "string",
|
|
31
|
+
description: "Optional short title. Auto-generated if omitted.",
|
|
32
|
+
},
|
|
33
|
+
tags: {
|
|
34
|
+
type: "array",
|
|
35
|
+
items: { type: "string" },
|
|
36
|
+
description: "Optional tags for filtering.",
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
required: ["content"],
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: "recall",
|
|
44
|
+
description: "Get the most relevant memories for a topic, fitted to a token budget. Use at the start of a task to load context, or when you need to remember how something was done before.",
|
|
45
|
+
inputSchema: {
|
|
46
|
+
type: "object",
|
|
47
|
+
properties: {
|
|
48
|
+
query: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "What you need context about.",
|
|
51
|
+
},
|
|
52
|
+
max_tokens: {
|
|
53
|
+
type: "number",
|
|
54
|
+
description: "Maximum tokens to return. Default 4000.",
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
required: ["query"],
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "search",
|
|
62
|
+
description: "Search memories by keyword. Use when you're looking for a specific thing you stored before.",
|
|
63
|
+
inputSchema: {
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {
|
|
66
|
+
query: { type: "string" },
|
|
67
|
+
type: { type: "string", enum: [...types_1.MEMORY_TYPES] },
|
|
68
|
+
limit: { type: "number", description: "Max results. Default 10." },
|
|
69
|
+
},
|
|
70
|
+
required: ["query"],
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: "forget",
|
|
75
|
+
description: "Delete a memory by ID. Use when a memory is outdated or wrong.",
|
|
76
|
+
inputSchema: {
|
|
77
|
+
type: "object",
|
|
78
|
+
properties: {
|
|
79
|
+
id: { type: "string", description: "Memory ID to delete." },
|
|
80
|
+
},
|
|
81
|
+
required: ["id"],
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "save_state",
|
|
86
|
+
description: "Save your current working state before the conversation ends. Capture what's in progress, what's blocked, what's done, and key decisions. The next session can load this to continue where you left off.",
|
|
87
|
+
inputSchema: {
|
|
88
|
+
type: "object",
|
|
89
|
+
properties: {
|
|
90
|
+
summary: {
|
|
91
|
+
type: "string",
|
|
92
|
+
description: "Full session state: in-progress work, blocked items, completed items, key decisions.",
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
required: ["summary"],
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
name: "load_state",
|
|
100
|
+
description: "Load the most recent session state. Call this at the start of a conversation to pick up where the last session left off.",
|
|
101
|
+
inputSchema: {
|
|
102
|
+
type: "object",
|
|
103
|
+
properties: {},
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
}));
|
|
108
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
109
|
+
const { name, arguments: args } = request.params;
|
|
110
|
+
try {
|
|
111
|
+
switch (name) {
|
|
112
|
+
case "remember": {
|
|
113
|
+
const record = mem.remember(args.content, {
|
|
114
|
+
type: args.type,
|
|
115
|
+
title: args.title,
|
|
116
|
+
tags: args.tags,
|
|
117
|
+
});
|
|
118
|
+
return {
|
|
119
|
+
content: [
|
|
120
|
+
{
|
|
121
|
+
type: "text",
|
|
122
|
+
text: `Remembered: ${record.id}\n[${record.type}] ${record.title}`,
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
case "recall": {
|
|
128
|
+
const context = mem.recall(args.query, {
|
|
129
|
+
max_tokens: args.max_tokens ?? 4000,
|
|
130
|
+
});
|
|
131
|
+
return {
|
|
132
|
+
content: [
|
|
133
|
+
{
|
|
134
|
+
type: "text",
|
|
135
|
+
text: context || "No relevant memories found.",
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
case "search": {
|
|
141
|
+
const results = mem.search(args.query, {
|
|
142
|
+
type: args.type,
|
|
143
|
+
limit: args.limit ?? 10,
|
|
144
|
+
});
|
|
145
|
+
if (results.length === 0) {
|
|
146
|
+
return { content: [{ type: "text", text: "No results found." }] };
|
|
147
|
+
}
|
|
148
|
+
const lines = results.map((r) => `[${r.type}] ${r.title}${r.rank != null ? ` (score: ${r.rank.toFixed(3)})` : ""}\nid: ${r.id}\n${r.content.slice(0, 200)}`);
|
|
149
|
+
return {
|
|
150
|
+
content: [{ type: "text", text: lines.join("\n\n---\n\n") }],
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
case "forget": {
|
|
154
|
+
const deleted = mem.forget(args.id);
|
|
155
|
+
return {
|
|
156
|
+
content: [
|
|
157
|
+
{
|
|
158
|
+
type: "text",
|
|
159
|
+
text: deleted ? `Deleted: ${args.id}` : `Not found: ${args.id}`,
|
|
160
|
+
},
|
|
161
|
+
],
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
case "save_state": {
|
|
165
|
+
const record = mem.saveState(args.summary);
|
|
166
|
+
return {
|
|
167
|
+
content: [
|
|
168
|
+
{
|
|
169
|
+
type: "text",
|
|
170
|
+
text: `State saved: ${record.id}\n${record.content.slice(0, 200)}...`,
|
|
171
|
+
},
|
|
172
|
+
],
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
case "load_state": {
|
|
176
|
+
const record = mem.loadState();
|
|
177
|
+
if (record) {
|
|
178
|
+
return {
|
|
179
|
+
content: [
|
|
180
|
+
{
|
|
181
|
+
type: "text",
|
|
182
|
+
text: `Last session (${record.created_at}):\n\n${record.content}`,
|
|
183
|
+
},
|
|
184
|
+
],
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
content: [{ type: "text", text: "No previous session found." }],
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
default:
|
|
192
|
+
return {
|
|
193
|
+
content: [{ type: "text", text: `Unknown tool: ${name}` }],
|
|
194
|
+
isError: true,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
return {
|
|
200
|
+
content: [{ type: "text", text: `Error: ${error?.message ?? String(error)}` }],
|
|
201
|
+
isError: true,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
206
|
+
await server.connect(transport);
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;AASA,kCA6NC;AAtOD,wEAAmE;AACnE,wEAAiF;AACjF,iEAG4C;AAC5C,qCAAkC;AAClC,mCAAuC;AAEhC,KAAK,UAAU,WAAW,CAAC,UAG9B,EAAE;IACJ,MAAM,GAAG,GAAG,IAAI,eAAM,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,IAAI,iBAAM,CACvB,EAAE,IAAI,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,EAC1C,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAChC,CAAC;IAEF,MAAM,CAAC,iBAAiB,CAAC,iCAAsB,EAAE,KAAK,IAAI,EAAE,CAAC,CAAC;QAC5D,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,UAAU;gBAChB,WAAW,EACT,wMAAwM;gBAC1M,WAAW,EAAE;oBACX,IAAI,EAAE,QAAiB;oBACvB,UAAU,EAAE;wBACV,OAAO,EAAE;4BACP,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,6FAA6F;yBAC3G;wBACD,IAAI,EAAE;4BACJ,IAAI,EAAE,QAAQ;4BACd,IAAI,EAAE,CAAC,GAAG,oBAAY,CAAC;4BACvB,WAAW,EAAE,uDAAuD;yBACrE;wBACD,KAAK,EAAE;4BACL,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,kDAAkD;yBAChE;wBACD,IAAI,EAAE;4BACJ,IAAI,EAAE,OAAO;4BACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;4BACzB,WAAW,EAAE,8BAA8B;yBAC5C;qBACF;oBACD,QAAQ,EAAE,CAAC,SAAS,CAAC;iBACtB;aACF;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,+KAA+K;gBACjL,WAAW,EAAE;oBACX,IAAI,EAAE,QAAiB;oBACvB,UAAU,EAAE;wBACV,KAAK,EAAE;4BACL,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,8BAA8B;yBAC5C;wBACD,UAAU,EAAE;4BACV,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,yCAAyC;yBACvD;qBACF;oBACD,QAAQ,EAAE,CAAC,OAAO,CAAC;iBACpB;aACF;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,6FAA6F;gBAC/F,WAAW,EAAE;oBACX,IAAI,EAAE,QAAiB;oBACvB,UAAU,EAAE;wBACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;wBACzB,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,GAAG,oBAAY,CAAC,EAAE;wBACjD,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,0BAA0B,EAAE;qBACnE;oBACD,QAAQ,EAAE,CAAC,OAAO,CAAC;iBACpB;aACF;YACD;gBACE,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,gEAAgE;gBAC7E,WAAW,EAAE;oBACX,IAAI,EAAE,QAAiB;oBACvB,UAAU,EAAE;wBACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE;qBAC5D;oBACD,QAAQ,EAAE,CAAC,IAAI,CAAC;iBACjB;aACF;YACD;gBACE,IAAI,EAAE,YAAY;gBAClB,WAAW,EACT,0MAA0M;gBAC5M,WAAW,EAAE;oBACX,IAAI,EAAE,QAAiB;oBACvB,UAAU,EAAE;wBACV,OAAO,EAAE;4BACP,IAAI,EAAE,QAAQ;4BACd,WAAW,EAAE,sFAAsF;yBACpG;qBACF;oBACD,QAAQ,EAAE,CAAC,SAAS,CAAC;iBACtB;aACF;YACD;gBACE,IAAI,EAAE,YAAY;gBAClB,WAAW,EACT,0HAA0H;gBAC5H,WAAW,EAAE;oBACX,IAAI,EAAE,QAAiB;oBACvB,UAAU,EAAE,EAAE;iBACf;aACF;SACF;KACF,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,iBAAiB,CAAC,gCAAqB,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE;QAChE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;QAEjD,IAAI,CAAC;YACL,QAAQ,IAAI,EAAE,CAAC;gBACb,KAAK,UAAU,CAAC,CAAC,CAAC;oBAChB,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,CAAC,IAAK,CAAC,OAAiB,EAAE;wBACnD,IAAI,EAAE,IAAK,CAAC,IAAW;wBACvB,KAAK,EAAE,IAAK,CAAC,KAAe;wBAC5B,IAAI,EAAE,IAAK,CAAC,IAAgB;qBAC7B,CAAC,CAAC;oBACH,OAAO;wBACL,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,eAAe,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,EAAE;6BACnE;yBACF;qBACF,CAAC;gBACJ,CAAC;gBAED,KAAK,QAAQ,CAAC,CAAC,CAAC;oBACd,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,IAAK,CAAC,KAAe,EAAE;wBAChD,UAAU,EAAG,IAAK,CAAC,UAAqB,IAAI,IAAI;qBACjD,CAAC,CAAC;oBACH,OAAO;wBACL,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,OAAO,IAAI,6BAA6B;6BAC/C;yBACF;qBACF,CAAC;gBACJ,CAAC;gBAED,KAAK,QAAQ,CAAC,CAAC,CAAC;oBACd,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,IAAK,CAAC,KAAe,EAAE;wBAChD,IAAI,EAAE,IAAK,CAAC,IAAW;wBACvB,KAAK,EAAG,IAAK,CAAC,KAAgB,IAAI,EAAE;qBACrC,CAAC,CAAC;oBACH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACzB,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC,EAAE,CAAC;oBAC7E,CAAC;oBACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CACvB,CAAC,CAAC,EAAE,EAAE,CACJ,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC7H,CAAC;oBACF,OAAO;wBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,CAAC;qBACtE,CAAC;gBACJ,CAAC;gBAED,KAAK,QAAQ,CAAC,CAAC,CAAC;oBACd,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,IAAK,CAAC,EAAY,CAAC,CAAC;oBAC/C,OAAO;wBACL,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,IAAK,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,cAAc,IAAK,CAAC,EAAE,EAAE;6BAClE;yBACF;qBACF,CAAC;gBACJ,CAAC;gBAED,KAAK,YAAY,CAAC,CAAC,CAAC;oBAClB,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,CAAC,IAAK,CAAC,OAAiB,CAAC,CAAC;oBACtD,OAAO;wBACL,OAAO,EAAE;4BACP;gCACE,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,gBAAgB,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,KAAK;6BACtE;yBACF;qBACF,CAAC;gBACJ,CAAC;gBAED,KAAK,YAAY,CAAC,CAAC,CAAC;oBAClB,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;oBAC/B,IAAI,MAAM,EAAE,CAAC;wBACX,OAAO;4BACL,OAAO,EAAE;gCACP;oCACE,IAAI,EAAE,MAAe;oCACrB,IAAI,EAAE,iBAAiB,MAAM,CAAC,UAAU,SAAS,MAAM,CAAC,OAAO,EAAE;iCAClE;6BACF;yBACF,CAAC;oBACJ,CAAC;oBACD,OAAO;wBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,4BAA4B,EAAE,CAAC;qBACzE,CAAC;gBACJ,CAAC;gBAED;oBACE,OAAO;wBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,iBAAiB,IAAI,EAAE,EAAE,CAAC;wBACnE,OAAO,EAAE,IAAI;qBACd,CAAC;YACN,CAAC;QACD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,UAAU,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;gBACvF,OAAO,EAAE,IAAI;aACd,CAAC;QACJ,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,MAAM,SAAS,GAAG,IAAI,+BAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export declare const MEMORY_TYPES: readonly ["setting", "bug", "decision", "procedure", "context", "feedback", "session"];
|
|
2
|
+
export type MemoryType = (typeof MEMORY_TYPES)[number];
|
|
3
|
+
export interface MemoryRecord {
|
|
4
|
+
id: string;
|
|
5
|
+
type: MemoryType;
|
|
6
|
+
title: string;
|
|
7
|
+
content: string;
|
|
8
|
+
tags: string[];
|
|
9
|
+
source: string;
|
|
10
|
+
project: string;
|
|
11
|
+
confidence: number;
|
|
12
|
+
supersedes: string;
|
|
13
|
+
created_at: string;
|
|
14
|
+
updated_at: string;
|
|
15
|
+
accessed_at: string;
|
|
16
|
+
access_count: number;
|
|
17
|
+
rank?: number;
|
|
18
|
+
}
|
|
19
|
+
export interface AddOptions {
|
|
20
|
+
type?: MemoryType;
|
|
21
|
+
title?: string;
|
|
22
|
+
tags?: string[];
|
|
23
|
+
source?: string;
|
|
24
|
+
project?: string;
|
|
25
|
+
confidence?: number;
|
|
26
|
+
supersedes?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface SearchOptions {
|
|
29
|
+
type?: MemoryType;
|
|
30
|
+
tags?: string[];
|
|
31
|
+
project?: string;
|
|
32
|
+
limit?: number;
|
|
33
|
+
}
|
|
34
|
+
export interface RecallOptions {
|
|
35
|
+
max_tokens?: number;
|
|
36
|
+
format?: "markdown" | "plain";
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,YAAY,wFAQf,CAAC;AAEX,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AAEvD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC;CAC/B"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MEMORY_TYPES = void 0;
|
|
4
|
+
exports.MEMORY_TYPES = [
|
|
5
|
+
"setting",
|
|
6
|
+
"bug",
|
|
7
|
+
"decision",
|
|
8
|
+
"procedure",
|
|
9
|
+
"context",
|
|
10
|
+
"feedback",
|
|
11
|
+
"session",
|
|
12
|
+
];
|
|
13
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":";;;AAAa,QAAA,YAAY,GAAG;IAC1B,SAAS;IACT,KAAK;IACL,UAAU;IACV,WAAW;IACX,SAAS;IACT,UAAU;IACV,SAAS;CACD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "agent-recall",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Your AI coding assistant forgets everything between sessions. Fix it in one command.",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"agent-recall": "dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"test": "vitest run",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"mcp",
|
|
17
|
+
"memory",
|
|
18
|
+
"agent",
|
|
19
|
+
"ai",
|
|
20
|
+
"llm",
|
|
21
|
+
"sqlite",
|
|
22
|
+
"fts5",
|
|
23
|
+
"claude",
|
|
24
|
+
"cursor",
|
|
25
|
+
"copilot",
|
|
26
|
+
"model-context-protocol",
|
|
27
|
+
"recall"
|
|
28
|
+
],
|
|
29
|
+
"author": "Michael Onyek",
|
|
30
|
+
"license": "MIT",
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/Thezenmonster/agent-recall.git"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://github.com/Thezenmonster/agent-recall#readme",
|
|
36
|
+
"bugs": {
|
|
37
|
+
"url": "https://github.com/Thezenmonster/agent-recall/issues"
|
|
38
|
+
},
|
|
39
|
+
"engines": {
|
|
40
|
+
"node": ">=18"
|
|
41
|
+
},
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"better-sqlite3": "^11.0.0",
|
|
44
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
45
|
+
"commander": "^12.0.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"typescript": "^5.4.0",
|
|
49
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
50
|
+
"@types/node": "^20.0.0",
|
|
51
|
+
"vitest": "^2.0.0"
|
|
52
|
+
},
|
|
53
|
+
"files": [
|
|
54
|
+
"dist",
|
|
55
|
+
"README.md",
|
|
56
|
+
"LICENSE"
|
|
57
|
+
]
|
|
58
|
+
}
|