@j0hanz/memory-mcp 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +32 -25
- package/dist/completions/index.d.ts.map +1 -1
- package/dist/completions/index.js +8 -5
- package/dist/completions/index.js.map +1 -1
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +68 -8
- package/dist/db/index.js.map +1 -1
- package/dist/db/typed.d.ts +9 -3
- package/dist/db/typed.d.ts.map +1 -1
- package/dist/db/typed.js +33 -4
- package/dist/db/typed.js.map +1 -1
- package/dist/index.js +13 -8
- package/dist/index.js.map +1 -1
- package/dist/instructions.md +102 -56
- package/dist/lib/errors.d.ts +3 -0
- package/dist/lib/errors.d.ts.map +1 -1
- package/dist/lib/errors.js +11 -4
- package/dist/lib/errors.js.map +1 -1
- package/dist/lib/hash.d.ts.map +1 -1
- package/dist/lib/hash.js +9 -2
- package/dist/lib/hash.js.map +1 -1
- package/dist/lib/instructions.d.ts +2 -0
- package/dist/lib/instructions.d.ts.map +1 -0
- package/dist/lib/instructions.js +27 -0
- package/dist/lib/instructions.js.map +1 -0
- package/dist/lib/mcp-utils.d.ts +6 -0
- package/dist/lib/mcp-utils.d.ts.map +1 -0
- package/dist/lib/mcp-utils.js +26 -0
- package/dist/lib/mcp-utils.js.map +1 -0
- package/dist/lib/pagination.d.ts.map +1 -1
- package/dist/lib/pagination.js +14 -7
- package/dist/lib/pagination.js.map +1 -1
- package/dist/lib/search-cursor.d.ts +13 -0
- package/dist/lib/search-cursor.d.ts.map +1 -0
- package/dist/lib/search-cursor.js +89 -0
- package/dist/lib/search-cursor.js.map +1 -0
- package/dist/lib/search.d.ts +16 -0
- package/dist/lib/search.d.ts.map +1 -1
- package/dist/lib/search.js +53 -12
- package/dist/lib/search.js.map +1 -1
- package/dist/lib/tool-response.d.ts +1 -5
- package/dist/lib/tool-response.d.ts.map +1 -1
- package/dist/lib/tool-response.js +9 -7
- package/dist/lib/tool-response.js.map +1 -1
- package/dist/lib/types.d.ts.map +1 -1
- package/dist/lib/types.js +10 -9
- package/dist/lib/types.js.map +1 -1
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +21 -35
- package/dist/prompts/index.js.map +1 -1
- package/dist/resources/index.d.ts.map +1 -1
- package/dist/resources/index.js +12 -32
- package/dist/resources/index.js.map +1 -1
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +1 -1
- package/dist/schemas/index.js.map +1 -1
- package/dist/schemas/inputs.d.ts +5 -5
- package/dist/schemas/inputs.d.ts.map +1 -1
- package/dist/schemas/inputs.js +21 -14
- package/dist/schemas/inputs.js.map +1 -1
- package/dist/schemas/outputs.d.ts +94 -148
- package/dist/schemas/outputs.d.ts.map +1 -1
- package/dist/schemas/outputs.js +59 -66
- package/dist/schemas/outputs.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +20 -18
- package/dist/server.js.map +1 -1
- package/dist/tools/create-relationship.d.ts.map +1 -1
- package/dist/tools/create-relationship.js +28 -17
- package/dist/tools/create-relationship.js.map +1 -1
- package/dist/tools/delete-memories.d.ts.map +1 -1
- package/dist/tools/delete-memories.js +23 -20
- package/dist/tools/delete-memories.js.map +1 -1
- package/dist/tools/delete-memory.d.ts.map +1 -1
- package/dist/tools/delete-memory.js +13 -13
- package/dist/tools/delete-memory.js.map +1 -1
- package/dist/tools/delete-relationship.d.ts.map +1 -1
- package/dist/tools/delete-relationship.js +18 -12
- package/dist/tools/delete-relationship.js.map +1 -1
- package/dist/tools/get-memory.d.ts.map +1 -1
- package/dist/tools/get-memory.js +16 -8
- package/dist/tools/get-memory.js.map +1 -1
- package/dist/tools/get-relationships.d.ts.map +1 -1
- package/dist/tools/get-relationships.js +27 -16
- package/dist/tools/get-relationships.js.map +1 -1
- package/dist/tools/index.d.ts +6 -14
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +5 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/memory-stats.d.ts.map +1 -1
- package/dist/tools/memory-stats.js +26 -20
- package/dist/tools/memory-stats.js.map +1 -1
- package/dist/tools/progress.d.ts +34 -0
- package/dist/tools/progress.d.ts.map +1 -0
- package/dist/tools/progress.js +129 -0
- package/dist/tools/progress.js.map +1 -0
- package/dist/tools/recall.d.ts.map +1 -1
- package/dist/tools/recall.js +150 -98
- package/dist/tools/recall.js.map +1 -1
- package/dist/tools/result.d.ts +5 -0
- package/dist/tools/result.d.ts.map +1 -0
- package/dist/tools/result.js +14 -0
- package/dist/tools/result.js.map +1 -0
- package/dist/tools/retrieve-context.d.ts.map +1 -1
- package/dist/tools/retrieve-context.js +99 -26
- package/dist/tools/retrieve-context.js.map +1 -1
- package/dist/tools/search-memories.d.ts.map +1 -1
- package/dist/tools/search-memories.js +28 -40
- package/dist/tools/search-memories.js.map +1 -1
- package/dist/tools/store-memories.d.ts.map +1 -1
- package/dist/tools/store-memories.js +30 -18
- package/dist/tools/store-memories.js.map +1 -1
- package/dist/tools/store-memory.d.ts.map +1 -1
- package/dist/tools/store-memory.js +32 -13
- package/dist/tools/store-memory.js.map +1 -1
- package/dist/tools/update-memory.d.ts.map +1 -1
- package/dist/tools/update-memory.js +35 -16
- package/dist/tools/update-memory.js.map +1 -1
- package/package.json +1 -2
- package/dist/tools/helpers.d.ts +0 -13
- package/dist/tools/helpers.d.ts.map +0 -1
- package/dist/tools/helpers.js +0 -49
- package/dist/tools/helpers.js.map +0 -1
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ Memory MCP provides a local, persistent memory layer for MCP-enabled assistants.
|
|
|
22
22
|
- **Token-budget retrieval** (`retrieve_context`) selects memories that fit a caller-specified token budget — no manual pagination needed.
|
|
23
23
|
- **Strict Zod input validation** with typed output envelopes and SHA-256 hash addressing.
|
|
24
24
|
- **Resource support** with `internal://instructions` (Markdown guide) and `memory://memories/{hash}` URI template with hash auto-completion.
|
|
25
|
-
- **stdio transport** with clean shutdown handling (`SIGINT`, `SIGTERM`) and no HTTP endpoints.
|
|
25
|
+
- **stdio transport** with clean shutdown handling (`SIGINT`, `SIGTERM`) and no HTTP endpoints. |
|
|
26
26
|
|
|
27
27
|
## Requirements
|
|
28
28
|
|
|
@@ -192,6 +192,16 @@ MCP client config:
|
|
|
192
192
|
|
|
193
193
|
</details>
|
|
194
194
|
|
|
195
|
+
## Documentation Maintenance
|
|
196
|
+
|
|
197
|
+
- **Owner**: maintainers updating MCP behavior in `src/` must update `README.md` and affected `mcp/` mirror pages in the same PR.
|
|
198
|
+
- **Link/version policy**: use pinned `https://modelcontextprotocol.io/specification/2025-11-25/...` links for protocol references; avoid `latest` and mixed legacy targets.
|
|
199
|
+
- **Drift-check checklist**:
|
|
200
|
+
- Re-verify capability declarations in `src/server.ts`.
|
|
201
|
+
- Reconcile tool/resource/prompt docs with `src/tools/index.ts`, `src/resources/index.ts`, and `src/prompts/index.ts`.
|
|
202
|
+
- Confirm limitations/gotchas in `src/instructions.md` match runtime behavior.
|
|
203
|
+
- **Validation commands**: `npm run type-check`, `npm run test:fast`, `npm run build`.
|
|
204
|
+
|
|
195
205
|
## MCP Surface
|
|
196
206
|
|
|
197
207
|
### Tools Summary
|
|
@@ -225,7 +235,7 @@ Store a new memory with content, tags, and optional type/importance. Idempotent
|
|
|
225
235
|
| `memory_type` | enum | No | `general` | `general`, `fact`, `plan`, `decision`, `reflection`, `lesson`, `error`, `gradient` |
|
|
226
236
|
| `importance` | `integer` | No | `0` | Priority 0–10 |
|
|
227
237
|
|
|
228
|
-
Returns: `{
|
|
238
|
+
Returns: `{ hash, created }`
|
|
229
239
|
|
|
230
240
|
---
|
|
231
241
|
|
|
@@ -237,7 +247,7 @@ Store multiple memories in one transaction (max 50 items).
|
|
|
237
247
|
| ------- | ------------------------ | -------- | -------------------------------------------------------------------------------------- |
|
|
238
248
|
| `items` | `Array<StoreMemoryItem>` | Yes | 1–50 items, each with `content`, `tags`, optional `memory_type`, optional `importance` |
|
|
239
249
|
|
|
240
|
-
Returns: `{
|
|
250
|
+
Returns: `{ items, succeeded, failed }`
|
|
241
251
|
|
|
242
252
|
---
|
|
243
253
|
|
|
@@ -249,7 +259,7 @@ Retrieve one memory by its SHA-256 hash.
|
|
|
249
259
|
| ------ | -------- | -------- | ----------------------------- |
|
|
250
260
|
| `hash` | `string` | Yes | 64-char lowercase SHA-256 hex |
|
|
251
261
|
|
|
252
|
-
Returns: `
|
|
262
|
+
Returns: `Memory` or `{ ok: false, error }` on `E_NOT_FOUND`.
|
|
253
263
|
|
|
254
264
|
---
|
|
255
265
|
|
|
@@ -263,7 +273,7 @@ Update content and optionally tags for an existing memory. Returns both hashes.
|
|
|
263
273
|
| `content` | `string` | Yes | — | Replacement content |
|
|
264
274
|
| `tags` | `string[]` | No | Existing tags | Replacement tags |
|
|
265
275
|
|
|
266
|
-
Returns: `{
|
|
276
|
+
Returns: `{ old_hash, new_hash }`
|
|
267
277
|
|
|
268
278
|
---
|
|
269
279
|
|
|
@@ -275,7 +285,7 @@ Delete one memory by hash. Cascades to related relationship rows.
|
|
|
275
285
|
| ------ | -------- | -------- | ----------- |
|
|
276
286
|
| `hash` | `string` | Yes | Memory hash |
|
|
277
287
|
|
|
278
|
-
Returns: `{
|
|
288
|
+
Returns: `{ hash, deleted }`
|
|
279
289
|
|
|
280
290
|
---
|
|
281
291
|
|
|
@@ -287,7 +297,7 @@ Delete multiple memories by hash in one transaction.
|
|
|
287
297
|
| -------- | ---------- | -------- | ------------------ |
|
|
288
298
|
| `hashes` | `string[]` | Yes | 1–50 memory hashes |
|
|
289
299
|
|
|
290
|
-
Returns: `{
|
|
300
|
+
Returns: `{ items, succeeded, failed }`
|
|
291
301
|
|
|
292
302
|
---
|
|
293
303
|
|
|
@@ -304,7 +314,7 @@ Full-text search over memory content and tags using FTS5. Supports importance an
|
|
|
304
314
|
| `max_importance` | `integer` | No | — | Only return memories with importance <= this value (0–10) |
|
|
305
315
|
| `memory_type` | enum | No | — | Filter by memory type |
|
|
306
316
|
|
|
307
|
-
Returns: `{
|
|
317
|
+
Returns: `{ memories, total_returned, nextCursor? }`
|
|
308
318
|
|
|
309
319
|
---
|
|
310
320
|
|
|
@@ -320,7 +330,7 @@ Suggested `relation_type` values: `related_to`, `causes`, `depends_on`, `parent_
|
|
|
320
330
|
| `to_hash` | `string` | Yes | Target memory hash |
|
|
321
331
|
| `relation_type` | `string` | Yes | Edge label (1–50 chars, no whitespace, free-form) |
|
|
322
332
|
|
|
323
|
-
Returns: `{
|
|
333
|
+
Returns: `{ created }`
|
|
324
334
|
|
|
325
335
|
---
|
|
326
336
|
|
|
@@ -334,7 +344,7 @@ Delete one directed relationship edge.
|
|
|
334
344
|
| `to_hash` | `string` | Yes | Target hash |
|
|
335
345
|
| `relation_type` | `string` | Yes | Relationship type |
|
|
336
346
|
|
|
337
|
-
Returns: `{
|
|
347
|
+
Returns: `{ deleted }` or `{ ok: false, error }` on `E_NOT_FOUND`.
|
|
338
348
|
|
|
339
349
|
---
|
|
340
350
|
|
|
@@ -347,7 +357,7 @@ Retrieve relationships for a memory, with optional direction filter.
|
|
|
347
357
|
| `hash` | `string` | Yes | — | Memory hash |
|
|
348
358
|
| `direction` | enum | No | `both` | `outgoing`, `incoming`, or `both` |
|
|
349
359
|
|
|
350
|
-
Returns: `{
|
|
360
|
+
Returns: `{ relationships, count }`
|
|
351
361
|
|
|
352
362
|
Each relationship includes `from_hash`, `to_hash`, `relation_type`, `created_at`, `linked_hash`, `linked_content`, and `linked_tags`.
|
|
353
363
|
|
|
@@ -367,7 +377,7 @@ Search memories by full-text query, then traverse the relationship graph up to `
|
|
|
367
377
|
| `max_importance` | `integer` | No | — | Seed filter: only memories with importance <= value (0–10) |
|
|
368
378
|
| `memory_type` | enum | No | — | Seed filter: only memories of this type |
|
|
369
379
|
|
|
370
|
-
Returns: `{
|
|
380
|
+
Returns: `{ memories, graph, depth_reached, aborted?, nextCursor? }`
|
|
371
381
|
|
|
372
382
|
Each item in `graph` uses the shape:
|
|
373
383
|
|
|
@@ -390,7 +400,7 @@ Search memories and return relevance-ranked results that fit within a caller-spe
|
|
|
390
400
|
| `token_budget` | `integer` | No | `4000` | Maximum estimated tokens to return (100–200000) |
|
|
391
401
|
| `strategy` | enum | No | `relevance` | Sort order: `relevance` (FTS rank), `importance` (highest first), `recency` (newest first) |
|
|
392
402
|
|
|
393
|
-
Returns: `{
|
|
403
|
+
Returns: `{ memories, estimated_tokens, truncated }`
|
|
394
404
|
|
|
395
405
|
> [!TIP]
|
|
396
406
|
> Token estimation is approximate (content length ÷ 4). `truncated: true` means the budget was reached before all candidates were included.
|
|
@@ -405,17 +415,14 @@ Returns:
|
|
|
405
415
|
|
|
406
416
|
```json
|
|
407
417
|
{
|
|
408
|
-
"
|
|
409
|
-
|
|
410
|
-
"
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
"relationships": { "total": 0 },
|
|
417
|
-
"by_type": {}
|
|
418
|
-
}
|
|
418
|
+
"memories": {
|
|
419
|
+
"total": 0,
|
|
420
|
+
"oldest": null,
|
|
421
|
+
"newest": null,
|
|
422
|
+
"avg_importance": null
|
|
423
|
+
},
|
|
424
|
+
"relationships": { "total": 0 },
|
|
425
|
+
"by_type": {}
|
|
419
426
|
}
|
|
420
427
|
```
|
|
421
428
|
|
|
@@ -469,7 +476,7 @@ Returns:
|
|
|
469
476
|
| SQLite busy timeout | 5000 ms |
|
|
470
477
|
|
|
471
478
|
> [!NOTE]
|
|
472
|
-
> Cursor values are base64url-encoded
|
|
479
|
+
> Cursor values are opaque base64url-encoded tokens. Treat them as opaque and do not parse them.
|
|
473
480
|
|
|
474
481
|
## Security
|
|
475
482
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/completions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/completions/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAY9C,wBAAgB,4BAA4B,CAC1C,EAAE,EAAE,OAAO,GACV,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,EAAE,CAQ7B"}
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
const HASH_MAX_LENGTH = 64;
|
|
2
2
|
const HASH_COMPLETION_LIMIT = 101;
|
|
3
3
|
const HASH_COMPLETION_SQL = `SELECT hash FROM memories WHERE hash LIKE ? ESCAPE '\\' ORDER BY hash LIMIT ${HASH_COMPLETION_LIMIT}`;
|
|
4
|
+
function normalizeHashPrefix(value) {
|
|
5
|
+
return escapeLikePattern(value.slice(0, HASH_MAX_LENGTH));
|
|
6
|
+
}
|
|
4
7
|
// Returns a completion callback for the `hash` URI variable.
|
|
5
8
|
export function createHashCompletionCallback(db) {
|
|
6
9
|
return (value) => {
|
|
7
|
-
const escapedPrefix =
|
|
8
|
-
|
|
9
|
-
.
|
|
10
|
-
.all(`${escapedPrefix}%`)
|
|
11
|
-
|
|
10
|
+
const escapedPrefix = normalizeHashPrefix(value);
|
|
11
|
+
return db
|
|
12
|
+
.prepareOnce(HASH_COMPLETION_SQL)
|
|
13
|
+
.all(`${escapedPrefix}%`)
|
|
14
|
+
.map((row) => row.hash);
|
|
12
15
|
};
|
|
13
16
|
}
|
|
14
17
|
function escapeLikePattern(value) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/completions/index.ts"],"names":[],"mappings":"AAGA,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,MAAM,mBAAmB,GAAG,+EAA+E,qBAAqB,EAAE,CAAC;AAEnI,6DAA6D;AAC7D,MAAM,UAAU,4BAA4B,CAC1C,EAAW;IAEX,OAAO,CAAC,KAAa,EAAY,EAAE;QACjC,MAAM,aAAa,GAAG,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/completions/index.ts"],"names":[],"mappings":"AAGA,MAAM,eAAe,GAAG,EAAE,CAAC;AAC3B,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAClC,MAAM,mBAAmB,GAAG,+EAA+E,qBAAqB,EAAE,CAAC;AAEnI,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,4BAA4B,CAC1C,EAAW;IAEX,OAAO,CAAC,KAAa,EAAY,EAAE;QACjC,MAAM,aAAa,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;QACjD,OAAO,EAAE;aACN,WAAW,CAAU,mBAAmB,CAAC;aACzC,GAAG,CAAC,GAAG,aAAa,GAAG,CAAC;aACxB,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAa;IACtC,OAAO,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;AAC1C,CAAC"}
|
package/dist/db/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,YAAY,CAAC;AAiLzD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAWvD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,YAAY,GAAG,WAAW,CAElE"}
|
package/dist/db/index.js
CHANGED
|
@@ -4,8 +4,17 @@ import { DatabaseSync } from 'node:sqlite';
|
|
|
4
4
|
import { createTypedDb } from './typed.js';
|
|
5
5
|
const SQLITE_TIMEOUT_MS = 5000;
|
|
6
6
|
const STATEMENT_CACHE_SIZE = 1000;
|
|
7
|
+
const TARGET_SCHEMA_VERSION = 2;
|
|
7
8
|
const FTS5_CHECK_SQL = 'CREATE VIRTUAL TABLE IF NOT EXISTS __fts5_check USING fts5(x); DROP TABLE __fts5_check;';
|
|
8
9
|
const FTS5_REQUIRED_MESSAGE = 'SQLite FTS5 extension is not available. memory-mcp requires a SQLite build with FTS5 support.';
|
|
10
|
+
const DEFENSIVE_PRAGMA_SQL = 'PRAGMA defensive = ON';
|
|
11
|
+
const RELATIONSHIPS_TABLE_SQL = `CREATE TABLE IF NOT EXISTS relationships (
|
|
12
|
+
from_hash TEXT NOT NULL REFERENCES memories(hash) ON DELETE CASCADE ON UPDATE CASCADE,
|
|
13
|
+
to_hash TEXT NOT NULL REFERENCES memories(hash) ON DELETE CASCADE ON UPDATE CASCADE,
|
|
14
|
+
relation_type TEXT NOT NULL,
|
|
15
|
+
created_at TEXT NOT NULL,
|
|
16
|
+
PRIMARY KEY (from_hash, to_hash, relation_type)
|
|
17
|
+
) STRICT;`;
|
|
9
18
|
const SCHEMA_SQL = `
|
|
10
19
|
CREATE TABLE IF NOT EXISTS memories (
|
|
11
20
|
hash TEXT PRIMARY KEY NOT NULL,
|
|
@@ -41,13 +50,7 @@ const SCHEMA_SQL = `
|
|
|
41
50
|
VALUES ('delete', old.rowid, old.content, old.tags);
|
|
42
51
|
END;
|
|
43
52
|
|
|
44
|
-
|
|
45
|
-
from_hash TEXT NOT NULL REFERENCES memories(hash) ON DELETE CASCADE,
|
|
46
|
-
to_hash TEXT NOT NULL REFERENCES memories(hash) ON DELETE CASCADE,
|
|
47
|
-
relation_type TEXT NOT NULL,
|
|
48
|
-
created_at TEXT NOT NULL,
|
|
49
|
-
PRIMARY KEY (from_hash, to_hash, relation_type)
|
|
50
|
-
) STRICT;
|
|
53
|
+
${RELATIONSHIPS_TABLE_SQL}
|
|
51
54
|
|
|
52
55
|
CREATE INDEX IF NOT EXISTS idx_memories_importance
|
|
53
56
|
ON memories(importance DESC);
|
|
@@ -76,12 +79,69 @@ function ensureParentDir(path) {
|
|
|
76
79
|
}
|
|
77
80
|
mkdirSync(dirname(path), { recursive: true });
|
|
78
81
|
}
|
|
82
|
+
function readUserVersion(db) {
|
|
83
|
+
const row = db.prepare('PRAGMA user_version').get();
|
|
84
|
+
return row?.user_version ?? 0;
|
|
85
|
+
}
|
|
86
|
+
function writeUserVersion(db, version) {
|
|
87
|
+
db.exec(`PRAGMA user_version = ${version}`);
|
|
88
|
+
}
|
|
89
|
+
function needsRelationshipsCascadeUpdateMigration(db) {
|
|
90
|
+
const rows = db
|
|
91
|
+
.prepare("PRAGMA foreign_key_list('relationships')")
|
|
92
|
+
.all();
|
|
93
|
+
if (rows.length === 0) {
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
for (const row of rows) {
|
|
97
|
+
const isMemoryEdge = row.table === 'memories' &&
|
|
98
|
+
(row.from === 'from_hash' || row.from === 'to_hash');
|
|
99
|
+
if (!isMemoryEdge) {
|
|
100
|
+
continue;
|
|
101
|
+
}
|
|
102
|
+
if (row.on_update.toUpperCase() !== 'CASCADE') {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
function migrateRelationshipsCascadeUpdate(db) {
|
|
109
|
+
db.exec('BEGIN IMMEDIATE');
|
|
110
|
+
try {
|
|
111
|
+
db.exec('ALTER TABLE relationships RENAME TO relationships_old');
|
|
112
|
+
db.exec(RELATIONSHIPS_TABLE_SQL.replace(' IF NOT EXISTS', ''));
|
|
113
|
+
db.exec(`
|
|
114
|
+
INSERT INTO relationships (from_hash, to_hash, relation_type, created_at)
|
|
115
|
+
SELECT from_hash, to_hash, relation_type, created_at
|
|
116
|
+
FROM relationships_old
|
|
117
|
+
`);
|
|
118
|
+
db.exec('DROP TABLE relationships_old');
|
|
119
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_relationships_from ON relationships(from_hash)');
|
|
120
|
+
db.exec('CREATE INDEX IF NOT EXISTS idx_relationships_to ON relationships(to_hash)');
|
|
121
|
+
db.exec('COMMIT');
|
|
122
|
+
}
|
|
123
|
+
catch (err) {
|
|
124
|
+
db.exec('ROLLBACK');
|
|
125
|
+
throw err;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function applyMigrations(db) {
|
|
129
|
+
const currentVersion = readUserVersion(db);
|
|
130
|
+
const needsCascadeMigration = needsRelationshipsCascadeUpdateMigration(db);
|
|
131
|
+
if (needsCascadeMigration) {
|
|
132
|
+
migrateRelationshipsCascadeUpdate(db);
|
|
133
|
+
}
|
|
134
|
+
if (currentVersion < TARGET_SCHEMA_VERSION || needsCascadeMigration) {
|
|
135
|
+
writeUserVersion(db, TARGET_SCHEMA_VERSION);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
79
138
|
function configureDatabase(db) {
|
|
80
139
|
// Enable defensive mode (SQLite v3.39+ / Node 24.12+: prevents deliberate DB corruption)
|
|
81
|
-
db.exec(
|
|
140
|
+
db.exec(DEFENSIVE_PRAGMA_SQL);
|
|
82
141
|
// Verify FTS5 support
|
|
83
142
|
assertFts5Available(db);
|
|
84
143
|
db.exec(SCHEMA_SQL);
|
|
144
|
+
applyMigrations(db);
|
|
85
145
|
}
|
|
86
146
|
export function initDatabase(path) {
|
|
87
147
|
ensureParentDir(path);
|
package/dist/db/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAoB,MAAM,aAAa,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAgB,MAAM,YAAY,CAAC;AAEzD,MAAM,iBAAiB,GAAG,IAAI,CAAC;AAC/B,MAAM,oBAAoB,GAAG,IAAI,CAAC;AAClC,MAAM,cAAc,GAClB,yFAAyF,CAAC;AAC5F,MAAM,qBAAqB,GACzB,+FAA+F,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/db/index.ts"],"names":[],"mappings":"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"}
|
package/dist/db/typed.d.ts
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import type { DatabaseSync, SQLInputValue, StatementResultingChanges } from 'node:sqlite';
|
|
2
|
+
type SqlParams = readonly SQLInputValue[];
|
|
2
3
|
export interface TypedStatement<T> {
|
|
3
|
-
all(...params:
|
|
4
|
-
get(...params:
|
|
5
|
-
run(...params:
|
|
4
|
+
all(...params: SqlParams): T[];
|
|
5
|
+
get(...params: SqlParams): T | undefined;
|
|
6
|
+
run(...params: SqlParams): StatementResultingChanges;
|
|
6
7
|
}
|
|
7
8
|
export declare class TypedDb {
|
|
8
9
|
private readonly db;
|
|
10
|
+
private readonly cache;
|
|
9
11
|
constructor(db: DatabaseSync);
|
|
12
|
+
private makeStatement;
|
|
10
13
|
prepare<T>(sql: string): TypedStatement<T>;
|
|
14
|
+
prepareOnce<T>(sql: string): TypedStatement<T>;
|
|
15
|
+
transaction<T>(action: () => T): T;
|
|
11
16
|
exec(sql: string): void;
|
|
12
17
|
close(): void;
|
|
13
18
|
}
|
|
14
19
|
export declare function createTypedDb(db: DatabaseSync): TypedDb;
|
|
20
|
+
export {};
|
|
15
21
|
//# sourceMappingURL=typed.d.ts.map
|
package/dist/db/typed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed.d.ts","sourceRoot":"","sources":["../../src/db/typed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,GAAG,CAAC,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"typed.d.ts","sourceRoot":"","sources":["../../src/db/typed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,yBAAyB,EAC1B,MAAM,aAAa,CAAC;AAErB,KAAK,SAAS,GAAG,SAAS,aAAa,EAAE,CAAC;AAE1C,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,GAAG,CAAC,GAAG,MAAM,EAAE,SAAS,GAAG,CAAC,EAAE,CAAC;IAC/B,GAAG,CAAC,GAAG,MAAM,EAAE,SAAS,GAAG,CAAC,GAAG,SAAS,CAAC;IACzC,GAAG,CAAC,GAAG,MAAM,EAAE,SAAS,GAAG,yBAAyB,CAAC;CACtD;AAED,qBAAa,OAAO;IAGN,OAAO,CAAC,QAAQ,CAAC,EAAE;IAF/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA8C;gBAEvC,EAAE,EAAE,YAAY;IAE7C,OAAO,CAAC,aAAa;IAcrB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC;IAI1C,WAAW,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,cAAc,CAAC,CAAC,CAAC;IAU9C,WAAW,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC;IAYlC,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAIvB,KAAK,IAAI,IAAI;CAId;AAED,wBAAgB,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,OAAO,CAEvD"}
|
package/dist/db/typed.js
CHANGED
|
@@ -1,20 +1,49 @@
|
|
|
1
1
|
export class TypedDb {
|
|
2
2
|
db;
|
|
3
|
+
cache = new Map();
|
|
3
4
|
constructor(db) {
|
|
4
5
|
this.db = db;
|
|
5
6
|
}
|
|
6
|
-
|
|
7
|
+
makeStatement(sql) {
|
|
7
8
|
const stmt = this.db.prepare(sql);
|
|
9
|
+
const materializeParams = (...params) => [
|
|
10
|
+
...params,
|
|
11
|
+
];
|
|
8
12
|
return {
|
|
9
|
-
all: (...params) => stmt.all(...params),
|
|
10
|
-
get: (...params) => stmt.get(...params),
|
|
11
|
-
run: (...params) => stmt.run(...params),
|
|
13
|
+
all: (...params) => stmt.all(...materializeParams(...params)),
|
|
14
|
+
get: (...params) => stmt.get(...materializeParams(...params)),
|
|
15
|
+
run: (...params) => stmt.run(...materializeParams(...params)),
|
|
12
16
|
};
|
|
13
17
|
}
|
|
18
|
+
prepare(sql) {
|
|
19
|
+
return this.makeStatement(sql);
|
|
20
|
+
}
|
|
21
|
+
prepareOnce(sql) {
|
|
22
|
+
const cached = this.cache.get(sql);
|
|
23
|
+
if (cached !== undefined) {
|
|
24
|
+
return cached;
|
|
25
|
+
}
|
|
26
|
+
const stmt = this.makeStatement(sql);
|
|
27
|
+
this.cache.set(sql, stmt);
|
|
28
|
+
return stmt;
|
|
29
|
+
}
|
|
30
|
+
transaction(action) {
|
|
31
|
+
this.db.exec('BEGIN IMMEDIATE');
|
|
32
|
+
try {
|
|
33
|
+
const result = action();
|
|
34
|
+
this.db.exec('COMMIT');
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
this.db.exec('ROLLBACK');
|
|
39
|
+
throw err;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
14
42
|
exec(sql) {
|
|
15
43
|
this.db.exec(sql);
|
|
16
44
|
}
|
|
17
45
|
close() {
|
|
46
|
+
this.cache.clear();
|
|
18
47
|
this.db.close();
|
|
19
48
|
}
|
|
20
49
|
}
|
package/dist/db/typed.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"typed.js","sourceRoot":"","sources":["../../src/db/typed.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"typed.js","sourceRoot":"","sources":["../../src/db/typed.ts"],"names":[],"mappings":"AAcA,MAAM,OAAO,OAAO;IAGW;IAFZ,KAAK,GAAG,IAAI,GAAG,EAAmC,CAAC;IAEpE,YAA6B,EAAgB;QAAhB,OAAE,GAAF,EAAE,CAAc;IAAG,CAAC;IAEzC,aAAa,CAAI,GAAW;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,iBAAiB,GAAG,CAAC,GAAG,MAAiB,EAAmB,EAAE,CAAC;YACnE,GAAG,MAAM;SACV,CAAC;QACF,OAAO;YACL,GAAG,EAAE,CAAC,GAAG,MAAiB,EAAE,EAAE,CAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,MAAM,CAAC,CAAQ;YAClD,GAAG,EAAE,CAAC,GAAG,MAAiB,EAAE,EAAE,CAC5B,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,MAAM,CAAC,CAAkB;YAC5D,GAAG,EAAE,CAAC,GAAG,MAAiB,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,MAAM,CAAC,CAAC;SACzE,CAAC;IACJ,CAAC;IAED,OAAO,CAAI,GAAW;QACpB,OAAO,IAAI,CAAC,aAAa,CAAI,GAAG,CAAC,CAAC;IACpC,CAAC;IAED,WAAW,CAAI,GAAW;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,MAA2B,CAAC;QACrC,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,aAAa,CAAI,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,WAAW,CAAI,MAAe;QAC5B,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAChC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC;YACxB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACzB,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAW;QACd,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpB,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACnB,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;CACF;AAED,MAAM,UAAU,aAAa,CAAC,EAAgB;IAC5C,OAAO,IAAI,OAAO,CAAC,EAAE,CAAC,CAAC;AACzB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,15 +2,13 @@
|
|
|
2
2
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
3
3
|
import process from 'node:process';
|
|
4
4
|
import { initTypedDatabase } from './db/index.js';
|
|
5
|
+
import { getErrorMessage } from './lib/errors.js';
|
|
5
6
|
import { createServer } from './server.js';
|
|
6
7
|
const MEMORY_DB_PATH = process.env['MEMORY_DB_PATH'] ?? 'memory.db';
|
|
7
8
|
const SHUTDOWN_SIGNALS = ['SIGINT', 'SIGTERM'];
|
|
8
9
|
const SHUTDOWN_TIMEOUT_MS = 3000;
|
|
9
10
|
const FORCED_EXIT_CODE = 1;
|
|
10
11
|
const CLEAN_EXIT_CODE = 0;
|
|
11
|
-
function formatFatalError(err) {
|
|
12
|
-
return err instanceof Error ? err.message : String(err);
|
|
13
|
-
}
|
|
14
12
|
function registerShutdownHandlers(shutdown) {
|
|
15
13
|
for (const signal of SHUTDOWN_SIGNALS) {
|
|
16
14
|
process.on(signal, shutdown);
|
|
@@ -24,16 +22,23 @@ function scheduleForcedShutdown() {
|
|
|
24
22
|
timer.unref();
|
|
25
23
|
return timer;
|
|
26
24
|
}
|
|
27
|
-
async function
|
|
28
|
-
const timer = scheduleForcedShutdown();
|
|
25
|
+
async function closeServer(server) {
|
|
29
26
|
try {
|
|
30
27
|
await server.close();
|
|
31
28
|
}
|
|
32
29
|
catch {
|
|
33
30
|
// ignore close errors
|
|
34
31
|
}
|
|
35
|
-
|
|
36
|
-
|
|
32
|
+
}
|
|
33
|
+
async function runShutdown(server, db) {
|
|
34
|
+
const timer = scheduleForcedShutdown();
|
|
35
|
+
try {
|
|
36
|
+
await closeServer(server);
|
|
37
|
+
db.close();
|
|
38
|
+
}
|
|
39
|
+
finally {
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
}
|
|
37
42
|
process.exit(CLEAN_EXIT_CODE);
|
|
38
43
|
}
|
|
39
44
|
function createShutdownHandler(server, db) {
|
|
@@ -54,7 +59,7 @@ async function main() {
|
|
|
54
59
|
await server.connect(transport);
|
|
55
60
|
}
|
|
56
61
|
main().catch((err) => {
|
|
57
|
-
process.stderr.write(`Fatal error: ${
|
|
62
|
+
process.stderr.write(`Fatal error: ${getErrorMessage(err)}\n`);
|
|
58
63
|
process.exit(FORCED_EXIT_CODE);
|
|
59
64
|
});
|
|
60
65
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,WAAW,CAAC;AACpE,MAAM,gBAAgB,GAAqB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACjE,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACjC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,SAAS,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AAEjF,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,WAAW,CAAC;AACpE,MAAM,gBAAgB,GAAqB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;AACjE,MAAM,mBAAmB,GAAG,IAAI,CAAC;AACjC,MAAM,gBAAgB,GAAG,CAAC,CAAC;AAC3B,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,SAAS,wBAAwB,CAAC,QAAoB;IACpD,KAAK,MAAM,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACtC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB;IAC7B,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;IACjC,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACxB,KAAK,CAAC,KAAK,EAAE,CAAC;IACd,OAAO,KAAK,CAAC;AACf,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,MAAuC;IAEvC,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CACxB,MAAuC,EACvC,EAAwC;IAExC,MAAM,KAAK,GAAG,sBAAsB,EAAE,CAAC;IACvC,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAC1B,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,qBAAqB,CAC5B,MAAuC,EACvC,EAAwC;IAExC,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,OAAO,GAAG,EAAE;QACV,IAAI,cAAc;YAAE,OAAO;QAC3B,cAAc,GAAG,IAAI,CAAC;QACtB,KAAK,WAAW,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,EAAE,GAAG,iBAAiB,CAAC,cAAc,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,QAAQ,GAAG,qBAAqB,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACnD,wBAAwB,CAAC,QAAQ,CAAC,CAAC;IAEnC,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;AAClC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAY,EAAE,EAAE;IAC5B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC/D,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;AACjC,CAAC,CAAC,CAAC"}
|