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 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
+ [![npm](https://img.shields.io/npm/v/agent-recall)](https://www.npmjs.com/package/agent-recall)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,qCAAkC;AAClC,qCAAuC;AAEvC,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,cAAc,CAAC;KACpB,WAAW,CAAC,sFAAsF,CAAC;KACnG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;KACrC,WAAW,CAAC,6BAA6B,CAAC;KAC1C,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC;KACtC,MAAM,CAAC,kBAAkB,EAAE,eAAe,CAAC;KAC3C,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,MAAM,IAAA,oBAAW,EAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;AAChE,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,iBAAiB,CAAC;KAC9B,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;KACzC,MAAM,CAAC,aAAa,EAAE,aAAa,EAAE,IAAI,CAAC;KAC1C,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC;KACtC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACtB,MAAM,GAAG,GAAG,IAAI,eAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE;QAChC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;KAC5B,CAAC,CAAC;IACH,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC7B,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,MAAM,KAAK,GAAG,CAAC,CAAC,IAAI,IAAI,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACrE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,GAAG,KAAK,EAAE,CAAC,CAAC;YAClD,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QACrE,CAAC;IACH,CAAC;IACD,GAAG,CAAC,KAAK,EAAE,CAAC;AACd,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,gBAAgB,CAAC;KACzB,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,cAAc,EAAE,kBAAkB,EAAE,MAAM,CAAC;KAClD,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC;KACtC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACtB,MAAM,GAAG,GAAG,IAAI,eAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACzE,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,6BAA6B,CAAC,CAAC;IACtD,GAAG,CAAC,KAAK,EAAE,CAAC;AACd,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,wBAAwB,CAAC;KACrC,MAAM,CAAC,aAAa,EAAE,eAAe,CAAC;KACtC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;IACf,MAAM,GAAG,GAAG,IAAI,eAAM,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,EAAE,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1C,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACvC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QACxB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YACtD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,GAAG,CAAC,KAAK,EAAE,CAAC;AACd,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -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"}
@@ -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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"}
@@ -0,0 +1,4 @@
1
+ import type Database from "better-sqlite3";
2
+ export declare const SCHEMA_VERSION = 1;
3
+ export declare function initDb(db: Database.Database): void;
4
+ //# sourceMappingURL=schema.d.ts.map
@@ -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"}
@@ -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":";;AAWA,8BAKC;AAED,sCAIC;AAmCD,8BAoEC;AAWD,wBA6BC;AAlKD,MAAM,aAAa,GAA2B;IAC5C,CAAC,yEAAyE,EAAE,KAAK,CAAC;IAClF,CAAC,0DAA0D,EAAE,UAAU,CAAC;IACxE,CAAC,iEAAiE,EAAE,SAAS,CAAC;IAC9E,CAAC,kEAAkE,EAAE,WAAW,CAAC;IACjF,CAAC,8DAA8D,EAAE,UAAU,CAAC;CAC7E,CAAC;AAEF,SAAgB,SAAS,CAAC,OAAe;IACvC,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,aAAa,EAAE,CAAC;QAC5C,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;IACzC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAgB,aAAa,CAAC,OAAe;IAC3C,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAChE,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,IAAI,aAAa,CAAC,MAAM,IAAI,GAAG;QAAE,OAAO,aAAa,CAAC;IAClF,OAAO,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC;AAC7C,CAAC;AAED,SAAS,WAAW,CAAC,GAAQ,EAAE,IAAa;IAC1C,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE;QACtF,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,YAAY,EAAE,GAAG,CAAC,YAAY;QAC9B,IAAI;KACL,CAAC;AACJ,CAAC;AAED,SAAS,YAAY,CAAC,UAAkB;IACtC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC;QACnE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,kBAAkB;IAC9D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,WAAmB;IACzC,IAAI,WAAW,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC;IAC/B,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,SAAgB,SAAS,CACvB,EAAqB,EACrB,KAAa,EACb,UAAyB,EAAE;IAE3B,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC;IAEpD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACrE,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAClC,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAEzD,IAAI,UAAU,GAAG,EAAE,CAAC;IACpB,MAAM,MAAM,GAAU,CAAC,QAAQ,CAAC,CAAC;IAEjC,IAAI,IAAI,EAAE,CAAC;QACT,UAAU,IAAI,iBAAiB,CAAC;QAChC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,IAAI,OAAO,EAAE,CAAC;QACZ,UAAU,IAAI,oBAAoB,CAAC;QACnC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC;IACD,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;QACjB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,UAAU,IAAI,oBAAoB,CAAC;YACnC,MAAM,CAAC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;IAEvB,MAAM,GAAG,GAAG;;;;;MAKR,UAAU;;;GAGb,CAAC;IAEF,IAAI,IAAW,CAAC;IAChB,IAAI,CAAC;QACH,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC9B,MAAM,OAAO,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC9B,MAAM,OAAO,GAAG,YAAY,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QAC9C,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QACnD,MAAM,UAAU,GAAG,GAAG,CAAC,UAAU,CAAC;QAClC,MAAM,SAAS,GAAG,OAAO,GAAG,GAAG,GAAG,OAAO,GAAG,GAAG,GAAG,SAAS,GAAG,GAAG,GAAG,UAAU,GAAG,GAAG,CAAC;QACrF,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;IACnC,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC;IAEzC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE;QAC5D,EAAE,CAAC,OAAO,CACR,mFAAmF,CACpF,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACnB,OAAO,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC;IAC7D,CAAC,CAAC,CAAC;IAEH,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,YAAY,CAAC,MAAoB,EAAE,MAAc;IACxD,IAAI,MAAM,KAAK,UAAU,EAAE,CAAC;QAC1B,MAAM,KAAK,GAAG,CAAC,QAAQ,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;QACvE,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,UAAU,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,OAAO,EAAE,CAAC;AAC/D,CAAC;AAED,SAAgB,MAAM,CACpB,EAAqB,EACrB,KAAa,EACb,UAAyB,EAAE,EAC3B,UAAkB,EAAE;IAEpB,MAAM,EAAE,UAAU,GAAG,IAAI,EAAE,MAAM,GAAG,UAAU,EAAE,GAAG,OAAO,CAAC;IAC3D,MAAM,UAAU,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAEhE,MAAM,UAAU,GAAG,SAAS,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;IAChE,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEvC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,KAAK,MAAM,MAAM,IAAI,UAAU,EAAE,CAAC;QAChC,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,UAAU,GAAG,MAAM,GAAG,UAAU;YAAE,SAAS;QAC/C,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACzB,UAAU,IAAI,MAAM,CAAC;IACvB,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,GAAG,CAAC,CAAC,CAAC;IACtE,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC;IACjE,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function startServer(options?: {
2
+ dbPath?: string;
3
+ project?: string;
4
+ }): Promise<void>;
5
+ //# sourceMappingURL=server.d.ts.map
@@ -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":"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"}
@@ -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
+ }