@codemem/mcp 0.38.0-alpha.1 → 0.38.0-alpha.2

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/dist/http.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as e } from "./server-BH_IcTFq.js";
2
+ import { t as e } from "./server-pfLtHrsT.js";
3
3
  import { createServer as t } from "node:http";
4
4
  import { isIP as n, isIPv6 as r } from "node:net";
5
5
  import { pathToFileURL as i } from "node:url";
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { t as e } from "./server-BH_IcTFq.js";
1
+ import { t as e } from "./server-pfLtHrsT.js";
2
2
  export { e as createCodememMcpServer };
@@ -1,18 +1,21 @@
1
- import { VERSION as e, dedupeOrderedIds as t, projectMatchesFilter as n, resolveProject as r, storeVectors as i, toJson as a } from "@codemem/core";
2
- import { McpServer as o } from "@modelcontextprotocol/sdk/server/mcp.js";
3
- import { z as s } from "zod";
1
+ import { ObserverClient as e, VERSION as t, buildDistillReport as n, dedupeOrderedIds as r, judgeDistillReport as i, projectMatchesFilter as a, resolveProject as o, resolveProjectRoot as s, storeVectors as c, toJson as l } from "@codemem/core";
2
+ import { existsSync as u, readFileSync as d } from "node:fs";
3
+ import { homedir as f } from "node:os";
4
+ import { join as p } from "node:path";
5
+ import { McpServer as m } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ import { z as h } from "zod";
4
7
  //#region src/project-scope.ts
5
- function c(e) {
8
+ function g(e) {
6
9
  return e?.trim() || null;
7
10
  }
8
- function l() {
9
- return c(process.env.CODEMEM_PROJECT) ?? r(process.cwd());
11
+ function _() {
12
+ return g(process.env.CODEMEM_PROJECT) ?? o(process.cwd());
10
13
  }
11
- function u(e) {
12
- return c(e.project) ?? c(e.envProject) ?? null;
14
+ function v(e) {
15
+ return g(e.project) ?? g(e.envProject) ?? null;
13
16
  }
14
- function d(e, t = l()) {
15
- let n = {}, r = !1, i = (typeof e.project == "string" ? c(e.project) : void 0) || c(t) || void 0;
17
+ function y(e, t = _()) {
18
+ let n = {}, r = !1, i = (typeof e.project == "string" ? g(e.project) : void 0) || g(t) || void 0;
16
19
  i && (n.project = i, r = !0);
17
20
  for (let t of [
18
21
  "kind",
@@ -44,139 +47,220 @@ function d(e, t = l()) {
44
47
  }
45
48
  //#endregion
46
49
  //#region src/content.ts
47
- function f(e) {
50
+ function b(e) {
48
51
  return { content: [{
49
52
  type: "text",
50
53
  text: JSON.stringify(e)
51
54
  }] };
52
55
  }
53
- function p(e) {
56
+ function x(e) {
54
57
  return { content: [{
55
58
  type: "text",
56
59
  text: JSON.stringify({ error: e })
57
60
  }] };
58
61
  }
59
62
  //#endregion
63
+ //#region src/schemas.ts
64
+ var S = {
65
+ scope_id: h.string().optional().describe("Filter by a single sharing domain scope_id"),
66
+ include_scope_ids: h.array(h.string()).optional().describe("Sharing domain scope_ids to include"),
67
+ exclude_scope_ids: h.array(h.string()).optional().describe("Sharing domain scope_ids to exclude")
68
+ }, C = {
69
+ kind: h.string().optional().describe("Filter by memory kind"),
70
+ project: h.string().optional().describe("Filter by project scope (matches sessions.project)"),
71
+ ...S,
72
+ visibility: h.array(h.string()).optional(),
73
+ include_visibility: h.array(h.string()).optional(),
74
+ exclude_visibility: h.array(h.string()).optional(),
75
+ include_workspace_ids: h.array(h.string()).optional(),
76
+ exclude_workspace_ids: h.array(h.string()).optional(),
77
+ include_workspace_kinds: h.array(h.string()).optional(),
78
+ exclude_workspace_kinds: h.array(h.string()).optional(),
79
+ include_actor_ids: h.array(h.string()).optional(),
80
+ exclude_actor_ids: h.array(h.string()).optional(),
81
+ include_trust_states: h.array(h.string()).optional(),
82
+ exclude_trust_states: h.array(h.string()).optional(),
83
+ ownership_scope: h.string().optional(),
84
+ personal_first: h.union([h.boolean(), h.string()]).optional(),
85
+ trust_bias: h.string().optional(),
86
+ widen_shared_when_weak: h.union([h.boolean(), h.string()]).optional(),
87
+ widen_shared_min_personal_results: h.number().int().optional(),
88
+ widen_shared_min_personal_score: h.number().optional()
89
+ }, w = h.enum([
90
+ "discovery",
91
+ "change",
92
+ "feature",
93
+ "bugfix",
94
+ "refactor",
95
+ "decision",
96
+ "exploration"
97
+ ]), T = Object.keys(C).toSorted();
98
+ //#endregion
99
+ //#region src/tools/distill.ts
100
+ function E(e, t, n) {
101
+ if (!u(e)) return null;
102
+ let r = d(e, "utf8");
103
+ return r.trim() ? {
104
+ path: t,
105
+ text: r,
106
+ scope: n
107
+ } : null;
108
+ }
109
+ function D(e, t = process.cwd()) {
110
+ let n = s(t) ?? t;
111
+ return [e ? E(p(n, "AGENTS.md"), "AGENTS.md", "project") : null, E(p(f(), ".config", "opencode", "AGENTS.md"), "~/.config/opencode/AGENTS.md", "user")].filter((e) => e != null);
112
+ }
113
+ function O(e, t) {
114
+ if (e.all_projects) return !1;
115
+ let n = o(process.cwd());
116
+ if (!n) return !1;
117
+ let r = typeof e.project == "string" ? e.project.trim() : "", i = r ? o(process.cwd(), r) : t;
118
+ return i ? a(i, n) : !1;
119
+ }
120
+ function k(e, t) {
121
+ if (e.all_projects && typeof e.project == "string" && e.project.trim()) throw Error("project cannot be combined with all_projects");
122
+ return y(e, e.all_projects ? null : t);
123
+ }
124
+ function A(t, r) {
125
+ let { defaultProject: a, store: o } = r;
126
+ t.tool("memory_distill_candidates", "Mine recurring memories into reviewable context candidates. Read-only; does not modify context files.", {
127
+ limit: h.number().int().min(1).max(50).default(10).describe("Max candidates"),
128
+ min_recurrence: h.number().int().min(1).max(50).default(2).describe("Minimum member count per candidate"),
129
+ all_projects: h.boolean().default(!1).describe("Mine memories across all projects"),
130
+ include_documented: h.boolean().default(!1).describe("Include candidates already represented in context files"),
131
+ max_evidence_items: h.number().int().min(1).max(20).default(5).describe("Evidence snippets per candidate"),
132
+ judge: h.boolean().default(!0).describe("Judge candidates with the observer model and drop routine-activity clusters (on by default; falls back to unjudged output when no observer model is configured)"),
133
+ ...C
134
+ }, async (t) => {
135
+ try {
136
+ let r = a(), s = k(t, r), c = t.kind ? [t.kind] : void 0, l = t.judge ? Math.min(t.limit * 3, t.limit + 20) : t.limit, u = await n(o, {
137
+ candidate: {
138
+ includeDocumented: t.include_documented,
139
+ maxEvidenceItems: t.max_evidence_items
140
+ },
141
+ contextDocuments: D(O(t, r)),
142
+ corpus: {
143
+ filters: s ?? null,
144
+ kinds: c
145
+ },
146
+ limit: l,
147
+ minRecurrence: t.min_recurrence
148
+ });
149
+ if (t.judge) {
150
+ try {
151
+ let t = new e();
152
+ u = await i(u, async (e, n) => (await t.observe(e, n)).raw);
153
+ } catch (e) {
154
+ let t = e instanceof Error ? e.message : String(e);
155
+ u = {
156
+ ...u,
157
+ metadata: {
158
+ ...u.metadata,
159
+ judged: !1,
160
+ judge_error: t
161
+ }
162
+ };
163
+ }
164
+ u.candidates.length > t.limit && (u = {
165
+ ...u,
166
+ candidates: u.candidates.slice(0, t.limit),
167
+ metadata: {
168
+ ...u.metadata,
169
+ candidate_count: t.limit
170
+ }
171
+ });
172
+ }
173
+ return b(u);
174
+ } catch (e) {
175
+ return x(e instanceof Error ? e.message : String(e));
176
+ }
177
+ });
178
+ }
179
+ //#endregion
60
180
  //#region src/memory-access.ts
61
- function m(e, t, n) {
181
+ function j(e, t, n) {
62
182
  return e.timeline(null, t, 0, 0, n ?? null).find((e) => e.id === t) ?? null;
63
183
  }
64
- function h(e, t, n) {
184
+ function M(e, t, n) {
65
185
  if (t.length === 0) return [];
66
186
  let r = [];
67
187
  for (let i of t) {
68
- let t = m(e, i, n);
188
+ let t = j(e, i, n);
69
189
  t && r.push(t);
70
190
  }
71
191
  return r;
72
192
  }
73
- function g(e, t, n) {
74
- return m(e, t, n) ? (e.forget(t), !0) : !1;
193
+ function N(e, t, n) {
194
+ return j(e, t, n) ? (e.forget(t), !0) : !1;
75
195
  }
76
- function _(e, t, n = {}) {
196
+ function P(e, t, n = {}) {
77
197
  return e.db.transaction(() => {
78
- let r = n.now?.() ?? (/* @__PURE__ */ new Date()).toISOString(), i = n.user ?? process.env.USER ?? "unknown", o = n.cwd ?? process.cwd(), s = u({
198
+ let r = n.now?.() ?? (/* @__PURE__ */ new Date()).toISOString(), i = n.user ?? process.env.USER ?? "unknown", a = n.cwd ?? process.cwd(), o = v({
79
199
  project: t.project,
80
200
  envProject: n.envProject
81
- }), c = e.db.prepare("INSERT INTO sessions(started_at, ended_at, cwd, project, user, tool_version, metadata_json)\n VALUES (?, ?, ?, ?, ?, ?, ?)").run(r, r, o, s, i, "mcp-ts", a({ mcp: !0 })), l = Number(c.lastInsertRowid), d = e.remember(l, t.kind, t.title, t.body, t.confidence);
82
- if (!m(e, d)) throw Error("unauthorized_scope");
83
- return e.db.prepare("UPDATE sessions SET ended_at = ?, metadata_json = ? WHERE id = ?").run(n.now?.() ?? (/* @__PURE__ */ new Date()).toISOString(), a({ mcp: !0 }), l), {
84
- memId: d,
201
+ }), s = e.db.prepare("INSERT INTO sessions(started_at, ended_at, cwd, project, user, tool_version, metadata_json)\n VALUES (?, ?, ?, ?, ?, ?, ?)").run(r, r, a, o, i, "mcp-ts", l({ mcp: !0 })), c = Number(s.lastInsertRowid), u = e.remember(c, t.kind, t.title, t.body, t.confidence);
202
+ if (!j(e, u)) throw Error("unauthorized_scope");
203
+ return e.db.prepare("UPDATE sessions SET ended_at = ?, metadata_json = ? WHERE id = ?").run(n.now?.() ?? (/* @__PURE__ */ new Date()).toISOString(), l({ mcp: !0 }), c), {
204
+ memId: u,
85
205
  title: t.title,
86
206
  body: t.body
87
207
  };
88
208
  })();
89
209
  }
90
210
  //#endregion
91
- //#region src/schemas.ts
92
- var v = {
93
- scope_id: s.string().optional().describe("Filter by a single sharing domain scope_id"),
94
- include_scope_ids: s.array(s.string()).optional().describe("Sharing domain scope_ids to include"),
95
- exclude_scope_ids: s.array(s.string()).optional().describe("Sharing domain scope_ids to exclude")
96
- }, y = {
97
- kind: s.string().optional().describe("Filter by memory kind"),
98
- project: s.string().optional().describe("Filter by project scope (matches sessions.project)"),
99
- ...v,
100
- visibility: s.array(s.string()).optional(),
101
- include_visibility: s.array(s.string()).optional(),
102
- exclude_visibility: s.array(s.string()).optional(),
103
- include_workspace_ids: s.array(s.string()).optional(),
104
- exclude_workspace_ids: s.array(s.string()).optional(),
105
- include_workspace_kinds: s.array(s.string()).optional(),
106
- exclude_workspace_kinds: s.array(s.string()).optional(),
107
- include_actor_ids: s.array(s.string()).optional(),
108
- exclude_actor_ids: s.array(s.string()).optional(),
109
- include_trust_states: s.array(s.string()).optional(),
110
- exclude_trust_states: s.array(s.string()).optional(),
111
- ownership_scope: s.string().optional(),
112
- personal_first: s.union([s.boolean(), s.string()]).optional(),
113
- trust_bias: s.string().optional(),
114
- widen_shared_when_weak: s.union([s.boolean(), s.string()]).optional(),
115
- widen_shared_min_personal_results: s.number().int().optional(),
116
- widen_shared_min_personal_score: s.number().optional()
117
- }, b = s.enum([
118
- "discovery",
119
- "change",
120
- "feature",
121
- "bugfix",
122
- "refactor",
123
- "decision",
124
- "exploration"
125
- ]), x = Object.keys(y).toSorted();
126
- //#endregion
127
211
  //#region src/tools/items.ts
128
- function S(e, t) {
212
+ function F(e, t) {
129
213
  let { envProject: n, store: r } = t;
130
214
  e.tool("memory_get", "Fetch a single memory item by ID.", {
131
- memory_id: s.number().int().describe("Memory ID"),
132
- ...y
215
+ memory_id: h.number().int().describe("Memory ID"),
216
+ ...C
133
217
  }, async (e) => {
134
218
  try {
135
- let t = m(r, e.memory_id, d(e, null));
136
- return t ? f(t) : p("not_found");
219
+ let t = j(r, e.memory_id, y(e, null));
220
+ return t ? b(t) : x("not_found");
137
221
  } catch (e) {
138
- return p(e instanceof Error ? e.message : String(e));
222
+ return x(e instanceof Error ? e.message : String(e));
139
223
  }
140
224
  }), e.tool("memory_get_observations", "Fetch multiple memory items by their IDs.", {
141
- ids: s.array(s.number().int()).max(200).describe("Memory IDs to fetch"),
142
- ...y
225
+ ids: h.array(h.number().int()).max(200).describe("Memory IDs to fetch"),
226
+ ...C
143
227
  }, async (e) => {
144
228
  try {
145
- return f({ items: h(r, e.ids, d(e, null)) });
229
+ return b({ items: M(r, e.ids, y(e, null)) });
146
230
  } catch (e) {
147
- return p(e instanceof Error ? e.message : String(e));
231
+ return x(e instanceof Error ? e.message : String(e));
148
232
  }
149
233
  }), e.tool("memory_remember", "Create a new memory. Use for milestones, decisions, and notable facts.", {
150
- kind: b.describe("Memory kind"),
151
- title: s.string().describe("Short title"),
152
- body: s.string().describe("Body text (high-signal content)"),
153
- confidence: s.number().min(0).max(1).default(.5).describe("Confidence 0-1"),
154
- project: s.string().optional().describe("Project identifier")
234
+ kind: w.describe("Memory kind"),
235
+ title: h.string().describe("Short title"),
236
+ body: h.string().describe("Body text (high-signal content)"),
237
+ confidence: h.number().min(0).max(1).default(.5).describe("Confidence 0-1"),
238
+ project: h.string().optional().describe("Project identifier")
155
239
  }, async (e) => {
156
240
  try {
157
- let t = _(r, e, { envProject: n() });
241
+ let t = P(r, e, { envProject: n() });
158
242
  try {
159
- await i(r.db, t.memId, t.title, t.body);
243
+ await c(r.db, t.memId, t.title, t.body);
160
244
  } catch {}
161
- return f({ id: t.memId });
245
+ return b({ id: t.memId });
162
246
  } catch (e) {
163
- return p(e instanceof Error ? e.message : String(e));
247
+ return x(e instanceof Error ? e.message : String(e));
164
248
  }
165
249
  }), e.tool("memory_forget", "Soft-delete a memory item. Use for incorrect or sensitive data.", {
166
- memory_id: s.number().int().describe("Memory ID to forget"),
167
- ...y
250
+ memory_id: h.number().int().describe("Memory ID to forget"),
251
+ ...C
168
252
  }, async (e) => {
169
253
  try {
170
- return g(r, e.memory_id, d(e, null)) ? f({ status: "ok" }) : p("not_found");
254
+ return N(r, e.memory_id, y(e, null)) ? b({ status: "ok" }) : x("not_found");
171
255
  } catch (e) {
172
- return p(e instanceof Error ? e.message : String(e));
256
+ return x(e instanceof Error ? e.message : String(e));
173
257
  }
174
258
  });
175
259
  }
176
260
  //#endregion
177
261
  //#region src/tools/learn.ts
178
- function C(e) {
179
- e.tool("memory_learn", "Learn how to use codemem memory tools. Call this first if unfamiliar.", {}, async () => f({
262
+ function I(e) {
263
+ e.tool("memory_learn", "Learn how to use codemem memory tools. Call this first if unfamiliar.", {}, async () => b({
180
264
  intro: "Use this tool when you're new to codemem or unsure when to recall/persist.",
181
265
  client_hint: "If you are unfamiliar with codemem, call memory.learn first.",
182
266
  recall: {
@@ -245,7 +329,7 @@ function C(e) {
245
329
  }
246
330
  //#endregion
247
331
  //#region src/memory-kinds.ts
248
- var w = {
332
+ var L = {
249
333
  discovery: "Something learned about the codebase, architecture, or tools",
250
334
  change: "A code change that was made",
251
335
  feature: "A new feature that was implemented",
@@ -256,10 +340,10 @@ var w = {
256
340
  };
257
341
  //#endregion
258
342
  //#region src/tools/schema.ts
259
- function T(e) {
260
- e.tool("memory_schema", "Return the memory schema — kinds, fields, and available filters.", {}, async () => f({
261
- kinds: Object.keys(w),
262
- kind_descriptions: w,
343
+ function R(e) {
344
+ e.tool("memory_schema", "Return the memory schema — kinds, fields, and available filters.", {}, async () => b({
345
+ kinds: Object.keys(L),
346
+ kind_descriptions: L,
263
347
  fields: {
264
348
  title: "short text",
265
349
  body: "long text",
@@ -271,21 +355,21 @@ function T(e) {
271
355
  files_modified: "list<string>",
272
356
  prompt_number: "int"
273
357
  },
274
- filters: x
358
+ filters: T
275
359
  }));
276
360
  }
277
361
  //#endregion
278
362
  //#region src/tools/search.ts
279
- function E(e, t) {
363
+ function z(e, t) {
280
364
  let { defaultProject: n, store: r } = t;
281
365
  e.tool("memory_search", "Search memories by text query. Returns full body text for each match.", {
282
- query: s.string().describe("Search query"),
283
- limit: s.number().int().min(1).max(50).default(5).describe("Max results"),
284
- ...y
366
+ query: h.string().describe("Search query"),
367
+ limit: h.number().int().min(1).max(50).default(5).describe("Max results"),
368
+ ...C
285
369
  }, async (e) => {
286
370
  try {
287
- let t = d(e, n());
288
- return f({ items: r.search(e.query, e.limit, t).map((e) => ({
371
+ let t = y(e, n());
372
+ return b({ items: r.search(e.query, e.limit, t).map((e) => ({
289
373
  id: e.id,
290
374
  title: e.title,
291
375
  kind: e.kind,
@@ -296,16 +380,16 @@ function E(e, t) {
296
380
  metadata: e.metadata
297
381
  })) });
298
382
  } catch (e) {
299
- return p(e instanceof Error ? e.message : String(e));
383
+ return x(e instanceof Error ? e.message : String(e));
300
384
  }
301
385
  }), e.tool("memory_search_index", "Search memories by text query. Returns compact index entries (no body) for browsing.", {
302
- query: s.string().describe("Search query"),
303
- limit: s.number().int().min(1).max(50).default(8).describe("Max results"),
304
- ...y
386
+ query: h.string().describe("Search query"),
387
+ limit: h.number().int().min(1).max(50).default(8).describe("Max results"),
388
+ ...C
305
389
  }, async (e) => {
306
390
  try {
307
- let t = d(e, n());
308
- return f({ items: r.search(e.query, e.limit, t).map((e) => ({
391
+ let t = y(e, n());
392
+ return b({ items: r.search(e.query, e.limit, t).map((e) => ({
309
393
  id: e.id,
310
394
  kind: e.kind,
311
395
  title: e.title,
@@ -315,117 +399,117 @@ function E(e, t) {
315
399
  metadata: e.metadata
316
400
  })) });
317
401
  } catch (e) {
318
- return p(e instanceof Error ? e.message : String(e));
402
+ return x(e instanceof Error ? e.message : String(e));
319
403
  }
320
404
  }), e.tool("memory_explain", "Explain search results with detailed scoring breakdown.", {
321
- query: s.string().optional().describe("Search query"),
322
- ids: s.array(s.number().int()).max(200).optional().describe("Specific memory IDs to explain"),
323
- limit: s.number().int().min(1).max(50).default(10).describe("Max results"),
324
- include_pack_context: s.boolean().default(!1).describe("Include formatted pack context"),
325
- ...y
405
+ query: h.string().optional().describe("Search query"),
406
+ ids: h.array(h.number().int()).max(200).optional().describe("Specific memory IDs to explain"),
407
+ limit: h.number().int().min(1).max(50).default(10).describe("Max results"),
408
+ include_pack_context: h.boolean().default(!1).describe("Include formatted pack context"),
409
+ ...C
326
410
  }, async (e) => {
327
411
  try {
328
- let t = d(e, n());
329
- return f(r.explain(e.query ?? null, e.ids ?? null, e.limit, t, { includePackContext: e.include_pack_context }));
412
+ let t = y(e, n());
413
+ return b(r.explain(e.query ?? null, e.ids ?? null, e.limit, t, { includePackContext: e.include_pack_context }));
330
414
  } catch (e) {
331
- return p(e instanceof Error ? e.message : String(e));
415
+ return x(e instanceof Error ? e.message : String(e));
332
416
  }
333
417
  }), e.tool("memory_recent", "Return recent memories, newest first.", {
334
- limit: s.number().int().min(1).max(100).default(8).describe("Max results"),
335
- ...y
418
+ limit: h.number().int().min(1).max(100).default(8).describe("Max results"),
419
+ ...C
336
420
  }, async (e) => {
337
421
  try {
338
- let t = d(e, n());
339
- return f({ items: r.recent(e.limit, t) });
422
+ let t = y(e, n());
423
+ return b({ items: r.recent(e.limit, t) });
340
424
  } catch (e) {
341
- return p(e instanceof Error ? e.message : String(e));
425
+ return x(e instanceof Error ? e.message : String(e));
342
426
  }
343
427
  }), e.tool("memory_pack", "Build a formatted memory pack from search results — quick one-shot context block.", {
344
- context: s.string().describe("Context description to search for"),
345
- limit: s.number().int().min(1).max(50).optional().describe("Max items to include"),
346
- compact: s.boolean().optional().describe("When true, render a scannable index of all items with full detail only for the top N (default 3). Saves tokens when broad overview matters more than per-item detail."),
347
- compact_detail_count: s.number().int().min(0).max(50).optional().describe("Number of items to show in full detail in compact mode (default 3)"),
348
- compression_mode: s.enum([
428
+ context: h.string().describe("Context description to search for"),
429
+ limit: h.number().int().min(1).max(50).optional().describe("Max items to include"),
430
+ compact: h.boolean().optional().describe("When true, render a scannable index of all items with full detail only for the top N (default 3). Saves tokens when broad overview matters more than per-item detail."),
431
+ compact_detail_count: h.number().int().min(0).max(50).optional().describe("Number of items to show in full detail in compact mode (default 3)"),
432
+ compression_mode: h.enum([
349
433
  "off",
350
434
  "compact",
351
435
  "ids"
352
436
  ]).optional().describe("Near-related compression mode: off disables it, compact applies only to compact rendering, ids applies in all modes. Defaults to CODEMEM_PACK_COMPRESSION or compact."),
353
- ...y
437
+ ...C
354
438
  }, async (e) => {
355
439
  try {
356
- let t = d(e, n()), i = e.compact || e.compact_detail_count != null || e.compression_mode != null ? {
440
+ let t = y(e, n()), i = e.compact || e.compact_detail_count != null || e.compression_mode != null ? {
357
441
  compact: e.compact ?? (e.compact_detail_count == null ? void 0 : !0),
358
442
  compactDetailCount: e.compact_detail_count,
359
443
  compressionMode: e.compression_mode
360
444
  } : void 0;
361
- return f(await r.buildMemoryPackAsync(e.context, e.limit ?? void 0, null, t, i));
445
+ return b(await r.buildMemoryPackAsync(e.context, e.limit ?? void 0, null, t, i));
362
446
  } catch (e) {
363
- return p(e instanceof Error ? e.message : String(e));
447
+ return x(e instanceof Error ? e.message : String(e));
364
448
  }
365
449
  });
366
450
  }
367
451
  //#endregion
368
452
  //#region src/tools/timeline.ts
369
- function D(e, r) {
370
- let { defaultProject: i, store: a } = r;
453
+ function B(e, t) {
454
+ let { defaultProject: n, store: i } = t;
371
455
  e.tool("memory_timeline", "Get a chronological window of memories around an anchor (by ID or query).", {
372
- query: s.string().optional().describe("Search query to find anchor"),
373
- memory_id: s.number().int().optional().describe("Anchor memory ID"),
374
- depth_before: s.number().int().min(0).default(3).describe("Items before anchor"),
375
- depth_after: s.number().int().min(0).default(3).describe("Items after anchor"),
376
- ...y
456
+ query: h.string().optional().describe("Search query to find anchor"),
457
+ memory_id: h.number().int().optional().describe("Anchor memory ID"),
458
+ depth_before: h.number().int().min(0).default(3).describe("Items before anchor"),
459
+ depth_after: h.number().int().min(0).default(3).describe("Items after anchor"),
460
+ ...C
377
461
  }, async (e) => {
378
462
  try {
379
- let t = d(e, i());
380
- return f({ items: a.timeline(e.query ?? null, e.memory_id ?? null, e.depth_before, e.depth_after, t) });
463
+ let t = y(e, n());
464
+ return b({ items: i.timeline(e.query ?? null, e.memory_id ?? null, e.depth_before, e.depth_after, t) });
381
465
  } catch (e) {
382
- return p(e instanceof Error ? e.message : String(e));
466
+ return x(e instanceof Error ? e.message : String(e));
383
467
  }
384
468
  }), e.tool("memory_expand", "Fetch memories by ID with surrounding timeline context.", {
385
- ids: s.array(s.union([s.number(), s.string()])).max(200).describe("Memory IDs to expand"),
386
- depth_before: s.number().int().min(0).default(3).describe("Timeline items before"),
387
- depth_after: s.number().int().min(0).default(3).describe("Timeline items after"),
388
- include_observations: s.boolean().default(!1).describe("Include full observation details"),
389
- ...y
469
+ ids: h.array(h.union([h.number(), h.string()])).max(200).describe("Memory IDs to expand"),
470
+ depth_before: h.number().int().min(0).default(3).describe("Timeline items before"),
471
+ depth_after: h.number().int().min(0).default(3).describe("Timeline items after"),
472
+ include_observations: h.boolean().default(!1).describe("Include full observation details"),
473
+ ...C
390
474
  }, async (e) => {
391
475
  try {
392
- let r = d(e, e.project !== void 0 && !e.project.trim() ? null : i()), o = r?.project ?? null, { ordered: s, invalid: c } = t(e.ids), l = [];
476
+ let t = y(e, e.project !== void 0 && !e.project.trim() ? null : n()), o = t?.project ?? null, { ordered: s, invalid: c } = r(e.ids), l = [];
393
477
  c.length > 0 && l.push({
394
478
  code: "INVALID_ARGUMENT",
395
479
  field: "ids",
396
480
  message: "some ids are not valid integers",
397
481
  ids: c
398
482
  });
399
- let u = [], p = [], m = [], g = [], _ = [], v = /* @__PURE__ */ new Set(), y = /* @__PURE__ */ new Map();
400
- for (let t of s) {
401
- let i = a.get(t);
402
- if (!i?.active) {
403
- u.push(t);
483
+ let u = [], d = [], f = [], p = [], m = [], h = /* @__PURE__ */ new Set(), g = /* @__PURE__ */ new Map();
484
+ for (let n of s) {
485
+ let r = i.get(n);
486
+ if (!r?.active) {
487
+ u.push(n);
404
488
  continue;
405
489
  }
406
- let s = i.session_id;
490
+ let s = r.session_id;
407
491
  if (o && s > 0) {
408
- if (!y.has(s)) {
409
- let e = a.db.prepare("SELECT project FROM sessions WHERE id = ? LIMIT 1").get(s);
410
- y.set(s, typeof e?.project == "string" ? e.project : null);
492
+ if (!g.has(s)) {
493
+ let e = i.db.prepare("SELECT project FROM sessions WHERE id = ? LIMIT 1").get(s);
494
+ g.set(s, typeof e?.project == "string" ? e.project : null);
411
495
  }
412
- if (!n(o, y.get(s) ?? null)) {
413
- p.push(t);
496
+ if (!a(o, g.get(s) ?? null)) {
497
+ d.push(n);
414
498
  continue;
415
499
  }
416
500
  } else if (o && s <= 0) {
417
- p.push(t);
501
+ d.push(n);
418
502
  continue;
419
503
  }
420
- let c = a.timeline(null, t, e.depth_before, e.depth_after, r), l = c.find((e) => e.id === t);
504
+ let c = i.timeline(null, n, e.depth_before, e.depth_after, t), l = c.find((e) => e.id === n);
421
505
  if (!l) {
422
- m.push(t);
506
+ f.push(n);
423
507
  continue;
424
508
  }
425
- g.push(l);
509
+ p.push(l);
426
510
  for (let e of c) {
427
511
  let t = e.id;
428
- t <= 0 || v.has(t) || (v.add(t), _.push(e));
512
+ t <= 0 || h.has(t) || (h.add(t), m.push(e));
429
513
  }
430
514
  }
431
515
  u.length > 0 && l.push({
@@ -433,56 +517,56 @@ function D(e, r) {
433
517
  field: "ids",
434
518
  message: "some requested ids were not found",
435
519
  ids: u
436
- }), p.length > 0 && l.push({
520
+ }), d.length > 0 && l.push({
437
521
  code: "PROJECT_MISMATCH",
438
522
  field: "project",
439
523
  message: "some requested ids are outside the requested project scope",
440
- ids: p
441
- }), m.length > 0 && l.push({
524
+ ids: d
525
+ }), f.length > 0 && l.push({
442
526
  code: "FILTER_MISMATCH",
443
527
  field: "filters",
444
528
  message: "some requested ids are outside the requested filters",
445
- ids: m
529
+ ids: f
446
530
  });
447
- let b = [];
531
+ let _ = [];
448
532
  if (e.include_observations) {
449
- let e = /* @__PURE__ */ new Set(), t = [];
450
- for (let n of [...g, ..._]) n.id > 0 && !e.has(n.id) && (e.add(n.id), t.push(n.id));
451
- b = h(a, t, r);
533
+ let e = /* @__PURE__ */ new Set(), n = [];
534
+ for (let t of [...p, ...m]) t.id > 0 && !e.has(t.id) && (e.add(t.id), n.push(t.id));
535
+ _ = M(i, n, t);
452
536
  }
453
- return f({
454
- anchors: g,
455
- timeline: _,
456
- observations: b,
457
- missing_ids: s.filter((e) => u.includes(e) || p.includes(e) || m.includes(e)),
537
+ return b({
538
+ anchors: p,
539
+ timeline: m,
540
+ observations: _,
541
+ missing_ids: s.filter((e) => u.includes(e) || d.includes(e) || f.includes(e)),
458
542
  errors: l,
459
543
  metadata: {
460
544
  project: o,
461
545
  requested_ids_count: s.length,
462
- returned_anchor_count: g.length,
463
- timeline_count: _.length,
546
+ returned_anchor_count: p.length,
547
+ timeline_count: m.length,
464
548
  include_observations: e.include_observations
465
549
  }
466
550
  });
467
551
  } catch (e) {
468
- return p(e instanceof Error ? e.message : String(e));
552
+ return x(e instanceof Error ? e.message : String(e));
469
553
  }
470
554
  });
471
555
  }
472
556
  //#endregion
473
557
  //#region src/server.ts
474
- function O(t, n = {}) {
475
- let r = new o({
558
+ function V(e, n = {}) {
559
+ let r = new m({
476
560
  name: "codemem",
477
- version: e
561
+ version: t
478
562
  }), i = {
479
- store: t,
480
- defaultProject: () => n.resolveDefaultProject ? n.resolveDefaultProject() : n.defaultProject === void 0 ? l() : n.defaultProject,
563
+ store: e,
564
+ defaultProject: () => n.resolveDefaultProject ? n.resolveDefaultProject() : n.defaultProject === void 0 ? _() : n.defaultProject,
481
565
  envProject: () => n.envProject === void 0 ? process.env.CODEMEM_PROJECT ?? null : n.envProject
482
566
  };
483
- return E(r, i), D(r, i), S(r, i), T(r), C(r), r;
567
+ return z(r, i), B(r, i), A(r, i), F(r, i), R(r), I(r), r;
484
568
  }
485
569
  //#endregion
486
- export { O as t };
570
+ export { V as t };
487
571
 
488
- //# sourceMappingURL=server-BH_IcTFq.js.map
572
+ //# sourceMappingURL=server-pfLtHrsT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server-pfLtHrsT.js","names":[],"sources":["../src/project-scope.ts","../src/content.ts","../src/schemas.ts","../src/tools/distill.ts","../src/memory-access.ts","../src/tools/items.ts","../src/tools/learn.ts","../src/memory-kinds.ts","../src/tools/schema.ts","../src/tools/search.ts","../src/tools/timeline.ts","../src/server.ts"],"sourcesContent":["import { type MemoryFilters, resolveProject } from \"@codemem/core\";\n\nfunction cleanProject(value: string | null | undefined): string | null {\n\tconst trimmed = value?.trim();\n\treturn trimmed ? trimmed : null;\n}\n\nexport function resolveDefaultProject(): string | null {\n\treturn cleanProject(process.env.CODEMEM_PROJECT) ?? resolveProject(process.cwd());\n}\n\nexport function resolveWriteProject(input: {\n\tproject?: string | null;\n\tenvProject?: string | null;\n}): string | null {\n\treturn cleanProject(input.project) ?? cleanProject(input.envProject) ?? null;\n}\n\nexport function buildFilters(\n\traw: Record<string, unknown>,\n\tdefaultProject = resolveDefaultProject(),\n): MemoryFilters | undefined {\n\tconst filters: MemoryFilters = {};\n\tlet hasAny = false;\n\n\tconst explicitProject = typeof raw.project === \"string\" ? cleanProject(raw.project) : undefined;\n\tconst resolvedProject = explicitProject || cleanProject(defaultProject) || undefined;\n\tif (resolvedProject) {\n\t\tfilters.project = resolvedProject;\n\t\thasAny = true;\n\t}\n\n\tfor (const key of [\n\t\t\"kind\",\n\t\t\"visibility\",\n\t\t\"scope_id\",\n\t\t\"include_scope_ids\",\n\t\t\"exclude_scope_ids\",\n\t\t\"include_visibility\",\n\t\t\"exclude_visibility\",\n\t\t\"include_workspace_ids\",\n\t\t\"exclude_workspace_ids\",\n\t\t\"include_workspace_kinds\",\n\t\t\"exclude_workspace_kinds\",\n\t\t\"include_actor_ids\",\n\t\t\"exclude_actor_ids\",\n\t\t\"include_trust_states\",\n\t\t\"exclude_trust_states\",\n\t\t\"ownership_scope\",\n\t\t\"personal_first\",\n\t\t\"trust_bias\",\n\t\t\"widen_shared_when_weak\",\n\t\t\"widen_shared_min_personal_results\",\n\t\t\"widen_shared_min_personal_score\",\n\t] as const) {\n\t\tconst val = raw[key];\n\t\tif (val !== undefined && val !== null) {\n\t\t\t(filters as Record<string, unknown>)[key] = val;\n\t\t\thasAny = true;\n\t\t}\n\t}\n\n\treturn hasAny ? filters : undefined;\n}\n","export function jsonContent(data: unknown) {\n\treturn { content: [{ type: \"text\" as const, text: JSON.stringify(data) }] };\n}\n\nexport function errorContent(message: string) {\n\treturn { content: [{ type: \"text\" as const, text: JSON.stringify({ error: message }) }] };\n}\n","import { z } from \"zod\";\n\nconst scopeFilterSchema = {\n\tscope_id: z.string().optional().describe(\"Filter by a single sharing domain scope_id\"),\n\tinclude_scope_ids: z.array(z.string()).optional().describe(\"Sharing domain scope_ids to include\"),\n\texclude_scope_ids: z.array(z.string()).optional().describe(\"Sharing domain scope_ids to exclude\"),\n};\n\nexport const filterSchema = {\n\tkind: z.string().optional().describe(\"Filter by memory kind\"),\n\tproject: z.string().optional().describe(\"Filter by project scope (matches sessions.project)\"),\n\t...scopeFilterSchema,\n\tvisibility: z.array(z.string()).optional(),\n\tinclude_visibility: z.array(z.string()).optional(),\n\texclude_visibility: z.array(z.string()).optional(),\n\tinclude_workspace_ids: z.array(z.string()).optional(),\n\texclude_workspace_ids: z.array(z.string()).optional(),\n\tinclude_workspace_kinds: z.array(z.string()).optional(),\n\texclude_workspace_kinds: z.array(z.string()).optional(),\n\tinclude_actor_ids: z.array(z.string()).optional(),\n\texclude_actor_ids: z.array(z.string()).optional(),\n\tinclude_trust_states: z.array(z.string()).optional(),\n\texclude_trust_states: z.array(z.string()).optional(),\n\townership_scope: z.string().optional(),\n\tpersonal_first: z.union([z.boolean(), z.string()]).optional(),\n\ttrust_bias: z.string().optional(),\n\twiden_shared_when_weak: z.union([z.boolean(), z.string()]).optional(),\n\twiden_shared_min_personal_results: z.number().int().optional(),\n\twiden_shared_min_personal_score: z.number().optional(),\n};\n\nexport const memoryKindSchema = z.enum([\n\t\"discovery\",\n\t\"change\",\n\t\"feature\",\n\t\"bugfix\",\n\t\"refactor\",\n\t\"decision\",\n\t\"exploration\",\n]);\n\nexport const filterNames = Object.keys(filterSchema).toSorted();\n","import { existsSync, readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport {\n\tbuildDistillReport,\n\ttype DistillContextDocument,\n\tjudgeDistillReport,\n\ttype MemoryFilters,\n\tObserverClient,\n\tprojectMatchesFilter,\n\tresolveProject,\n\tresolveProjectRoot,\n} from \"@codemem/core\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { errorContent, jsonContent } from \"../content.js\";\nimport { buildFilters } from \"../project-scope.js\";\nimport { filterSchema } from \"../schemas.js\";\nimport type { ToolRegistrationContext } from \"../tool-context.js\";\n\nfunction readContextFile(\n\tpath: string,\n\tdisplayPath: string,\n\tscope: DistillContextDocument[\"scope\"],\n): DistillContextDocument | null {\n\tif (!existsSync(path)) return null;\n\tconst text = readFileSync(path, \"utf8\");\n\treturn text.trim() ? { path: displayPath, text, scope } : null;\n}\n\nfunction loadDefaultContextDocuments(\n\tincludeProjectContext: boolean,\n\tcwd = process.cwd(),\n): DistillContextDocument[] {\n\t// The repo-root AGENTS.md describes the current repo (scope \"project\") and is\n\t// gated to current-project runs; the user-global context (scope \"user\")\n\t// always applies and never suppresses other projects' candidates. Resolve the\n\t// repo root so running from a subdirectory still finds the project context.\n\tconst projectRoot = resolveProjectRoot(cwd) ?? cwd;\n\tconst documents = [\n\t\tincludeProjectContext\n\t\t\t? readContextFile(join(projectRoot, \"AGENTS.md\"), \"AGENTS.md\", \"project\")\n\t\t\t: null,\n\t\treadContextFile(\n\t\t\tjoin(homedir(), \".config\", \"opencode\", \"AGENTS.md\"),\n\t\t\t\"~/.config/opencode/AGENTS.md\",\n\t\t\t\"user\",\n\t\t),\n\t];\n\treturn documents.filter((document): document is DistillContextDocument => document != null);\n}\n\nfunction shouldIncludeProjectContext(\n\targs: { all_projects?: boolean; project?: unknown },\n\tdefaultProject: string | null,\n): boolean {\n\tif (args.all_projects) return false;\n\tconst currentProject = resolveProject(process.cwd());\n\tif (!currentProject) return false;\n\tconst explicitProject = typeof args.project === \"string\" ? args.project.trim() : \"\";\n\t// Match the corpus filter: the cwd AGENTS.md is only valid when the mined\n\t// project (explicit arg or the server default project) is this repo.\n\tconst targetProject = explicitProject\n\t\t? resolveProject(process.cwd(), explicitProject)\n\t\t: defaultProject;\n\tif (!targetProject) return false;\n\treturn projectMatchesFilter(targetProject, currentProject);\n}\n\nfunction buildDistillFilters(\n\targs: { all_projects?: boolean } & Record<string, unknown>,\n\tdefaultProject: string | null,\n): MemoryFilters | undefined {\n\tif (args.all_projects && typeof args.project === \"string\" && args.project.trim()) {\n\t\tthrow new Error(\"project cannot be combined with all_projects\");\n\t}\n\treturn buildFilters(args, args.all_projects ? null : defaultProject);\n}\n\nexport function registerDistillTools(server: McpServer, context: ToolRegistrationContext): void {\n\tconst { defaultProject, store } = context;\n\n\tserver.tool(\n\t\t\"memory_distill_candidates\",\n\t\t\"Mine recurring memories into reviewable context candidates. Read-only; does not modify context files.\",\n\t\t{\n\t\t\tlimit: z.number().int().min(1).max(50).default(10).describe(\"Max candidates\"),\n\t\t\tmin_recurrence: z\n\t\t\t\t.number()\n\t\t\t\t.int()\n\t\t\t\t.min(1)\n\t\t\t\t.max(50)\n\t\t\t\t.default(2)\n\t\t\t\t.describe(\"Minimum member count per candidate\"),\n\t\t\tall_projects: z.boolean().default(false).describe(\"Mine memories across all projects\"),\n\t\t\tinclude_documented: z\n\t\t\t\t.boolean()\n\t\t\t\t.default(false)\n\t\t\t\t.describe(\"Include candidates already represented in context files\"),\n\t\t\tmax_evidence_items: z\n\t\t\t\t.number()\n\t\t\t\t.int()\n\t\t\t\t.min(1)\n\t\t\t\t.max(20)\n\t\t\t\t.default(5)\n\t\t\t\t.describe(\"Evidence snippets per candidate\"),\n\t\t\tjudge: z\n\t\t\t\t.boolean()\n\t\t\t\t.default(true)\n\t\t\t\t.describe(\n\t\t\t\t\t\"Judge candidates with the observer model and drop routine-activity clusters (on by default; falls back to unjudged output when no observer model is configured)\",\n\t\t\t\t),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst resolvedDefaultProject = defaultProject();\n\t\t\t\tconst filters = buildDistillFilters(args, resolvedDefaultProject);\n\t\t\t\tconst kinds = args.kind ? [args.kind] : undefined;\n\t\t\t\t// When judging, mine extra candidates so routine drops are backfilled\n\t\t\t\t// from the next-ranked clusters instead of shrinking the caller's limit.\n\t\t\t\tconst fetchLimit = args.judge ? Math.min(args.limit * 3, args.limit + 20) : args.limit;\n\t\t\t\tlet result = await buildDistillReport(store, {\n\t\t\t\t\tcandidate: {\n\t\t\t\t\t\tincludeDocumented: args.include_documented,\n\t\t\t\t\t\tmaxEvidenceItems: args.max_evidence_items,\n\t\t\t\t\t},\n\t\t\t\t\tcontextDocuments: loadDefaultContextDocuments(\n\t\t\t\t\t\tshouldIncludeProjectContext(args, resolvedDefaultProject),\n\t\t\t\t\t),\n\t\t\t\t\tcorpus: { filters: filters ?? null, kinds },\n\t\t\t\t\tlimit: fetchLimit,\n\t\t\t\t\tminRecurrence: args.min_recurrence,\n\t\t\t\t});\n\t\t\t\tif (args.judge) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst client = new ObserverClient();\n\t\t\t\t\t\tresult = await judgeDistillReport(result, async (system, user) => {\n\t\t\t\t\t\t\tconst response = await client.observe(system, user);\n\t\t\t\t\t\t\treturn response.raw;\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\t// Fall back to unjudged output rather than failing the tool —\n\t\t\t\t\t\t// the caller sees judged:false + judge_error and can decide.\n\t\t\t\t\t\tconst message = err instanceof Error ? err.message : String(err);\n\t\t\t\t\t\tresult = {\n\t\t\t\t\t\t\t...result,\n\t\t\t\t\t\t\tmetadata: { ...result.metadata, judged: false, judge_error: message },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t\tif (result.candidates.length > args.limit) {\n\t\t\t\t\t\tresult = {\n\t\t\t\t\t\t\t...result,\n\t\t\t\t\t\t\tcandidates: result.candidates.slice(0, args.limit),\n\t\t\t\t\t\t\tmetadata: { ...result.metadata, candidate_count: args.limit },\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn jsonContent(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n}\n","import {\n\ttype MemoryFilters,\n\ttype MemoryItemResponse,\n\ttype MemoryStore,\n\ttoJson,\n} from \"@codemem/core\";\nimport { resolveWriteProject } from \"./project-scope.js\";\n\nexport function getMemoryForMcp(\n\tstore: MemoryStore,\n\tmemoryId: number,\n\tfilters?: MemoryFilters,\n): MemoryItemResponse | null {\n\tconst rows = store.timeline(null, memoryId, 0, 0, filters ?? null);\n\treturn rows.find((row) => row.id === memoryId) ?? null;\n}\n\nexport function getManyForMcp(\n\tstore: MemoryStore,\n\tids: number[],\n\tfilters?: MemoryFilters,\n): MemoryItemResponse[] {\n\tif (ids.length === 0) return [];\n\tconst results: MemoryItemResponse[] = [];\n\tfor (const id of ids) {\n\t\tconst item = getMemoryForMcp(store, id, filters);\n\t\tif (item) results.push(item);\n\t}\n\treturn results;\n}\n\nexport function forgetMemoryForMcp(\n\tstore: MemoryStore,\n\tmemoryId: number,\n\tfilters?: MemoryFilters,\n): boolean {\n\tconst item = getMemoryForMcp(store, memoryId, filters);\n\tif (!item) return false;\n\tstore.forget(memoryId);\n\treturn true;\n}\n\nexport interface RememberMemoryForMcpInput {\n\tkind: string;\n\ttitle: string;\n\tbody: string;\n\tconfidence: number;\n\tproject?: string | null;\n}\n\nexport interface RememberMemoryForMcpContext {\n\tcwd?: string;\n\tuser?: string;\n\tenvProject?: string | null;\n\tnow?: () => string;\n}\n\nexport function rememberMemoryForMcp(\n\tstore: MemoryStore,\n\tinput: RememberMemoryForMcpInput,\n\tcontext: RememberMemoryForMcpContext = {},\n): { memId: number; title: string; body: string } {\n\treturn store.db.transaction(() => {\n\t\tconst now = context.now?.() ?? new Date().toISOString();\n\t\tconst user = context.user ?? process.env.USER ?? \"unknown\";\n\t\tconst cwd = context.cwd ?? process.cwd();\n\t\tconst project = resolveWriteProject({\n\t\t\tproject: input.project,\n\t\t\tenvProject: context.envProject,\n\t\t});\n\n\t\tconst sessionInfo = store.db\n\t\t\t.prepare(\n\t\t\t\t`INSERT INTO sessions(started_at, ended_at, cwd, project, user, tool_version, metadata_json)\n\t\t\t\t VALUES (?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t)\n\t\t\t.run(now, now, cwd, project, user, \"mcp-ts\", toJson({ mcp: true }));\n\t\tconst sessionId = Number(sessionInfo.lastInsertRowid);\n\n\t\tconst memId = store.remember(sessionId, input.kind, input.title, input.body, input.confidence);\n\t\tif (!getMemoryForMcp(store, memId)) {\n\t\t\tthrow new Error(\"unauthorized_scope\");\n\t\t}\n\n\t\tstore.db\n\t\t\t.prepare(\"UPDATE sessions SET ended_at = ?, metadata_json = ? WHERE id = ?\")\n\t\t\t.run(context.now?.() ?? new Date().toISOString(), toJson({ mcp: true }), sessionId);\n\n\t\treturn { memId, title: input.title, body: input.body };\n\t})();\n}\n","import { storeVectors } from \"@codemem/core\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { errorContent, jsonContent } from \"../content.js\";\nimport {\n\tforgetMemoryForMcp,\n\tgetManyForMcp,\n\tgetMemoryForMcp,\n\trememberMemoryForMcp,\n} from \"../memory-access.js\";\nimport { buildFilters } from \"../project-scope.js\";\nimport { filterSchema, memoryKindSchema } from \"../schemas.js\";\nimport type { ToolRegistrationContext } from \"../tool-context.js\";\n\nexport function registerItemTools(server: McpServer, context: ToolRegistrationContext): void {\n\tconst { envProject, store } = context;\n\n\tserver.tool(\n\t\t\"memory_get\",\n\t\t\"Fetch a single memory item by ID.\",\n\t\t{\n\t\t\tmemory_id: z.number().int().describe(\"Memory ID\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\t// Direct-ID ops do not inherit the server default project. Callers already\n\t\t\t\t// have an exact ID; cwd/env should not silently scope the lookup.\n\t\t\t\tconst item = getMemoryForMcp(store, args.memory_id, buildFilters(args, null));\n\t\t\t\tif (!item) return errorContent(\"not_found\");\n\t\t\t\treturn jsonContent(item);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_get_observations\",\n\t\t\"Fetch multiple memory items by their IDs.\",\n\t\t{\n\t\t\tids: z.array(z.number().int()).max(200).describe(\"Memory IDs to fetch\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst items = getManyForMcp(store, args.ids, buildFilters(args, null));\n\t\t\t\treturn jsonContent({ items });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_remember\",\n\t\t\"Create a new memory. Use for milestones, decisions, and notable facts.\",\n\t\t{\n\t\t\tkind: memoryKindSchema.describe(\"Memory kind\"),\n\t\t\ttitle: z.string().describe(\"Short title\"),\n\t\t\tbody: z.string().describe(\"Body text (high-signal content)\"),\n\t\t\tconfidence: z.number().min(0).max(1).default(0.5).describe(\"Confidence 0-1\"),\n\t\t\tproject: z.string().optional().describe(\"Project identifier\"),\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\t// Writes never inherit the server default project. They only honor an\n\t\t\t\t// explicit `project` input or CODEMEM_PROJECT; otherwise project stays null.\n\t\t\t\tconst result = rememberMemoryForMcp(store, args, {\n\t\t\t\t\tenvProject: envProject(),\n\t\t\t\t});\n\n\t\t\t\ttry {\n\t\t\t\t\tawait storeVectors(store.db, result.memId, result.title, result.body);\n\t\t\t\t} catch {\n\t\t\t\t\t// Memory writes should succeed even if embeddings are unavailable.\n\t\t\t\t}\n\n\t\t\t\treturn jsonContent({ id: result.memId });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_forget\",\n\t\t\"Soft-delete a memory item. Use for incorrect or sensitive data.\",\n\t\t{\n\t\t\tmemory_id: z.number().int().describe(\"Memory ID to forget\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tif (!forgetMemoryForMcp(store, args.memory_id, buildFilters(args, null))) {\n\t\t\t\t\treturn errorContent(\"not_found\");\n\t\t\t\t}\n\t\t\t\treturn jsonContent({ status: \"ok\" });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { jsonContent } from \"../content.js\";\n\nexport function registerLearnTools(server: McpServer): void {\n\tserver.tool(\n\t\t\"memory_learn\",\n\t\t\"Learn how to use codemem memory tools. Call this first if unfamiliar.\",\n\t\t{},\n\t\tasync () => {\n\t\t\treturn jsonContent({\n\t\t\t\tintro: \"Use this tool when you're new to codemem or unsure when to recall/persist.\",\n\t\t\t\tclient_hint: \"If you are unfamiliar with codemem, call memory.learn first.\",\n\t\t\t\trecall: {\n\t\t\t\t\twhen: [\n\t\t\t\t\t\t\"Start of a task or when the user references prior work.\",\n\t\t\t\t\t\t\"When you need background context, decisions, or recent changes.\",\n\t\t\t\t\t],\n\t\t\t\t\thow: [\n\t\t\t\t\t\t\"Use memory.search_index to get compact candidates.\",\n\t\t\t\t\t\t\"Use memory.timeline to expand around a promising memory.\",\n\t\t\t\t\t\t\"Use memory.get_observations for full details only when needed.\",\n\t\t\t\t\t\t\"Use memory.pack for quick one-shot context blocks.\",\n\t\t\t\t\t\t\"Use the project filter unless the user requests cross-project context.\",\n\t\t\t\t\t],\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t'memory.search_index(\"billing cache bug\", limit=5)',\n\t\t\t\t\t\t\"memory.timeline(memory_id=123)\",\n\t\t\t\t\t\t\"memory.get_observations([123, 456])\",\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tpersistence: {\n\t\t\t\t\twhen: [\n\t\t\t\t\t\t\"Milestones (task done, key decision, new facts learned).\",\n\t\t\t\t\t\t\"Notable regressions or follow-ups that should be remembered.\",\n\t\t\t\t\t],\n\t\t\t\t\thow: [\n\t\t\t\t\t\t\"Use memory.remember with kind decision/discovery/change/exploration.\",\n\t\t\t\t\t\t\"Keep titles short and bodies high-signal.\",\n\t\t\t\t\t\t\"ALWAYS pass the project parameter if known.\",\n\t\t\t\t\t],\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t'memory.remember(kind=\"decision\", title=\"Switch to async cache\", body=\"...why...\", project=\"my-service\")',\n\t\t\t\t\t\t'memory.remember(kind=\"change\", title=\"Fixed retry loop\", body=\"...impact...\", project=\"my-service\")',\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tforget: {\n\t\t\t\t\twhen: [\n\t\t\t\t\t\t\"Accidental or sensitive data stored in memory items.\",\n\t\t\t\t\t\t\"Obsolete or incorrect items that should no longer surface.\",\n\t\t\t\t\t],\n\t\t\t\t\thow: [\n\t\t\t\t\t\t\"Call memory.forget(id) to mark the item inactive.\",\n\t\t\t\t\t\t\"Prefer forgetting over overwriting to preserve auditability.\",\n\t\t\t\t\t],\n\t\t\t\t\texamples: [\"memory.forget(123)\"],\n\t\t\t\t},\n\t\t\t\tprompt_hint:\n\t\t\t\t\t\"At task start: call memory.search_index; during work: memory.timeline + memory.get_observations; at milestones: memory.remember.\",\n\t\t\t\trecommended_system_prompt: [\n\t\t\t\t\t\"Trigger policy (1-liner): If the user references prior work or starts a task,\",\n\t\t\t\t\t\"immediately call memory.search_index; then use memory.timeline + memory.get_observations;\",\n\t\t\t\t\t\"at milestones, call memory.remember; use memory.forget for incorrect/sensitive items.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"System prompt:\",\n\t\t\t\t\t\"You have access to codemem MCP tools. If unfamiliar, call memory.learn first.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Recall:\",\n\t\t\t\t\t\"- Start of any task: call memory.search_index with a concise task query.\",\n\t\t\t\t\t'- If prior work is referenced (\"as before\", \"last time\", \"we already did…\", \"regression\"),',\n\t\t\t\t\t\" call memory.search_index or memory.timeline.\",\n\t\t\t\t\t\"- Use memory.get_observations only after filtering IDs.\",\n\t\t\t\t\t\"- Prefer project-scoped queries unless the user asks for cross-project.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Persistence:\",\n\t\t\t\t\t\"- On milestones (task done, key decision, new facts learned), call memory.remember.\",\n\t\t\t\t\t\"- Use kind=decision for tradeoffs, kind=change for outcomes, kind=discovery/exploration for useful findings.\",\n\t\t\t\t\t\"- Keep titles short and bodies high-signal.\",\n\t\t\t\t\t\"- ALWAYS pass the project parameter if known.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Safety:\",\n\t\t\t\t\t\"- Use memory.forget(id) for incorrect or sensitive items.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Examples:\",\n\t\t\t\t\t'- memory.search_index(\"billing cache bug\")',\n\t\t\t\t\t\"- memory.timeline(memory_id=123)\",\n\t\t\t\t\t\"- memory.get_observations([123, 456])\",\n\t\t\t\t\t'- memory.remember(kind=\"decision\", title=\"Use async cache\", body=\"Chose async cache to avoid lock contention in X.\", project=\"my-service\")',\n\t\t\t\t\t'- memory.remember(kind=\"change\", title=\"Fixed retry loop\", body=\"Root cause was Y; added guard in Z.\", project=\"my-service\")',\n\t\t\t\t\t\"- memory.forget(123)\",\n\t\t\t\t].join(\"\\n\"),\n\t\t\t});\n\t\t},\n\t);\n}\n","export const MEMORY_KINDS: Record<string, string> = {\n\tdiscovery: \"Something learned about the codebase, architecture, or tools\",\n\tchange: \"A code change that was made\",\n\tfeature: \"A new feature that was implemented\",\n\tbugfix: \"A bug that was found and fixed\",\n\trefactor: \"Code that was refactored or restructured\",\n\tdecision: \"A design or architecture decision\",\n\texploration: \"An experiment or investigation (may not have shipped)\",\n};\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { jsonContent } from \"../content.js\";\nimport { MEMORY_KINDS } from \"../memory-kinds.js\";\nimport { filterNames } from \"../schemas.js\";\n\nexport function registerSchemaTools(server: McpServer): void {\n\tserver.tool(\n\t\t\"memory_schema\",\n\t\t\"Return the memory schema — kinds, fields, and available filters.\",\n\t\t{},\n\t\tasync () => {\n\t\t\treturn jsonContent({\n\t\t\t\tkinds: Object.keys(MEMORY_KINDS),\n\t\t\t\tkind_descriptions: MEMORY_KINDS,\n\t\t\t\tfields: {\n\t\t\t\t\ttitle: \"short text\",\n\t\t\t\t\tbody: \"long text\",\n\t\t\t\t\tsubtitle: \"short text\",\n\t\t\t\t\tfacts: \"list<string>\",\n\t\t\t\t\tnarrative: \"long text\",\n\t\t\t\t\tconcepts: \"list<string>\",\n\t\t\t\t\tfiles_read: \"list<string>\",\n\t\t\t\t\tfiles_modified: \"list<string>\",\n\t\t\t\t\tprompt_number: \"int\",\n\t\t\t\t},\n\t\t\t\tfilters: filterNames,\n\t\t\t});\n\t\t},\n\t);\n}\n","import type { MemoryResult } from \"@codemem/core\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { errorContent, jsonContent } from \"../content.js\";\nimport { buildFilters } from \"../project-scope.js\";\nimport { filterSchema } from \"../schemas.js\";\nimport type { ToolRegistrationContext } from \"../tool-context.js\";\n\nexport function registerSearchTools(server: McpServer, context: ToolRegistrationContext): void {\n\tconst { defaultProject, store } = context;\n\n\tserver.tool(\n\t\t\"memory_search\",\n\t\t\"Search memories by text query. Returns full body text for each match.\",\n\t\t{\n\t\t\tquery: z.string().describe(\"Search query\"),\n\t\t\tlimit: z.number().int().min(1).max(50).default(5).describe(\"Max results\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst items = store.search(args.query, args.limit, filters);\n\t\t\t\treturn jsonContent({\n\t\t\t\t\titems: items.map((m: MemoryResult) => ({\n\t\t\t\t\t\tid: m.id,\n\t\t\t\t\t\ttitle: m.title,\n\t\t\t\t\t\tkind: m.kind,\n\t\t\t\t\t\tbody: m.body_text,\n\t\t\t\t\t\tconfidence: m.confidence,\n\t\t\t\t\t\tscore: m.score,\n\t\t\t\t\t\tsession_id: m.session_id,\n\t\t\t\t\t\tmetadata: m.metadata,\n\t\t\t\t\t})),\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_search_index\",\n\t\t\"Search memories by text query. Returns compact index entries (no body) for browsing.\",\n\t\t{\n\t\t\tquery: z.string().describe(\"Search query\"),\n\t\t\tlimit: z.number().int().min(1).max(50).default(8).describe(\"Max results\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst items = store.search(args.query, args.limit, filters);\n\t\t\t\treturn jsonContent({\n\t\t\t\t\titems: items.map((m: MemoryResult) => ({\n\t\t\t\t\t\tid: m.id,\n\t\t\t\t\t\tkind: m.kind,\n\t\t\t\t\t\ttitle: m.title,\n\t\t\t\t\t\tscore: m.score,\n\t\t\t\t\t\tcreated_at: m.created_at,\n\t\t\t\t\t\tsession_id: m.session_id,\n\t\t\t\t\t\tmetadata: m.metadata,\n\t\t\t\t\t})),\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_explain\",\n\t\t\"Explain search results with detailed scoring breakdown.\",\n\t\t{\n\t\t\tquery: z.string().optional().describe(\"Search query\"),\n\t\t\tids: z.array(z.number().int()).max(200).optional().describe(\"Specific memory IDs to explain\"),\n\t\t\tlimit: z.number().int().min(1).max(50).default(10).describe(\"Max results\"),\n\t\t\tinclude_pack_context: z.boolean().default(false).describe(\"Include formatted pack context\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst result = store.explain(args.query ?? null, args.ids ?? null, args.limit, filters, {\n\t\t\t\t\tincludePackContext: args.include_pack_context,\n\t\t\t\t});\n\t\t\t\treturn jsonContent(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_recent\",\n\t\t\"Return recent memories, newest first.\",\n\t\t{\n\t\t\tlimit: z.number().int().min(1).max(100).default(8).describe(\"Max results\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst items = store.recent(args.limit, filters);\n\t\t\t\treturn jsonContent({ items });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_pack\",\n\t\t\"Build a formatted memory pack from search results — quick one-shot context block.\",\n\t\t{\n\t\t\tcontext: z.string().describe(\"Context description to search for\"),\n\t\t\tlimit: z.number().int().min(1).max(50).optional().describe(\"Max items to include\"),\n\t\t\tcompact: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t\"When true, render a scannable index of all items with full detail only for the top N (default 3). Saves tokens when broad overview matters more than per-item detail.\",\n\t\t\t\t),\n\t\t\tcompact_detail_count: z\n\t\t\t\t.number()\n\t\t\t\t.int()\n\t\t\t\t.min(0)\n\t\t\t\t.max(50)\n\t\t\t\t.optional()\n\t\t\t\t.describe(\"Number of items to show in full detail in compact mode (default 3)\"),\n\t\t\tcompression_mode: z\n\t\t\t\t.enum([\"off\", \"compact\", \"ids\"])\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t\"Near-related compression mode: off disables it, compact applies only to compact rendering, ids applies in all modes. Defaults to CODEMEM_PACK_COMPRESSION or compact.\",\n\t\t\t\t),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst renderOptions =\n\t\t\t\t\targs.compact || args.compact_detail_count != null || args.compression_mode != null\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tcompact: args.compact ?? (args.compact_detail_count != null ? true : undefined),\n\t\t\t\t\t\t\t\tcompactDetailCount: args.compact_detail_count,\n\t\t\t\t\t\t\t\tcompressionMode: args.compression_mode,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst result = await store.buildMemoryPackAsync(\n\t\t\t\t\targs.context,\n\t\t\t\t\targs.limit ?? undefined,\n\t\t\t\t\tnull,\n\t\t\t\t\tfilters,\n\t\t\t\t\trenderOptions,\n\t\t\t\t);\n\t\t\t\treturn jsonContent(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n}\n","import { dedupeOrderedIds, type MemoryItemResponse, projectMatchesFilter } from \"@codemem/core\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { errorContent, jsonContent } from \"../content.js\";\nimport { getManyForMcp } from \"../memory-access.js\";\nimport { buildFilters } from \"../project-scope.js\";\nimport { filterSchema } from \"../schemas.js\";\nimport type { ToolRegistrationContext } from \"../tool-context.js\";\n\nexport function registerTimelineTools(server: McpServer, context: ToolRegistrationContext): void {\n\tconst { defaultProject, store } = context;\n\n\tserver.tool(\n\t\t\"memory_timeline\",\n\t\t\"Get a chronological window of memories around an anchor (by ID or query).\",\n\t\t{\n\t\t\tquery: z.string().optional().describe(\"Search query to find anchor\"),\n\t\t\tmemory_id: z.number().int().optional().describe(\"Anchor memory ID\"),\n\t\t\tdepth_before: z.number().int().min(0).default(3).describe(\"Items before anchor\"),\n\t\t\tdepth_after: z.number().int().min(0).default(3).describe(\"Items after anchor\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst items = store.timeline(\n\t\t\t\t\targs.query ?? null,\n\t\t\t\t\targs.memory_id ?? null,\n\t\t\t\t\targs.depth_before,\n\t\t\t\t\targs.depth_after,\n\t\t\t\t\tfilters,\n\t\t\t\t);\n\t\t\t\treturn jsonContent({ items });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_expand\",\n\t\t\"Fetch memories by ID with surrounding timeline context.\",\n\t\t{\n\t\t\tids: z\n\t\t\t\t.array(z.union([z.number(), z.string()]))\n\t\t\t\t.max(200)\n\t\t\t\t.describe(\"Memory IDs to expand\"),\n\t\t\tdepth_before: z.number().int().min(0).default(3).describe(\"Timeline items before\"),\n\t\t\tdepth_after: z.number().int().min(0).default(3).describe(\"Timeline items after\"),\n\t\t\tinclude_observations: z.boolean().default(false).describe(\"Include full observation details\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\t// Explicit blank `project` clears scoping for cross-project expansion.\n\t\t\t\t// Only fall back to the server default when `project` is omitted entirely.\n\t\t\t\tconst filterDefaultProject =\n\t\t\t\t\targs.project !== undefined && !args.project.trim() ? null : defaultProject();\n\t\t\t\tconst filters = buildFilters(args, filterDefaultProject);\n\t\t\t\tconst resolvedProject = filters?.project ?? null;\n\t\t\t\tconst { ordered: orderedIds, invalid: invalidIds } = dedupeOrderedIds(args.ids);\n\t\t\t\tconst errors: Array<Record<string, unknown>> = [];\n\n\t\t\t\tif (invalidIds.length > 0) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tcode: \"INVALID_ARGUMENT\",\n\t\t\t\t\t\tfield: \"ids\",\n\t\t\t\t\t\tmessage: \"some ids are not valid integers\",\n\t\t\t\t\t\tids: invalidIds,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst missingNotFound: number[] = [];\n\t\t\t\tconst missingProjectMismatch: number[] = [];\n\t\t\t\tconst missingFilterMismatch: number[] = [];\n\t\t\t\tconst anchors: MemoryItemResponse[] = [];\n\t\t\t\tconst timelineItems: MemoryItemResponse[] = [];\n\t\t\t\tconst timelineSeen = new Set<number>();\n\t\t\t\tconst sessionProjects = new Map<number, string | null>();\n\n\t\t\t\tfor (const memoryId of orderedIds) {\n\t\t\t\t\tconst item = store.get(memoryId);\n\t\t\t\t\tif (!item?.active) {\n\t\t\t\t\t\tmissingNotFound.push(memoryId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst sessionId = item.session_id;\n\t\t\t\t\tif (resolvedProject && sessionId > 0) {\n\t\t\t\t\t\tif (!sessionProjects.has(sessionId)) {\n\t\t\t\t\t\t\tconst row = store.db\n\t\t\t\t\t\t\t\t.prepare(\"SELECT project FROM sessions WHERE id = ? LIMIT 1\")\n\t\t\t\t\t\t\t\t.get(sessionId) as { project: string | null } | undefined;\n\t\t\t\t\t\t\tsessionProjects.set(sessionId, typeof row?.project === \"string\" ? row.project : null);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!projectMatchesFilter(resolvedProject, sessionProjects.get(sessionId) ?? null)) {\n\t\t\t\t\t\t\tmissingProjectMismatch.push(memoryId);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (resolvedProject && sessionId <= 0) {\n\t\t\t\t\t\tmissingProjectMismatch.push(memoryId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst expanded = store.timeline(\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\tmemoryId,\n\t\t\t\t\t\targs.depth_before,\n\t\t\t\t\t\targs.depth_after,\n\t\t\t\t\t\tfilters,\n\t\t\t\t\t);\n\t\t\t\t\tconst anchor = expanded.find((expandedItem) => expandedItem.id === memoryId);\n\t\t\t\t\tif (!anchor) {\n\t\t\t\t\t\tmissingFilterMismatch.push(memoryId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tanchors.push(anchor);\n\t\t\t\t\tfor (const expandedItem of expanded) {\n\t\t\t\t\t\tconst expandedId = expandedItem.id;\n\t\t\t\t\t\tif (expandedId <= 0 || timelineSeen.has(expandedId)) continue;\n\t\t\t\t\t\ttimelineSeen.add(expandedId);\n\t\t\t\t\t\ttimelineItems.push(expandedItem);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (missingNotFound.length > 0) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\t\tfield: \"ids\",\n\t\t\t\t\t\tmessage: \"some requested ids were not found\",\n\t\t\t\t\t\tids: missingNotFound,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (missingProjectMismatch.length > 0) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tcode: \"PROJECT_MISMATCH\",\n\t\t\t\t\t\tfield: \"project\",\n\t\t\t\t\t\tmessage: \"some requested ids are outside the requested project scope\",\n\t\t\t\t\t\tids: missingProjectMismatch,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (missingFilterMismatch.length > 0) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tcode: \"FILTER_MISMATCH\",\n\t\t\t\t\t\tfield: \"filters\",\n\t\t\t\t\t\tmessage: \"some requested ids are outside the requested filters\",\n\t\t\t\t\t\tids: missingFilterMismatch,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tlet observations: MemoryItemResponse[] = [];\n\t\t\t\tif (args.include_observations) {\n\t\t\t\t\tconst observationSeen = new Set<number>();\n\t\t\t\t\tconst observationIds: number[] = [];\n\t\t\t\t\tfor (const item of [...anchors, ...timelineItems]) {\n\t\t\t\t\t\tif (item.id > 0 && !observationSeen.has(item.id)) {\n\t\t\t\t\t\t\tobservationSeen.add(item.id);\n\t\t\t\t\t\t\tobservationIds.push(item.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tobservations = getManyForMcp(store, observationIds, filters);\n\t\t\t\t}\n\n\t\t\t\treturn jsonContent({\n\t\t\t\t\tanchors,\n\t\t\t\t\ttimeline: timelineItems,\n\t\t\t\t\tobservations,\n\t\t\t\t\tmissing_ids: orderedIds.filter(\n\t\t\t\t\t\t(memoryId: number) =>\n\t\t\t\t\t\t\tmissingNotFound.includes(memoryId) ||\n\t\t\t\t\t\t\tmissingProjectMismatch.includes(memoryId) ||\n\t\t\t\t\t\t\tmissingFilterMismatch.includes(memoryId),\n\t\t\t\t\t),\n\t\t\t\t\terrors,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tproject: resolvedProject,\n\t\t\t\t\t\trequested_ids_count: orderedIds.length,\n\t\t\t\t\t\treturned_anchor_count: anchors.length,\n\t\t\t\t\t\ttimeline_count: timelineItems.length,\n\t\t\t\t\t\tinclude_observations: args.include_observations,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n}\n","import { type MemoryStore, VERSION } from \"@codemem/core\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { resolveDefaultProject } from \"./project-scope.js\";\nimport type { CodememMcpServerOptions, ToolRegistrationContext } from \"./tool-context.js\";\nimport { registerDistillTools } from \"./tools/distill.js\";\nimport { registerItemTools } from \"./tools/items.js\";\nimport { registerLearnTools } from \"./tools/learn.js\";\nimport { registerSchemaTools } from \"./tools/schema.js\";\nimport { registerSearchTools } from \"./tools/search.js\";\nimport { registerTimelineTools } from \"./tools/timeline.js\";\n\nexport function createCodememMcpServer(\n\tstore: MemoryStore,\n\toptions: CodememMcpServerOptions = {},\n): McpServer {\n\tconst server = new McpServer({ name: \"codemem\", version: VERSION });\n\tconst context: ToolRegistrationContext = {\n\t\tstore,\n\t\t// Resolve lazily per call so long-running servers pick up the current\n\t\t// CODEMEM_PROJECT / process.cwd() rather than the value at construction.\n\t\tdefaultProject: () => {\n\t\t\tif (options.resolveDefaultProject) return options.resolveDefaultProject();\n\t\t\tif (options.defaultProject !== undefined) return options.defaultProject;\n\t\t\treturn resolveDefaultProject();\n\t\t},\n\t\tenvProject: () =>\n\t\t\toptions.envProject !== undefined ? options.envProject : (process.env.CODEMEM_PROJECT ?? null),\n\t};\n\n\tregisterSearchTools(server, context);\n\tregisterTimelineTools(server, context);\n\tregisterDistillTools(server, context);\n\tregisterItemTools(server, context);\n\tregisterSchemaTools(server);\n\tregisterLearnTools(server);\n\n\treturn server;\n}\n"],"mappings":";;;;;;;AAEA,SAAS,EAAa,GAAiD;CAEtE,OADgB,GAAO,KAAK,KACD;AAC5B;AAEA,SAAgB,IAAuC;CACtD,OAAO,EAAa,QAAQ,IAAI,eAAe,KAAK,EAAe,QAAQ,IAAI,CAAC;AACjF;AAEA,SAAgB,EAAoB,GAGlB;CACjB,OAAO,EAAa,EAAM,OAAO,KAAK,EAAa,EAAM,UAAU,KAAK;AACzE;AAEA,SAAgB,EACf,GACA,IAAiB,EAAsB,GACX;CAC5B,IAAM,IAAyB,CAAC,GAC5B,IAAS,IAGP,KADkB,OAAO,EAAI,WAAY,WAAW,EAAa,EAAI,OAAO,IAAI,KAAA,MAC3C,EAAa,CAAc,KAAK,KAAA;CAC3E,AAAI,MACH,EAAQ,UAAU,GAClB,IAAS;CAGV,KAAK,IAAM,KAAO;EACjB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD,GAAY;EACX,IAAM,IAAM,EAAI;EAChB,AAAI,KAA6B,SAChC,EAAqC,KAAO,GAC5C,IAAS;CAEX;CAEA,OAAO,IAAS,IAAU,KAAA;AAC3B;;;AC/DA,SAAgB,EAAY,GAAe;CAC1C,OAAO,EAAE,SAAS,CAAC;EAAE,MAAM;EAAiB,MAAM,KAAK,UAAU,CAAI;CAAE,CAAC,EAAE;AAC3E;AAEA,SAAgB,EAAa,GAAiB;CAC7C,OAAO,EAAE,SAAS,CAAC;EAAE,MAAM;EAAiB,MAAM,KAAK,UAAU,EAAE,OAAO,EAAQ,CAAC;CAAE,CAAC,EAAE;AACzF;;;ACJA,IAAM,IAAoB;CACzB,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;CACrF,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,qCAAqC;CAChG,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,qCAAqC;AACjG,GAEa,IAAe;CAC3B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;CAC5D,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;CAC5F,GAAG;CACH,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACzC,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACjD,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACjD,uBAAuB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACpD,uBAAuB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACpD,yBAAyB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACtD,yBAAyB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACtD,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CAChD,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CAChD,sBAAsB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACnD,sBAAsB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACnD,iBAAiB,EAAE,OAAO,EAAE,SAAS;CACrC,gBAAgB,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;CAC5D,YAAY,EAAE,OAAO,EAAE,SAAS;CAChC,wBAAwB,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;CACpE,mCAAmC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;CAC7D,iCAAiC,EAAE,OAAO,EAAE,SAAS;AACtD,GAEa,IAAmB,EAAE,KAAK;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;AACD,CAAC,GAEY,IAAc,OAAO,KAAK,CAAY,EAAE,SAAS;;;ACrB9D,SAAS,EACR,GACA,GACA,GACgC;CAChC,IAAI,CAAC,EAAW,CAAI,GAAG,OAAO;CAC9B,IAAM,IAAO,EAAa,GAAM,MAAM;CACtC,OAAO,EAAK,KAAK,IAAI;EAAE,MAAM;EAAa;EAAM;CAAM,IAAI;AAC3D;AAEA,SAAS,EACR,GACA,IAAM,QAAQ,IAAI,GACS;CAK3B,IAAM,IAAc,EAAmB,CAAG,KAAK;CAW/C,OAAO,CATN,IACG,EAAgB,EAAK,GAAa,WAAW,GAAG,aAAa,SAAS,IACtE,MACH,EACC,EAAK,EAAQ,GAAG,WAAW,YAAY,WAAW,GAClD,gCACA,MACD,CAEM,EAAU,QAAQ,MAAiD,KAAY,IAAI;AAC3F;AAEA,SAAS,EACR,GACA,GACU;CACV,IAAI,EAAK,cAAc,OAAO;CAC9B,IAAM,IAAiB,EAAe,QAAQ,IAAI,CAAC;CACnD,IAAI,CAAC,GAAgB,OAAO;CAC5B,IAAM,IAAkB,OAAO,EAAK,WAAY,WAAW,EAAK,QAAQ,KAAK,IAAI,IAG3E,IAAgB,IACnB,EAAe,QAAQ,IAAI,GAAG,CAAe,IAC7C;CAEH,OADK,IACE,EAAqB,GAAe,CAAc,IAD9B;AAE5B;AAEA,SAAS,EACR,GACA,GAC4B;CAC5B,IAAI,EAAK,gBAAgB,OAAO,EAAK,WAAY,YAAY,EAAK,QAAQ,KAAK,GAC9E,MAAU,MAAM,8CAA8C;CAE/D,OAAO,EAAa,GAAM,EAAK,eAAe,OAAO,CAAc;AACpE;AAEA,SAAgB,EAAqB,GAAmB,GAAwC;CAC/F,IAAM,EAAE,mBAAgB,aAAU;CAElC,EAAO,KACN,6BACA,yGACA;EACC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,gBAAgB;EAC5E,gBAAgB,EACd,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,EAAE,EACN,QAAQ,CAAC,EACT,SAAS,oCAAoC;EAC/C,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAK,EAAE,SAAS,mCAAmC;EACrF,oBAAoB,EAClB,QAAQ,EACR,QAAQ,EAAK,EACb,SAAS,yDAAyD;EACpE,oBAAoB,EAClB,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,EAAE,EACN,QAAQ,CAAC,EACT,SAAS,iCAAiC;EAC5C,OAAO,EACL,QAAQ,EACR,QAAQ,EAAI,EACZ,SACA,iKACD;EACD,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAyB,EAAe,GACxC,IAAU,EAAoB,GAAM,CAAsB,GAC1D,IAAQ,EAAK,OAAO,CAAC,EAAK,IAAI,IAAI,KAAA,GAGlC,IAAa,EAAK,QAAQ,KAAK,IAAI,EAAK,QAAQ,GAAG,EAAK,QAAQ,EAAE,IAAI,EAAK,OAC7E,IAAS,MAAM,EAAmB,GAAO;IAC5C,WAAW;KACV,mBAAmB,EAAK;KACxB,kBAAkB,EAAK;IACxB;IACA,kBAAkB,EACjB,EAA4B,GAAM,CAAsB,CACzD;IACA,QAAQ;KAAE,SAAS,KAAW;KAAM;IAAM;IAC1C,OAAO;IACP,eAAe,EAAK;GACrB,CAAC;GACD,IAAI,EAAK,OAAO;IACf,IAAI;KACH,IAAM,IAAS,IAAI,EAAe;KAClC,IAAS,MAAM,EAAmB,GAAQ,OAAO,GAAQ,OAEjD,MADgB,EAAO,QAAQ,GAAQ,CAAI,GAClC,GAChB;IACF,SAAS,GAAK;KAGb,IAAM,IAAU,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG;KAC/D,IAAS;MACR,GAAG;MACH,UAAU;OAAE,GAAG,EAAO;OAAU,QAAQ;OAAO,aAAa;MAAQ;KACrE;IACD;IACA,AAAI,EAAO,WAAW,SAAS,EAAK,UACnC,IAAS;KACR,GAAG;KACH,YAAY,EAAO,WAAW,MAAM,GAAG,EAAK,KAAK;KACjD,UAAU;MAAE,GAAG,EAAO;MAAU,iBAAiB,EAAK;KAAM;IAC7D;GAEF;GACA,OAAO,EAAY,CAAM;EAC1B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD;AACD;;;AC5JA,SAAgB,EACf,GACA,GACA,GAC4B;CAE5B,OADa,EAAM,SAAS,MAAM,GAAU,GAAG,GAAG,KAAW,IACtD,EAAK,MAAM,MAAQ,EAAI,OAAO,CAAQ,KAAK;AACnD;AAEA,SAAgB,EACf,GACA,GACA,GACuB;CACvB,IAAI,EAAI,WAAW,GAAG,OAAO,CAAC;CAC9B,IAAM,IAAgC,CAAC;CACvC,KAAK,IAAM,KAAM,GAAK;EACrB,IAAM,IAAO,EAAgB,GAAO,GAAI,CAAO;EAC/C,AAAI,KAAM,EAAQ,KAAK,CAAI;CAC5B;CACA,OAAO;AACR;AAEA,SAAgB,EACf,GACA,GACA,GACU;CAIV,OAHa,EAAgB,GAAO,GAAU,CACzC,KACL,EAAM,OAAO,CAAQ,GACd,MAFW;AAGnB;AAiBA,SAAgB,EACf,GACA,GACA,IAAuC,CAAC,GACS;CACjD,OAAO,EAAM,GAAG,kBAAkB;EACjC,IAAM,IAAM,EAAQ,MAAM,sBAAK,IAAI,KAAK,GAAE,YAAY,GAChD,IAAO,EAAQ,QAAQ,QAAQ,IAAI,QAAQ,WAC3C,IAAM,EAAQ,OAAO,QAAQ,IAAI,GACjC,IAAU,EAAoB;GACnC,SAAS,EAAM;GACf,YAAY,EAAQ;EACrB,CAAC,GAEK,IAAc,EAAM,GACxB,QACA,gIAED,EACC,IAAI,GAAK,GAAK,GAAK,GAAS,GAAM,UAAU,EAAO,EAAE,KAAK,GAAK,CAAC,CAAC,GAC7D,IAAY,OAAO,EAAY,eAAe,GAE9C,IAAQ,EAAM,SAAS,GAAW,EAAM,MAAM,EAAM,OAAO,EAAM,MAAM,EAAM,UAAU;EAC7F,IAAI,CAAC,EAAgB,GAAO,CAAK,GAChC,MAAU,MAAM,oBAAoB;EAOrC,OAJA,EAAM,GACJ,QAAQ,kEAAkE,EAC1E,IAAI,EAAQ,MAAM,sBAAK,IAAI,KAAK,GAAE,YAAY,GAAG,EAAO,EAAE,KAAK,GAAK,CAAC,GAAG,CAAS,GAE5E;GAAE;GAAO,OAAO,EAAM;GAAO,MAAM,EAAM;EAAK;CACtD,CAAC,EAAE;AACJ;;;AC5EA,SAAgB,EAAkB,GAAmB,GAAwC;CAC5F,IAAM,EAAE,eAAY,aAAU;CAsE9B,AApEA,EAAO,KACN,cACA,qCACA;EACC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,WAAW;EAChD,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GAGH,IAAM,IAAO,EAAgB,GAAO,EAAK,WAAW,EAAa,GAAM,IAAI,CAAC;GAE5E,OADK,IACE,EAAY,CAAI,IADL,EAAa,WAAW;EAE3C,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,2BACA,6CACA;EACC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,qBAAqB;EACtE,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GAEH,OAAO,EAAY,EAAE,OADP,EAAc,GAAO,EAAK,KAAK,EAAa,GAAM,IAAI,CAC/C,EAAM,CAAC;EAC7B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,mBACA,0EACA;EACC,MAAM,EAAiB,SAAS,aAAa;EAC7C,OAAO,EAAE,OAAO,EAAE,SAAS,aAAa;EACxC,MAAM,EAAE,OAAO,EAAE,SAAS,iCAAiC;EAC3D,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAG,EAAE,SAAS,gBAAgB;EAC3E,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;CAC7D,GACA,OAAO,MAAS;EACf,IAAI;GAGH,IAAM,IAAS,EAAqB,GAAO,GAAM,EAChD,YAAY,EAAW,EACxB,CAAC;GAED,IAAI;IACH,MAAM,EAAa,EAAM,IAAI,EAAO,OAAO,EAAO,OAAO,EAAO,IAAI;GACrE,QAAQ,CAER;GAEA,OAAO,EAAY,EAAE,IAAI,EAAO,MAAM,CAAC;EACxC,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,iBACA,mEACA;EACC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,qBAAqB;EAC1D,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GAIH,OAHK,EAAmB,GAAO,EAAK,WAAW,EAAa,GAAM,IAAI,CAAC,IAGhE,EAAY,EAAE,QAAQ,KAAK,CAAC,IAF3B,EAAa,WAAW;EAGjC,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD;AACD;;;ACpGA,SAAgB,EAAmB,GAAyB;CAC3D,EAAO,KACN,gBACA,yEACA,CAAC,GACD,YACQ,EAAY;EAClB,OAAO;EACP,aAAa;EACb,QAAQ;GACP,MAAM,CACL,2DACA,iEACD;GACA,KAAK;IACJ;IACA;IACA;IACA;IACA;GACD;GACA,UAAU;IACT;IACA;IACA;GACD;EACD;EACA,aAAa;GACZ,MAAM,CACL,4DACA,8DACD;GACA,KAAK;IACJ;IACA;IACA;GACD;GACA,UAAU,CACT,mHACA,6GACD;EACD;EACA,QAAQ;GACP,MAAM,CACL,wDACA,4DACD;GACA,KAAK,CACJ,qDACA,8DACD;GACA,UAAU,CAAC,oBAAoB;EAChC;EACA,aACC;EACD,2BAA2B;GAC1B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD,EAAE,KAAK,IAAI;CACZ,CAAC,CAEH;AACD;;;AC7FA,IAAa,IAAuC;CACnD,WAAW;CACX,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,UAAU;CACV,UAAU;CACV,aAAa;AACd;;;ACHA,SAAgB,EAAoB,GAAyB;CAC5D,EAAO,KACN,iBACA,oEACA,CAAC,GACD,YACQ,EAAY;EAClB,OAAO,OAAO,KAAK,CAAY;EAC/B,mBAAmB;EACnB,QAAQ;GACP,OAAO;GACP,MAAM;GACN,UAAU;GACV,OAAO;GACP,WAAW;GACX,UAAU;GACV,YAAY;GACZ,gBAAgB;GAChB,eAAe;EAChB;EACA,SAAS;CACV,CAAC,CAEH;AACD;;;ACrBA,SAAgB,EAAoB,GAAmB,GAAwC;CAC9F,IAAM,EAAE,mBAAgB,aAAU;CAsGlC,AApGA,EAAO,KACN,iBACA,yEACA;EACC,OAAO,EAAE,OAAO,EAAE,SAAS,cAAc;EACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,EAAE,SAAS,aAAa;EACxE,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC;GAEnD,OAAO,EAAY,EAClB,OAFa,EAAM,OAAO,EAAK,OAAO,EAAK,OAAO,CAE3C,EAAM,KAAK,OAAqB;IACtC,IAAI,EAAE;IACN,OAAO,EAAE;IACT,MAAM,EAAE;IACR,MAAM,EAAE;IACR,YAAY,EAAE;IACd,OAAO,EAAE;IACT,YAAY,EAAE;IACd,UAAU,EAAE;GACb,EAAE,EACH,CAAC;EACF,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,uBACA,wFACA;EACC,OAAO,EAAE,OAAO,EAAE,SAAS,cAAc;EACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,EAAE,SAAS,aAAa;EACxE,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC;GAEnD,OAAO,EAAY,EAClB,OAFa,EAAM,OAAO,EAAK,OAAO,EAAK,OAAO,CAE3C,EAAM,KAAK,OAAqB;IACtC,IAAI,EAAE;IACN,MAAM,EAAE;IACR,OAAO,EAAE;IACT,OAAO,EAAE;IACT,YAAY,EAAE;IACd,YAAY,EAAE;IACd,UAAU,EAAE;GACb,EAAE,EACH,CAAC;EACF,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,kBACA,2DACA;EACC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,cAAc;EACpD,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gCAAgC;EAC5F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,aAAa;EACzE,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,EAAK,EAAE,SAAS,gCAAgC;EAC1F,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC;GAInD,OAAO,EAHQ,EAAM,QAAQ,EAAK,SAAS,MAAM,EAAK,OAAO,MAAM,EAAK,OAAO,GAAS,EACvF,oBAAoB,EAAK,qBAC1B,CACmB,CAAM;EAC1B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,iBACA,yCACA;EACC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS,aAAa;EACzE,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC;GAEnD,OAAO,EAAY,EAAE,OADP,EAAM,OAAO,EAAK,OAAO,CAClB,EAAM,CAAC;EAC7B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,eACA,qFACA;EACC,SAAS,EAAE,OAAO,EAAE,SAAS,mCAAmC;EAChE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,sBAAsB;EACjF,SAAS,EACP,QAAQ,EACR,SAAS,EACT,SACA,uKACD;EACD,sBAAsB,EACpB,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,EAAE,EACN,SAAS,EACT,SAAS,oEAAoE;EAC/E,kBAAkB,EAChB,KAAK;GAAC;GAAO;GAAW;EAAK,CAAC,EAC9B,SAAS,EACT,SACA,uKACD;EACD,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC,GAC7C,IACL,EAAK,WAAW,EAAK,wBAAwB,QAAQ,EAAK,oBAAoB,OAC3E;IACA,SAAS,EAAK,YAAY,EAAK,wBAAwB,OAAc,KAAA,IAAP;IAC9D,oBAAoB,EAAK;IACzB,iBAAiB,EAAK;GACvB,IACC,KAAA;GAQJ,OAAO,EAAY,MAPE,EAAM,qBAC1B,EAAK,SACL,EAAK,SAAS,KAAA,GACd,MACA,GACA,CACD,CACyB;EAC1B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD;AACD;;;ACzJA,SAAgB,EAAsB,GAAmB,GAAwC;CAChG,IAAM,EAAE,mBAAgB,aAAU;CA6BlC,AA3BA,EAAO,KACN,mBACA,6EACA;EACC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;EACnE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,kBAAkB;EAClE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,qBAAqB;EAC/E,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,oBAAoB;EAC7E,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC;GAQnD,OAAO,EAAY,EAAE,OAPP,EAAM,SACnB,EAAK,SAAS,MACd,EAAK,aAAa,MAClB,EAAK,cACL,EAAK,aACL,CAEoB,EAAM,CAAC;EAC7B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,iBACA,2DACA;EACC,KAAK,EACH,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EACvC,IAAI,GAAG,EACP,SAAS,sBAAsB;EACjC,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,uBAAuB;EACjF,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,sBAAsB;EAC/E,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,EAAK,EAAE,SAAS,kCAAkC;EAC5F,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GAKH,IAAM,IAAU,EAAa,GAD5B,EAAK,YAAY,KAAA,KAAa,CAAC,EAAK,QAAQ,KAAK,IAAI,OAAO,EAAe,CACrB,GACjD,IAAkB,GAAS,WAAW,MACtC,EAAE,SAAS,GAAY,SAAS,MAAe,EAAiB,EAAK,GAAG,GACxE,IAAyC,CAAC;GAEhD,AAAI,EAAW,SAAS,KACvB,EAAO,KAAK;IACX,MAAM;IACN,OAAO;IACP,SAAS;IACT,KAAK;GACN,CAAC;GAGF,IAAM,IAA4B,CAAC,GAC7B,IAAmC,CAAC,GACpC,IAAkC,CAAC,GACnC,IAAgC,CAAC,GACjC,IAAsC,CAAC,GACvC,oBAAe,IAAI,IAAY,GAC/B,oBAAkB,IAAI,IAA2B;GAEvD,KAAK,IAAM,KAAY,GAAY;IAClC,IAAM,IAAO,EAAM,IAAI,CAAQ;IAC/B,IAAI,CAAC,GAAM,QAAQ;KAClB,EAAgB,KAAK,CAAQ;KAC7B;IACD;IAEA,IAAM,IAAY,EAAK;IACvB,IAAI,KAAmB,IAAY,GAAG;KACrC,IAAI,CAAC,EAAgB,IAAI,CAAS,GAAG;MACpC,IAAM,IAAM,EAAM,GAChB,QAAQ,mDAAmD,EAC3D,IAAI,CAAS;MACf,EAAgB,IAAI,GAAW,OAAO,GAAK,WAAY,WAAW,EAAI,UAAU,IAAI;KACrF;KACA,IAAI,CAAC,EAAqB,GAAiB,EAAgB,IAAI,CAAS,KAAK,IAAI,GAAG;MACnF,EAAuB,KAAK,CAAQ;MACpC;KACD;IACD,OAAO,IAAI,KAAmB,KAAa,GAAG;KAC7C,EAAuB,KAAK,CAAQ;KACpC;IACD;IAEA,IAAM,IAAW,EAAM,SACtB,MACA,GACA,EAAK,cACL,EAAK,aACL,CACD,GACM,IAAS,EAAS,MAAM,MAAiB,EAAa,OAAO,CAAQ;IAC3E,IAAI,CAAC,GAAQ;KACZ,EAAsB,KAAK,CAAQ;KACnC;IACD;IAEA,EAAQ,KAAK,CAAM;IACnB,KAAK,IAAM,KAAgB,GAAU;KACpC,IAAM,IAAa,EAAa;KAC5B,KAAc,KAAK,EAAa,IAAI,CAAU,MAClD,EAAa,IAAI,CAAU,GAC3B,EAAc,KAAK,CAAY;IAChC;GACD;GAkBA,AAhBI,EAAgB,SAAS,KAC5B,EAAO,KAAK;IACX,MAAM;IACN,OAAO;IACP,SAAS;IACT,KAAK;GACN,CAAC,GAEE,EAAuB,SAAS,KACnC,EAAO,KAAK;IACX,MAAM;IACN,OAAO;IACP,SAAS;IACT,KAAK;GACN,CAAC,GAEE,EAAsB,SAAS,KAClC,EAAO,KAAK;IACX,MAAM;IACN,OAAO;IACP,SAAS;IACT,KAAK;GACN,CAAC;GAGF,IAAI,IAAqC,CAAC;GAC1C,IAAI,EAAK,sBAAsB;IAC9B,IAAM,oBAAkB,IAAI,IAAY,GAClC,IAA2B,CAAC;IAClC,KAAK,IAAM,KAAQ,CAAC,GAAG,GAAS,GAAG,CAAa,GAC/C,AAAI,EAAK,KAAK,KAAK,CAAC,EAAgB,IAAI,EAAK,EAAE,MAC9C,EAAgB,IAAI,EAAK,EAAE,GAC3B,EAAe,KAAK,EAAK,EAAE;IAG7B,IAAe,EAAc,GAAO,GAAgB,CAAO;GAC5D;GAEA,OAAO,EAAY;IAClB;IACA,UAAU;IACV;IACA,aAAa,EAAW,QACtB,MACA,EAAgB,SAAS,CAAQ,KACjC,EAAuB,SAAS,CAAQ,KACxC,EAAsB,SAAS,CAAQ,CACzC;IACA;IACA,UAAU;KACT,SAAS;KACT,qBAAqB,EAAW;KAChC,uBAAuB,EAAQ;KAC/B,gBAAgB,EAAc;KAC9B,sBAAsB,EAAK;IAC5B;GACD,CAAC;EACF,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD;AACD;;;ACjLA,SAAgB,EACf,GACA,IAAmC,CAAC,GACxB;CACZ,IAAM,IAAS,IAAI,EAAU;EAAE,MAAM;EAAW,SAAS;CAAQ,CAAC,GAC5D,IAAmC;EACxC;EAGA,sBACK,EAAQ,wBAA8B,EAAQ,sBAAsB,IACpE,EAAQ,mBAAmB,KAAA,IACxB,EAAsB,IADoB,EAAQ;EAG1D,kBACC,EAAQ,eAAe,KAAA,IAAkC,QAAQ,IAAI,mBAAmB,OAArD,EAAQ;CAC7C;CASA,OAPA,EAAoB,GAAQ,CAAO,GACnC,EAAsB,GAAQ,CAAO,GACrC,EAAqB,GAAQ,CAAO,GACpC,EAAkB,GAAQ,CAAO,GACjC,EAAoB,CAAM,GAC1B,EAAmB,CAAM,GAElB;AACR"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAW,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,uBAAuB,EAA2B,MAAM,mBAAmB,CAAC;AAO1F,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,uBAA4B,GACnC,SAAS,CAsBX"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAW,MAAM,eAAe,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,KAAK,EAAE,uBAAuB,EAA2B,MAAM,mBAAmB,CAAC;AAQ1F,wBAAgB,sBAAsB,CACrC,KAAK,EAAE,WAAW,EAClB,OAAO,GAAE,uBAA4B,GACnC,SAAS,CAuBX"}
package/dist/stdio.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as e } from "./server-BH_IcTFq.js";
2
+ import { t as e } from "./server-pfLtHrsT.js";
3
3
  import { MemoryStore as t, resolveDbPath as n } from "@codemem/core";
4
4
  import { existsSync as r } from "node:fs";
5
5
  import { dirname as i, join as a } from "node:path";
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import type { ToolRegistrationContext } from "../tool-context.js";
3
+ export declare function registerDistillTools(server: McpServer, context: ToolRegistrationContext): void;
4
+ //# sourceMappingURL=distill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"distill.d.ts","sourceRoot":"","sources":["../../src/tools/distill.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAKzE,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AA6DlE,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAqF9F"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codemem/mcp",
3
- "version": "0.38.0-alpha.1",
3
+ "version": "0.38.0-alpha.2",
4
4
  "type": "module",
5
5
  "types": "./dist/index.d.ts",
6
6
  "exports": {
@@ -31,7 +31,7 @@
31
31
  "express": "^5.2.1",
32
32
  "express-rate-limit": "^8.5.2",
33
33
  "zod": "^4.4.3",
34
- "@codemem/core": "^0.38.0-alpha.1"
34
+ "@codemem/core": "^0.38.0-alpha.2"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/express": "^5.0.6",
@@ -1 +0,0 @@
1
- {"version":3,"file":"server-BH_IcTFq.js","names":[],"sources":["../src/project-scope.ts","../src/content.ts","../src/memory-access.ts","../src/schemas.ts","../src/tools/items.ts","../src/tools/learn.ts","../src/memory-kinds.ts","../src/tools/schema.ts","../src/tools/search.ts","../src/tools/timeline.ts","../src/server.ts"],"sourcesContent":["import { type MemoryFilters, resolveProject } from \"@codemem/core\";\n\nfunction cleanProject(value: string | null | undefined): string | null {\n\tconst trimmed = value?.trim();\n\treturn trimmed ? trimmed : null;\n}\n\nexport function resolveDefaultProject(): string | null {\n\treturn cleanProject(process.env.CODEMEM_PROJECT) ?? resolveProject(process.cwd());\n}\n\nexport function resolveWriteProject(input: {\n\tproject?: string | null;\n\tenvProject?: string | null;\n}): string | null {\n\treturn cleanProject(input.project) ?? cleanProject(input.envProject) ?? null;\n}\n\nexport function buildFilters(\n\traw: Record<string, unknown>,\n\tdefaultProject = resolveDefaultProject(),\n): MemoryFilters | undefined {\n\tconst filters: MemoryFilters = {};\n\tlet hasAny = false;\n\n\tconst explicitProject = typeof raw.project === \"string\" ? cleanProject(raw.project) : undefined;\n\tconst resolvedProject = explicitProject || cleanProject(defaultProject) || undefined;\n\tif (resolvedProject) {\n\t\tfilters.project = resolvedProject;\n\t\thasAny = true;\n\t}\n\n\tfor (const key of [\n\t\t\"kind\",\n\t\t\"visibility\",\n\t\t\"scope_id\",\n\t\t\"include_scope_ids\",\n\t\t\"exclude_scope_ids\",\n\t\t\"include_visibility\",\n\t\t\"exclude_visibility\",\n\t\t\"include_workspace_ids\",\n\t\t\"exclude_workspace_ids\",\n\t\t\"include_workspace_kinds\",\n\t\t\"exclude_workspace_kinds\",\n\t\t\"include_actor_ids\",\n\t\t\"exclude_actor_ids\",\n\t\t\"include_trust_states\",\n\t\t\"exclude_trust_states\",\n\t\t\"ownership_scope\",\n\t\t\"personal_first\",\n\t\t\"trust_bias\",\n\t\t\"widen_shared_when_weak\",\n\t\t\"widen_shared_min_personal_results\",\n\t\t\"widen_shared_min_personal_score\",\n\t] as const) {\n\t\tconst val = raw[key];\n\t\tif (val !== undefined && val !== null) {\n\t\t\t(filters as Record<string, unknown>)[key] = val;\n\t\t\thasAny = true;\n\t\t}\n\t}\n\n\treturn hasAny ? filters : undefined;\n}\n","export function jsonContent(data: unknown) {\n\treturn { content: [{ type: \"text\" as const, text: JSON.stringify(data) }] };\n}\n\nexport function errorContent(message: string) {\n\treturn { content: [{ type: \"text\" as const, text: JSON.stringify({ error: message }) }] };\n}\n","import {\n\ttype MemoryFilters,\n\ttype MemoryItemResponse,\n\ttype MemoryStore,\n\ttoJson,\n} from \"@codemem/core\";\nimport { resolveWriteProject } from \"./project-scope.js\";\n\nexport function getMemoryForMcp(\n\tstore: MemoryStore,\n\tmemoryId: number,\n\tfilters?: MemoryFilters,\n): MemoryItemResponse | null {\n\tconst rows = store.timeline(null, memoryId, 0, 0, filters ?? null);\n\treturn rows.find((row) => row.id === memoryId) ?? null;\n}\n\nexport function getManyForMcp(\n\tstore: MemoryStore,\n\tids: number[],\n\tfilters?: MemoryFilters,\n): MemoryItemResponse[] {\n\tif (ids.length === 0) return [];\n\tconst results: MemoryItemResponse[] = [];\n\tfor (const id of ids) {\n\t\tconst item = getMemoryForMcp(store, id, filters);\n\t\tif (item) results.push(item);\n\t}\n\treturn results;\n}\n\nexport function forgetMemoryForMcp(\n\tstore: MemoryStore,\n\tmemoryId: number,\n\tfilters?: MemoryFilters,\n): boolean {\n\tconst item = getMemoryForMcp(store, memoryId, filters);\n\tif (!item) return false;\n\tstore.forget(memoryId);\n\treturn true;\n}\n\nexport interface RememberMemoryForMcpInput {\n\tkind: string;\n\ttitle: string;\n\tbody: string;\n\tconfidence: number;\n\tproject?: string | null;\n}\n\nexport interface RememberMemoryForMcpContext {\n\tcwd?: string;\n\tuser?: string;\n\tenvProject?: string | null;\n\tnow?: () => string;\n}\n\nexport function rememberMemoryForMcp(\n\tstore: MemoryStore,\n\tinput: RememberMemoryForMcpInput,\n\tcontext: RememberMemoryForMcpContext = {},\n): { memId: number; title: string; body: string } {\n\treturn store.db.transaction(() => {\n\t\tconst now = context.now?.() ?? new Date().toISOString();\n\t\tconst user = context.user ?? process.env.USER ?? \"unknown\";\n\t\tconst cwd = context.cwd ?? process.cwd();\n\t\tconst project = resolveWriteProject({\n\t\t\tproject: input.project,\n\t\t\tenvProject: context.envProject,\n\t\t});\n\n\t\tconst sessionInfo = store.db\n\t\t\t.prepare(\n\t\t\t\t`INSERT INTO sessions(started_at, ended_at, cwd, project, user, tool_version, metadata_json)\n\t\t\t\t VALUES (?, ?, ?, ?, ?, ?, ?)`,\n\t\t\t)\n\t\t\t.run(now, now, cwd, project, user, \"mcp-ts\", toJson({ mcp: true }));\n\t\tconst sessionId = Number(sessionInfo.lastInsertRowid);\n\n\t\tconst memId = store.remember(sessionId, input.kind, input.title, input.body, input.confidence);\n\t\tif (!getMemoryForMcp(store, memId)) {\n\t\t\tthrow new Error(\"unauthorized_scope\");\n\t\t}\n\n\t\tstore.db\n\t\t\t.prepare(\"UPDATE sessions SET ended_at = ?, metadata_json = ? WHERE id = ?\")\n\t\t\t.run(context.now?.() ?? new Date().toISOString(), toJson({ mcp: true }), sessionId);\n\n\t\treturn { memId, title: input.title, body: input.body };\n\t})();\n}\n","import { z } from \"zod\";\n\nconst scopeFilterSchema = {\n\tscope_id: z.string().optional().describe(\"Filter by a single sharing domain scope_id\"),\n\tinclude_scope_ids: z.array(z.string()).optional().describe(\"Sharing domain scope_ids to include\"),\n\texclude_scope_ids: z.array(z.string()).optional().describe(\"Sharing domain scope_ids to exclude\"),\n};\n\nexport const filterSchema = {\n\tkind: z.string().optional().describe(\"Filter by memory kind\"),\n\tproject: z.string().optional().describe(\"Filter by project scope (matches sessions.project)\"),\n\t...scopeFilterSchema,\n\tvisibility: z.array(z.string()).optional(),\n\tinclude_visibility: z.array(z.string()).optional(),\n\texclude_visibility: z.array(z.string()).optional(),\n\tinclude_workspace_ids: z.array(z.string()).optional(),\n\texclude_workspace_ids: z.array(z.string()).optional(),\n\tinclude_workspace_kinds: z.array(z.string()).optional(),\n\texclude_workspace_kinds: z.array(z.string()).optional(),\n\tinclude_actor_ids: z.array(z.string()).optional(),\n\texclude_actor_ids: z.array(z.string()).optional(),\n\tinclude_trust_states: z.array(z.string()).optional(),\n\texclude_trust_states: z.array(z.string()).optional(),\n\townership_scope: z.string().optional(),\n\tpersonal_first: z.union([z.boolean(), z.string()]).optional(),\n\ttrust_bias: z.string().optional(),\n\twiden_shared_when_weak: z.union([z.boolean(), z.string()]).optional(),\n\twiden_shared_min_personal_results: z.number().int().optional(),\n\twiden_shared_min_personal_score: z.number().optional(),\n};\n\nexport const memoryKindSchema = z.enum([\n\t\"discovery\",\n\t\"change\",\n\t\"feature\",\n\t\"bugfix\",\n\t\"refactor\",\n\t\"decision\",\n\t\"exploration\",\n]);\n\nexport const filterNames = Object.keys(filterSchema).toSorted();\n","import { storeVectors } from \"@codemem/core\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { errorContent, jsonContent } from \"../content.js\";\nimport {\n\tforgetMemoryForMcp,\n\tgetManyForMcp,\n\tgetMemoryForMcp,\n\trememberMemoryForMcp,\n} from \"../memory-access.js\";\nimport { buildFilters } from \"../project-scope.js\";\nimport { filterSchema, memoryKindSchema } from \"../schemas.js\";\nimport type { ToolRegistrationContext } from \"../tool-context.js\";\n\nexport function registerItemTools(server: McpServer, context: ToolRegistrationContext): void {\n\tconst { envProject, store } = context;\n\n\tserver.tool(\n\t\t\"memory_get\",\n\t\t\"Fetch a single memory item by ID.\",\n\t\t{\n\t\t\tmemory_id: z.number().int().describe(\"Memory ID\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\t// Direct-ID ops do not inherit the server default project. Callers already\n\t\t\t\t// have an exact ID; cwd/env should not silently scope the lookup.\n\t\t\t\tconst item = getMemoryForMcp(store, args.memory_id, buildFilters(args, null));\n\t\t\t\tif (!item) return errorContent(\"not_found\");\n\t\t\t\treturn jsonContent(item);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_get_observations\",\n\t\t\"Fetch multiple memory items by their IDs.\",\n\t\t{\n\t\t\tids: z.array(z.number().int()).max(200).describe(\"Memory IDs to fetch\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst items = getManyForMcp(store, args.ids, buildFilters(args, null));\n\t\t\t\treturn jsonContent({ items });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_remember\",\n\t\t\"Create a new memory. Use for milestones, decisions, and notable facts.\",\n\t\t{\n\t\t\tkind: memoryKindSchema.describe(\"Memory kind\"),\n\t\t\ttitle: z.string().describe(\"Short title\"),\n\t\t\tbody: z.string().describe(\"Body text (high-signal content)\"),\n\t\t\tconfidence: z.number().min(0).max(1).default(0.5).describe(\"Confidence 0-1\"),\n\t\t\tproject: z.string().optional().describe(\"Project identifier\"),\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\t// Writes never inherit the server default project. They only honor an\n\t\t\t\t// explicit `project` input or CODEMEM_PROJECT; otherwise project stays null.\n\t\t\t\tconst result = rememberMemoryForMcp(store, args, {\n\t\t\t\t\tenvProject: envProject(),\n\t\t\t\t});\n\n\t\t\t\ttry {\n\t\t\t\t\tawait storeVectors(store.db, result.memId, result.title, result.body);\n\t\t\t\t} catch {\n\t\t\t\t\t// Memory writes should succeed even if embeddings are unavailable.\n\t\t\t\t}\n\n\t\t\t\treturn jsonContent({ id: result.memId });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_forget\",\n\t\t\"Soft-delete a memory item. Use for incorrect or sensitive data.\",\n\t\t{\n\t\t\tmemory_id: z.number().int().describe(\"Memory ID to forget\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tif (!forgetMemoryForMcp(store, args.memory_id, buildFilters(args, null))) {\n\t\t\t\t\treturn errorContent(\"not_found\");\n\t\t\t\t}\n\t\t\t\treturn jsonContent({ status: \"ok\" });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { jsonContent } from \"../content.js\";\n\nexport function registerLearnTools(server: McpServer): void {\n\tserver.tool(\n\t\t\"memory_learn\",\n\t\t\"Learn how to use codemem memory tools. Call this first if unfamiliar.\",\n\t\t{},\n\t\tasync () => {\n\t\t\treturn jsonContent({\n\t\t\t\tintro: \"Use this tool when you're new to codemem or unsure when to recall/persist.\",\n\t\t\t\tclient_hint: \"If you are unfamiliar with codemem, call memory.learn first.\",\n\t\t\t\trecall: {\n\t\t\t\t\twhen: [\n\t\t\t\t\t\t\"Start of a task or when the user references prior work.\",\n\t\t\t\t\t\t\"When you need background context, decisions, or recent changes.\",\n\t\t\t\t\t],\n\t\t\t\t\thow: [\n\t\t\t\t\t\t\"Use memory.search_index to get compact candidates.\",\n\t\t\t\t\t\t\"Use memory.timeline to expand around a promising memory.\",\n\t\t\t\t\t\t\"Use memory.get_observations for full details only when needed.\",\n\t\t\t\t\t\t\"Use memory.pack for quick one-shot context blocks.\",\n\t\t\t\t\t\t\"Use the project filter unless the user requests cross-project context.\",\n\t\t\t\t\t],\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t'memory.search_index(\"billing cache bug\", limit=5)',\n\t\t\t\t\t\t\"memory.timeline(memory_id=123)\",\n\t\t\t\t\t\t\"memory.get_observations([123, 456])\",\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tpersistence: {\n\t\t\t\t\twhen: [\n\t\t\t\t\t\t\"Milestones (task done, key decision, new facts learned).\",\n\t\t\t\t\t\t\"Notable regressions or follow-ups that should be remembered.\",\n\t\t\t\t\t],\n\t\t\t\t\thow: [\n\t\t\t\t\t\t\"Use memory.remember with kind decision/discovery/change/exploration.\",\n\t\t\t\t\t\t\"Keep titles short and bodies high-signal.\",\n\t\t\t\t\t\t\"ALWAYS pass the project parameter if known.\",\n\t\t\t\t\t],\n\t\t\t\t\texamples: [\n\t\t\t\t\t\t'memory.remember(kind=\"decision\", title=\"Switch to async cache\", body=\"...why...\", project=\"my-service\")',\n\t\t\t\t\t\t'memory.remember(kind=\"change\", title=\"Fixed retry loop\", body=\"...impact...\", project=\"my-service\")',\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t\tforget: {\n\t\t\t\t\twhen: [\n\t\t\t\t\t\t\"Accidental or sensitive data stored in memory items.\",\n\t\t\t\t\t\t\"Obsolete or incorrect items that should no longer surface.\",\n\t\t\t\t\t],\n\t\t\t\t\thow: [\n\t\t\t\t\t\t\"Call memory.forget(id) to mark the item inactive.\",\n\t\t\t\t\t\t\"Prefer forgetting over overwriting to preserve auditability.\",\n\t\t\t\t\t],\n\t\t\t\t\texamples: [\"memory.forget(123)\"],\n\t\t\t\t},\n\t\t\t\tprompt_hint:\n\t\t\t\t\t\"At task start: call memory.search_index; during work: memory.timeline + memory.get_observations; at milestones: memory.remember.\",\n\t\t\t\trecommended_system_prompt: [\n\t\t\t\t\t\"Trigger policy (1-liner): If the user references prior work or starts a task,\",\n\t\t\t\t\t\"immediately call memory.search_index; then use memory.timeline + memory.get_observations;\",\n\t\t\t\t\t\"at milestones, call memory.remember; use memory.forget for incorrect/sensitive items.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"System prompt:\",\n\t\t\t\t\t\"You have access to codemem MCP tools. If unfamiliar, call memory.learn first.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Recall:\",\n\t\t\t\t\t\"- Start of any task: call memory.search_index with a concise task query.\",\n\t\t\t\t\t'- If prior work is referenced (\"as before\", \"last time\", \"we already did…\", \"regression\"),',\n\t\t\t\t\t\" call memory.search_index or memory.timeline.\",\n\t\t\t\t\t\"- Use memory.get_observations only after filtering IDs.\",\n\t\t\t\t\t\"- Prefer project-scoped queries unless the user asks for cross-project.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Persistence:\",\n\t\t\t\t\t\"- On milestones (task done, key decision, new facts learned), call memory.remember.\",\n\t\t\t\t\t\"- Use kind=decision for tradeoffs, kind=change for outcomes, kind=discovery/exploration for useful findings.\",\n\t\t\t\t\t\"- Keep titles short and bodies high-signal.\",\n\t\t\t\t\t\"- ALWAYS pass the project parameter if known.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Safety:\",\n\t\t\t\t\t\"- Use memory.forget(id) for incorrect or sensitive items.\",\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Examples:\",\n\t\t\t\t\t'- memory.search_index(\"billing cache bug\")',\n\t\t\t\t\t\"- memory.timeline(memory_id=123)\",\n\t\t\t\t\t\"- memory.get_observations([123, 456])\",\n\t\t\t\t\t'- memory.remember(kind=\"decision\", title=\"Use async cache\", body=\"Chose async cache to avoid lock contention in X.\", project=\"my-service\")',\n\t\t\t\t\t'- memory.remember(kind=\"change\", title=\"Fixed retry loop\", body=\"Root cause was Y; added guard in Z.\", project=\"my-service\")',\n\t\t\t\t\t\"- memory.forget(123)\",\n\t\t\t\t].join(\"\\n\"),\n\t\t\t});\n\t\t},\n\t);\n}\n","export const MEMORY_KINDS: Record<string, string> = {\n\tdiscovery: \"Something learned about the codebase, architecture, or tools\",\n\tchange: \"A code change that was made\",\n\tfeature: \"A new feature that was implemented\",\n\tbugfix: \"A bug that was found and fixed\",\n\trefactor: \"Code that was refactored or restructured\",\n\tdecision: \"A design or architecture decision\",\n\texploration: \"An experiment or investigation (may not have shipped)\",\n};\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { jsonContent } from \"../content.js\";\nimport { MEMORY_KINDS } from \"../memory-kinds.js\";\nimport { filterNames } from \"../schemas.js\";\n\nexport function registerSchemaTools(server: McpServer): void {\n\tserver.tool(\n\t\t\"memory_schema\",\n\t\t\"Return the memory schema — kinds, fields, and available filters.\",\n\t\t{},\n\t\tasync () => {\n\t\t\treturn jsonContent({\n\t\t\t\tkinds: Object.keys(MEMORY_KINDS),\n\t\t\t\tkind_descriptions: MEMORY_KINDS,\n\t\t\t\tfields: {\n\t\t\t\t\ttitle: \"short text\",\n\t\t\t\t\tbody: \"long text\",\n\t\t\t\t\tsubtitle: \"short text\",\n\t\t\t\t\tfacts: \"list<string>\",\n\t\t\t\t\tnarrative: \"long text\",\n\t\t\t\t\tconcepts: \"list<string>\",\n\t\t\t\t\tfiles_read: \"list<string>\",\n\t\t\t\t\tfiles_modified: \"list<string>\",\n\t\t\t\t\tprompt_number: \"int\",\n\t\t\t\t},\n\t\t\t\tfilters: filterNames,\n\t\t\t});\n\t\t},\n\t);\n}\n","import type { MemoryResult } from \"@codemem/core\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { errorContent, jsonContent } from \"../content.js\";\nimport { buildFilters } from \"../project-scope.js\";\nimport { filterSchema } from \"../schemas.js\";\nimport type { ToolRegistrationContext } from \"../tool-context.js\";\n\nexport function registerSearchTools(server: McpServer, context: ToolRegistrationContext): void {\n\tconst { defaultProject, store } = context;\n\n\tserver.tool(\n\t\t\"memory_search\",\n\t\t\"Search memories by text query. Returns full body text for each match.\",\n\t\t{\n\t\t\tquery: z.string().describe(\"Search query\"),\n\t\t\tlimit: z.number().int().min(1).max(50).default(5).describe(\"Max results\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst items = store.search(args.query, args.limit, filters);\n\t\t\t\treturn jsonContent({\n\t\t\t\t\titems: items.map((m: MemoryResult) => ({\n\t\t\t\t\t\tid: m.id,\n\t\t\t\t\t\ttitle: m.title,\n\t\t\t\t\t\tkind: m.kind,\n\t\t\t\t\t\tbody: m.body_text,\n\t\t\t\t\t\tconfidence: m.confidence,\n\t\t\t\t\t\tscore: m.score,\n\t\t\t\t\t\tsession_id: m.session_id,\n\t\t\t\t\t\tmetadata: m.metadata,\n\t\t\t\t\t})),\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_search_index\",\n\t\t\"Search memories by text query. Returns compact index entries (no body) for browsing.\",\n\t\t{\n\t\t\tquery: z.string().describe(\"Search query\"),\n\t\t\tlimit: z.number().int().min(1).max(50).default(8).describe(\"Max results\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst items = store.search(args.query, args.limit, filters);\n\t\t\t\treturn jsonContent({\n\t\t\t\t\titems: items.map((m: MemoryResult) => ({\n\t\t\t\t\t\tid: m.id,\n\t\t\t\t\t\tkind: m.kind,\n\t\t\t\t\t\ttitle: m.title,\n\t\t\t\t\t\tscore: m.score,\n\t\t\t\t\t\tcreated_at: m.created_at,\n\t\t\t\t\t\tsession_id: m.session_id,\n\t\t\t\t\t\tmetadata: m.metadata,\n\t\t\t\t\t})),\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_explain\",\n\t\t\"Explain search results with detailed scoring breakdown.\",\n\t\t{\n\t\t\tquery: z.string().optional().describe(\"Search query\"),\n\t\t\tids: z.array(z.number().int()).max(200).optional().describe(\"Specific memory IDs to explain\"),\n\t\t\tlimit: z.number().int().min(1).max(50).default(10).describe(\"Max results\"),\n\t\t\tinclude_pack_context: z.boolean().default(false).describe(\"Include formatted pack context\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst result = store.explain(args.query ?? null, args.ids ?? null, args.limit, filters, {\n\t\t\t\t\tincludePackContext: args.include_pack_context,\n\t\t\t\t});\n\t\t\t\treturn jsonContent(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_recent\",\n\t\t\"Return recent memories, newest first.\",\n\t\t{\n\t\t\tlimit: z.number().int().min(1).max(100).default(8).describe(\"Max results\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst items = store.recent(args.limit, filters);\n\t\t\t\treturn jsonContent({ items });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_pack\",\n\t\t\"Build a formatted memory pack from search results — quick one-shot context block.\",\n\t\t{\n\t\t\tcontext: z.string().describe(\"Context description to search for\"),\n\t\t\tlimit: z.number().int().min(1).max(50).optional().describe(\"Max items to include\"),\n\t\t\tcompact: z\n\t\t\t\t.boolean()\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t\"When true, render a scannable index of all items with full detail only for the top N (default 3). Saves tokens when broad overview matters more than per-item detail.\",\n\t\t\t\t),\n\t\t\tcompact_detail_count: z\n\t\t\t\t.number()\n\t\t\t\t.int()\n\t\t\t\t.min(0)\n\t\t\t\t.max(50)\n\t\t\t\t.optional()\n\t\t\t\t.describe(\"Number of items to show in full detail in compact mode (default 3)\"),\n\t\t\tcompression_mode: z\n\t\t\t\t.enum([\"off\", \"compact\", \"ids\"])\n\t\t\t\t.optional()\n\t\t\t\t.describe(\n\t\t\t\t\t\"Near-related compression mode: off disables it, compact applies only to compact rendering, ids applies in all modes. Defaults to CODEMEM_PACK_COMPRESSION or compact.\",\n\t\t\t\t),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst renderOptions =\n\t\t\t\t\targs.compact || args.compact_detail_count != null || args.compression_mode != null\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tcompact: args.compact ?? (args.compact_detail_count != null ? true : undefined),\n\t\t\t\t\t\t\t\tcompactDetailCount: args.compact_detail_count,\n\t\t\t\t\t\t\t\tcompressionMode: args.compression_mode,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: undefined;\n\t\t\t\tconst result = await store.buildMemoryPackAsync(\n\t\t\t\t\targs.context,\n\t\t\t\t\targs.limit ?? undefined,\n\t\t\t\t\tnull,\n\t\t\t\t\tfilters,\n\t\t\t\t\trenderOptions,\n\t\t\t\t);\n\t\t\t\treturn jsonContent(result);\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n}\n","import { dedupeOrderedIds, type MemoryItemResponse, projectMatchesFilter } from \"@codemem/core\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { z } from \"zod\";\nimport { errorContent, jsonContent } from \"../content.js\";\nimport { getManyForMcp } from \"../memory-access.js\";\nimport { buildFilters } from \"../project-scope.js\";\nimport { filterSchema } from \"../schemas.js\";\nimport type { ToolRegistrationContext } from \"../tool-context.js\";\n\nexport function registerTimelineTools(server: McpServer, context: ToolRegistrationContext): void {\n\tconst { defaultProject, store } = context;\n\n\tserver.tool(\n\t\t\"memory_timeline\",\n\t\t\"Get a chronological window of memories around an anchor (by ID or query).\",\n\t\t{\n\t\t\tquery: z.string().optional().describe(\"Search query to find anchor\"),\n\t\t\tmemory_id: z.number().int().optional().describe(\"Anchor memory ID\"),\n\t\t\tdepth_before: z.number().int().min(0).default(3).describe(\"Items before anchor\"),\n\t\t\tdepth_after: z.number().int().min(0).default(3).describe(\"Items after anchor\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\tconst filters = buildFilters(args, defaultProject());\n\t\t\t\tconst items = store.timeline(\n\t\t\t\t\targs.query ?? null,\n\t\t\t\t\targs.memory_id ?? null,\n\t\t\t\t\targs.depth_before,\n\t\t\t\t\targs.depth_after,\n\t\t\t\t\tfilters,\n\t\t\t\t);\n\t\t\t\treturn jsonContent({ items });\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n\n\tserver.tool(\n\t\t\"memory_expand\",\n\t\t\"Fetch memories by ID with surrounding timeline context.\",\n\t\t{\n\t\t\tids: z\n\t\t\t\t.array(z.union([z.number(), z.string()]))\n\t\t\t\t.max(200)\n\t\t\t\t.describe(\"Memory IDs to expand\"),\n\t\t\tdepth_before: z.number().int().min(0).default(3).describe(\"Timeline items before\"),\n\t\t\tdepth_after: z.number().int().min(0).default(3).describe(\"Timeline items after\"),\n\t\t\tinclude_observations: z.boolean().default(false).describe(\"Include full observation details\"),\n\t\t\t...filterSchema,\n\t\t},\n\t\tasync (args) => {\n\t\t\ttry {\n\t\t\t\t// Explicit blank `project` clears scoping for cross-project expansion.\n\t\t\t\t// Only fall back to the server default when `project` is omitted entirely.\n\t\t\t\tconst filterDefaultProject =\n\t\t\t\t\targs.project !== undefined && !args.project.trim() ? null : defaultProject();\n\t\t\t\tconst filters = buildFilters(args, filterDefaultProject);\n\t\t\t\tconst resolvedProject = filters?.project ?? null;\n\t\t\t\tconst { ordered: orderedIds, invalid: invalidIds } = dedupeOrderedIds(args.ids);\n\t\t\t\tconst errors: Array<Record<string, unknown>> = [];\n\n\t\t\t\tif (invalidIds.length > 0) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tcode: \"INVALID_ARGUMENT\",\n\t\t\t\t\t\tfield: \"ids\",\n\t\t\t\t\t\tmessage: \"some ids are not valid integers\",\n\t\t\t\t\t\tids: invalidIds,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst missingNotFound: number[] = [];\n\t\t\t\tconst missingProjectMismatch: number[] = [];\n\t\t\t\tconst missingFilterMismatch: number[] = [];\n\t\t\t\tconst anchors: MemoryItemResponse[] = [];\n\t\t\t\tconst timelineItems: MemoryItemResponse[] = [];\n\t\t\t\tconst timelineSeen = new Set<number>();\n\t\t\t\tconst sessionProjects = new Map<number, string | null>();\n\n\t\t\t\tfor (const memoryId of orderedIds) {\n\t\t\t\t\tconst item = store.get(memoryId);\n\t\t\t\t\tif (!item?.active) {\n\t\t\t\t\t\tmissingNotFound.push(memoryId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst sessionId = item.session_id;\n\t\t\t\t\tif (resolvedProject && sessionId > 0) {\n\t\t\t\t\t\tif (!sessionProjects.has(sessionId)) {\n\t\t\t\t\t\t\tconst row = store.db\n\t\t\t\t\t\t\t\t.prepare(\"SELECT project FROM sessions WHERE id = ? LIMIT 1\")\n\t\t\t\t\t\t\t\t.get(sessionId) as { project: string | null } | undefined;\n\t\t\t\t\t\t\tsessionProjects.set(sessionId, typeof row?.project === \"string\" ? row.project : null);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (!projectMatchesFilter(resolvedProject, sessionProjects.get(sessionId) ?? null)) {\n\t\t\t\t\t\t\tmissingProjectMismatch.push(memoryId);\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (resolvedProject && sessionId <= 0) {\n\t\t\t\t\t\tmissingProjectMismatch.push(memoryId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst expanded = store.timeline(\n\t\t\t\t\t\tnull,\n\t\t\t\t\t\tmemoryId,\n\t\t\t\t\t\targs.depth_before,\n\t\t\t\t\t\targs.depth_after,\n\t\t\t\t\t\tfilters,\n\t\t\t\t\t);\n\t\t\t\t\tconst anchor = expanded.find((expandedItem) => expandedItem.id === memoryId);\n\t\t\t\t\tif (!anchor) {\n\t\t\t\t\t\tmissingFilterMismatch.push(memoryId);\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tanchors.push(anchor);\n\t\t\t\t\tfor (const expandedItem of expanded) {\n\t\t\t\t\t\tconst expandedId = expandedItem.id;\n\t\t\t\t\t\tif (expandedId <= 0 || timelineSeen.has(expandedId)) continue;\n\t\t\t\t\t\ttimelineSeen.add(expandedId);\n\t\t\t\t\t\ttimelineItems.push(expandedItem);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (missingNotFound.length > 0) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tcode: \"NOT_FOUND\",\n\t\t\t\t\t\tfield: \"ids\",\n\t\t\t\t\t\tmessage: \"some requested ids were not found\",\n\t\t\t\t\t\tids: missingNotFound,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (missingProjectMismatch.length > 0) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tcode: \"PROJECT_MISMATCH\",\n\t\t\t\t\t\tfield: \"project\",\n\t\t\t\t\t\tmessage: \"some requested ids are outside the requested project scope\",\n\t\t\t\t\t\tids: missingProjectMismatch,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tif (missingFilterMismatch.length > 0) {\n\t\t\t\t\terrors.push({\n\t\t\t\t\t\tcode: \"FILTER_MISMATCH\",\n\t\t\t\t\t\tfield: \"filters\",\n\t\t\t\t\t\tmessage: \"some requested ids are outside the requested filters\",\n\t\t\t\t\t\tids: missingFilterMismatch,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tlet observations: MemoryItemResponse[] = [];\n\t\t\t\tif (args.include_observations) {\n\t\t\t\t\tconst observationSeen = new Set<number>();\n\t\t\t\t\tconst observationIds: number[] = [];\n\t\t\t\t\tfor (const item of [...anchors, ...timelineItems]) {\n\t\t\t\t\t\tif (item.id > 0 && !observationSeen.has(item.id)) {\n\t\t\t\t\t\t\tobservationSeen.add(item.id);\n\t\t\t\t\t\t\tobservationIds.push(item.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tobservations = getManyForMcp(store, observationIds, filters);\n\t\t\t\t}\n\n\t\t\t\treturn jsonContent({\n\t\t\t\t\tanchors,\n\t\t\t\t\ttimeline: timelineItems,\n\t\t\t\t\tobservations,\n\t\t\t\t\tmissing_ids: orderedIds.filter(\n\t\t\t\t\t\t(memoryId: number) =>\n\t\t\t\t\t\t\tmissingNotFound.includes(memoryId) ||\n\t\t\t\t\t\t\tmissingProjectMismatch.includes(memoryId) ||\n\t\t\t\t\t\t\tmissingFilterMismatch.includes(memoryId),\n\t\t\t\t\t),\n\t\t\t\t\terrors,\n\t\t\t\t\tmetadata: {\n\t\t\t\t\t\tproject: resolvedProject,\n\t\t\t\t\t\trequested_ids_count: orderedIds.length,\n\t\t\t\t\t\treturned_anchor_count: anchors.length,\n\t\t\t\t\t\ttimeline_count: timelineItems.length,\n\t\t\t\t\t\tinclude_observations: args.include_observations,\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t} catch (err) {\n\t\t\t\treturn errorContent(err instanceof Error ? err.message : String(err));\n\t\t\t}\n\t\t},\n\t);\n}\n","import { type MemoryStore, VERSION } from \"@codemem/core\";\nimport { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { resolveDefaultProject } from \"./project-scope.js\";\nimport type { CodememMcpServerOptions, ToolRegistrationContext } from \"./tool-context.js\";\nimport { registerItemTools } from \"./tools/items.js\";\nimport { registerLearnTools } from \"./tools/learn.js\";\nimport { registerSchemaTools } from \"./tools/schema.js\";\nimport { registerSearchTools } from \"./tools/search.js\";\nimport { registerTimelineTools } from \"./tools/timeline.js\";\n\nexport function createCodememMcpServer(\n\tstore: MemoryStore,\n\toptions: CodememMcpServerOptions = {},\n): McpServer {\n\tconst server = new McpServer({ name: \"codemem\", version: VERSION });\n\tconst context: ToolRegistrationContext = {\n\t\tstore,\n\t\t// Resolve lazily per call so long-running servers pick up the current\n\t\t// CODEMEM_PROJECT / process.cwd() rather than the value at construction.\n\t\tdefaultProject: () => {\n\t\t\tif (options.resolveDefaultProject) return options.resolveDefaultProject();\n\t\t\tif (options.defaultProject !== undefined) return options.defaultProject;\n\t\t\treturn resolveDefaultProject();\n\t\t},\n\t\tenvProject: () =>\n\t\t\toptions.envProject !== undefined ? options.envProject : (process.env.CODEMEM_PROJECT ?? null),\n\t};\n\n\tregisterSearchTools(server, context);\n\tregisterTimelineTools(server, context);\n\tregisterItemTools(server, context);\n\tregisterSchemaTools(server);\n\tregisterLearnTools(server);\n\n\treturn server;\n}\n"],"mappings":";;;;AAEA,SAAS,EAAa,GAAiD;CAEtE,OADgB,GAAO,KAAK,KACD;AAC5B;AAEA,SAAgB,IAAuC;CACtD,OAAO,EAAa,QAAQ,IAAI,eAAe,KAAK,EAAe,QAAQ,IAAI,CAAC;AACjF;AAEA,SAAgB,EAAoB,GAGlB;CACjB,OAAO,EAAa,EAAM,OAAO,KAAK,EAAa,EAAM,UAAU,KAAK;AACzE;AAEA,SAAgB,EACf,GACA,IAAiB,EAAsB,GACX;CAC5B,IAAM,IAAyB,CAAC,GAC5B,IAAS,IAGP,KADkB,OAAO,EAAI,WAAY,WAAW,EAAa,EAAI,OAAO,IAAI,KAAA,MAC3C,EAAa,CAAc,KAAK,KAAA;CAC3E,AAAI,MACH,EAAQ,UAAU,GAClB,IAAS;CAGV,KAAK,IAAM,KAAO;EACjB;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACD,GAAY;EACX,IAAM,IAAM,EAAI;EAChB,AAAI,KAA6B,SAChC,EAAqC,KAAO,GAC5C,IAAS;CAEX;CAEA,OAAO,IAAS,IAAU,KAAA;AAC3B;;;AC/DA,SAAgB,EAAY,GAAe;CAC1C,OAAO,EAAE,SAAS,CAAC;EAAE,MAAM;EAAiB,MAAM,KAAK,UAAU,CAAI;CAAE,CAAC,EAAE;AAC3E;AAEA,SAAgB,EAAa,GAAiB;CAC7C,OAAO,EAAE,SAAS,CAAC;EAAE,MAAM;EAAiB,MAAM,KAAK,UAAU,EAAE,OAAO,EAAQ,CAAC;CAAE,CAAC,EAAE;AACzF;;;ACEA,SAAgB,EACf,GACA,GACA,GAC4B;CAE5B,OADa,EAAM,SAAS,MAAM,GAAU,GAAG,GAAG,KAAW,IACtD,EAAK,MAAM,MAAQ,EAAI,OAAO,CAAQ,KAAK;AACnD;AAEA,SAAgB,EACf,GACA,GACA,GACuB;CACvB,IAAI,EAAI,WAAW,GAAG,OAAO,CAAC;CAC9B,IAAM,IAAgC,CAAC;CACvC,KAAK,IAAM,KAAM,GAAK;EACrB,IAAM,IAAO,EAAgB,GAAO,GAAI,CAAO;EAC/C,AAAI,KAAM,EAAQ,KAAK,CAAI;CAC5B;CACA,OAAO;AACR;AAEA,SAAgB,EACf,GACA,GACA,GACU;CAIV,OAHa,EAAgB,GAAO,GAAU,CACzC,KACL,EAAM,OAAO,CAAQ,GACd,MAFW;AAGnB;AAiBA,SAAgB,EACf,GACA,GACA,IAAuC,CAAC,GACS;CACjD,OAAO,EAAM,GAAG,kBAAkB;EACjC,IAAM,IAAM,EAAQ,MAAM,sBAAK,IAAI,KAAK,GAAE,YAAY,GAChD,IAAO,EAAQ,QAAQ,QAAQ,IAAI,QAAQ,WAC3C,IAAM,EAAQ,OAAO,QAAQ,IAAI,GACjC,IAAU,EAAoB;GACnC,SAAS,EAAM;GACf,YAAY,EAAQ;EACrB,CAAC,GAEK,IAAc,EAAM,GACxB,QACA,gIAED,EACC,IAAI,GAAK,GAAK,GAAK,GAAS,GAAM,UAAU,EAAO,EAAE,KAAK,GAAK,CAAC,CAAC,GAC7D,IAAY,OAAO,EAAY,eAAe,GAE9C,IAAQ,EAAM,SAAS,GAAW,EAAM,MAAM,EAAM,OAAO,EAAM,MAAM,EAAM,UAAU;EAC7F,IAAI,CAAC,EAAgB,GAAO,CAAK,GAChC,MAAU,MAAM,oBAAoB;EAOrC,OAJA,EAAM,GACJ,QAAQ,kEAAkE,EAC1E,IAAI,EAAQ,MAAM,sBAAK,IAAI,KAAK,GAAE,YAAY,GAAG,EAAO,EAAE,KAAK,GAAK,CAAC,GAAG,CAAS,GAE5E;GAAE;GAAO,OAAO,EAAM;GAAO,MAAM,EAAM;EAAK;CACtD,CAAC,EAAE;AACJ;;;ACxFA,IAAM,IAAoB;CACzB,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,4CAA4C;CACrF,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,qCAAqC;CAChG,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,SAAS,qCAAqC;AACjG,GAEa,IAAe;CAC3B,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,uBAAuB;CAC5D,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oDAAoD;CAC5F,GAAG;CACH,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACzC,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACjD,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACjD,uBAAuB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACpD,uBAAuB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACpD,yBAAyB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACtD,yBAAyB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACtD,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CAChD,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CAChD,sBAAsB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACnD,sBAAsB,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS;CACnD,iBAAiB,EAAE,OAAO,EAAE,SAAS;CACrC,gBAAgB,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;CAC5D,YAAY,EAAE,OAAO,EAAE,SAAS;CAChC,wBAAwB,EAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,OAAO,CAAC,CAAC,EAAE,SAAS;CACpE,mCAAmC,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS;CAC7D,iCAAiC,EAAE,OAAO,EAAE,SAAS;AACtD,GAEa,IAAmB,EAAE,KAAK;CACtC;CACA;CACA;CACA;CACA;CACA;CACA;AACD,CAAC,GAEY,IAAc,OAAO,KAAK,CAAY,EAAE,SAAS;;;AC3B9D,SAAgB,EAAkB,GAAmB,GAAwC;CAC5F,IAAM,EAAE,eAAY,aAAU;CAsE9B,AApEA,EAAO,KACN,cACA,qCACA;EACC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,WAAW;EAChD,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GAGH,IAAM,IAAO,EAAgB,GAAO,EAAK,WAAW,EAAa,GAAM,IAAI,CAAC;GAE5E,OADK,IACE,EAAY,CAAI,IADL,EAAa,WAAW;EAE3C,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,2BACA,6CACA;EACC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,qBAAqB;EACtE,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GAEH,OAAO,EAAY,EAAE,OADP,EAAc,GAAO,EAAK,KAAK,EAAa,GAAM,IAAI,CAC/C,EAAM,CAAC;EAC7B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,mBACA,0EACA;EACC,MAAM,EAAiB,SAAS,aAAa;EAC7C,OAAO,EAAE,OAAO,EAAE,SAAS,aAAa;EACxC,MAAM,EAAE,OAAO,EAAE,SAAS,iCAAiC;EAC3D,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE,QAAQ,EAAG,EAAE,SAAS,gBAAgB;EAC3E,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,oBAAoB;CAC7D,GACA,OAAO,MAAS;EACf,IAAI;GAGH,IAAM,IAAS,EAAqB,GAAO,GAAM,EAChD,YAAY,EAAW,EACxB,CAAC;GAED,IAAI;IACH,MAAM,EAAa,EAAM,IAAI,EAAO,OAAO,EAAO,OAAO,EAAO,IAAI;GACrE,QAAQ,CAER;GAEA,OAAO,EAAY,EAAE,IAAI,EAAO,MAAM,CAAC;EACxC,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,iBACA,mEACA;EACC,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,qBAAqB;EAC1D,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GAIH,OAHK,EAAmB,GAAO,EAAK,WAAW,EAAa,GAAM,IAAI,CAAC,IAGhE,EAAY,EAAE,QAAQ,KAAK,CAAC,IAF3B,EAAa,WAAW;EAGjC,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD;AACD;;;ACpGA,SAAgB,EAAmB,GAAyB;CAC3D,EAAO,KACN,gBACA,yEACA,CAAC,GACD,YACQ,EAAY;EAClB,OAAO;EACP,aAAa;EACb,QAAQ;GACP,MAAM,CACL,2DACA,iEACD;GACA,KAAK;IACJ;IACA;IACA;IACA;IACA;GACD;GACA,UAAU;IACT;IACA;IACA;GACD;EACD;EACA,aAAa;GACZ,MAAM,CACL,4DACA,8DACD;GACA,KAAK;IACJ;IACA;IACA;GACD;GACA,UAAU,CACT,mHACA,6GACD;EACD;EACA,QAAQ;GACP,MAAM,CACL,wDACA,4DACD;GACA,KAAK,CACJ,qDACA,8DACD;GACA,UAAU,CAAC,oBAAoB;EAChC;EACA,aACC;EACD,2BAA2B;GAC1B;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;EACD,EAAE,KAAK,IAAI;CACZ,CAAC,CAEH;AACD;;;AC7FA,IAAa,IAAuC;CACnD,WAAW;CACX,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,UAAU;CACV,UAAU;CACV,aAAa;AACd;;;ACHA,SAAgB,EAAoB,GAAyB;CAC5D,EAAO,KACN,iBACA,oEACA,CAAC,GACD,YACQ,EAAY;EAClB,OAAO,OAAO,KAAK,CAAY;EAC/B,mBAAmB;EACnB,QAAQ;GACP,OAAO;GACP,MAAM;GACN,UAAU;GACV,OAAO;GACP,WAAW;GACX,UAAU;GACV,YAAY;GACZ,gBAAgB;GAChB,eAAe;EAChB;EACA,SAAS;CACV,CAAC,CAEH;AACD;;;ACrBA,SAAgB,EAAoB,GAAmB,GAAwC;CAC9F,IAAM,EAAE,mBAAgB,aAAU;CAsGlC,AApGA,EAAO,KACN,iBACA,yEACA;EACC,OAAO,EAAE,OAAO,EAAE,SAAS,cAAc;EACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,EAAE,SAAS,aAAa;EACxE,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC;GAEnD,OAAO,EAAY,EAClB,OAFa,EAAM,OAAO,EAAK,OAAO,EAAK,OAAO,CAE3C,EAAM,KAAK,OAAqB;IACtC,IAAI,EAAE;IACN,OAAO,EAAE;IACT,MAAM,EAAE;IACR,MAAM,EAAE;IACR,YAAY,EAAE;IACd,OAAO,EAAE;IACT,YAAY,EAAE;IACd,UAAU,EAAE;GACb,EAAE,EACH,CAAC;EACF,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,uBACA,wFACA;EACC,OAAO,EAAE,OAAO,EAAE,SAAS,cAAc;EACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,EAAE,SAAS,aAAa;EACxE,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC;GAEnD,OAAO,EAAY,EAClB,OAFa,EAAM,OAAO,EAAK,OAAO,EAAK,OAAO,CAE3C,EAAM,KAAK,OAAqB;IACtC,IAAI,EAAE;IACN,MAAM,EAAE;IACR,OAAO,EAAE;IACT,OAAO,EAAE;IACT,YAAY,EAAE;IACd,YAAY,EAAE;IACd,UAAU,EAAE;GACb,EAAE,EACH,CAAC;EACF,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,kBACA,2DACA;EACC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,cAAc;EACpD,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS,gCAAgC;EAC5F,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,SAAS,aAAa;EACzE,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,EAAK,EAAE,SAAS,gCAAgC;EAC1F,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC;GAInD,OAAO,EAHQ,EAAM,QAAQ,EAAK,SAAS,MAAM,EAAK,OAAO,MAAM,EAAK,OAAO,GAAS,EACvF,oBAAoB,EAAK,qBAC1B,CACmB,CAAM;EAC1B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,iBACA,yCACA;EACC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,QAAQ,CAAC,EAAE,SAAS,aAAa;EACzE,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC;GAEnD,OAAO,EAAY,EAAE,OADP,EAAM,OAAO,EAAK,OAAO,CAClB,EAAM,CAAC;EAC7B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,eACA,qFACA;EACC,SAAS,EAAE,OAAO,EAAE,SAAS,mCAAmC;EAChE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,SAAS,sBAAsB;EACjF,SAAS,EACP,QAAQ,EACR,SAAS,EACT,SACA,uKACD;EACD,sBAAsB,EACpB,OAAO,EACP,IAAI,EACJ,IAAI,CAAC,EACL,IAAI,EAAE,EACN,SAAS,EACT,SAAS,oEAAoE;EAC/E,kBAAkB,EAChB,KAAK;GAAC;GAAO;GAAW;EAAK,CAAC,EAC9B,SAAS,EACT,SACA,uKACD;EACD,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC,GAC7C,IACL,EAAK,WAAW,EAAK,wBAAwB,QAAQ,EAAK,oBAAoB,OAC3E;IACA,SAAS,EAAK,YAAY,EAAK,wBAAwB,OAAc,KAAA,IAAP;IAC9D,oBAAoB,EAAK;IACzB,iBAAiB,EAAK;GACvB,IACC,KAAA;GAQJ,OAAO,EAAY,MAPE,EAAM,qBAC1B,EAAK,SACL,EAAK,SAAS,KAAA,GACd,MACA,GACA,CACD,CACyB;EAC1B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD;AACD;;;ACzJA,SAAgB,EAAsB,GAAmB,GAAwC;CAChG,IAAM,EAAE,mBAAgB,aAAU;CA6BlC,AA3BA,EAAO,KACN,mBACA,6EACA;EACC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,6BAA6B;EACnE,WAAW,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,kBAAkB;EAClE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,qBAAqB;EAC/E,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,oBAAoB;EAC7E,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GACH,IAAM,IAAU,EAAa,GAAM,EAAe,CAAC;GAQnD,OAAO,EAAY,EAAE,OAPP,EAAM,SACnB,EAAK,SAAS,MACd,EAAK,aAAa,MAClB,EAAK,cACL,EAAK,aACL,CAEoB,EAAM,CAAC;EAC7B,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD,GAEA,EAAO,KACN,iBACA,2DACA;EACC,KAAK,EACH,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC,CAAC,EACvC,IAAI,GAAG,EACP,SAAS,sBAAsB;EACjC,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,uBAAuB;EACjF,aAAa,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,QAAQ,CAAC,EAAE,SAAS,sBAAsB;EAC/E,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,EAAK,EAAE,SAAS,kCAAkC;EAC5F,GAAG;CACJ,GACA,OAAO,MAAS;EACf,IAAI;GAKH,IAAM,IAAU,EAAa,GAD5B,EAAK,YAAY,KAAA,KAAa,CAAC,EAAK,QAAQ,KAAK,IAAI,OAAO,EAAe,CACrB,GACjD,IAAkB,GAAS,WAAW,MACtC,EAAE,SAAS,GAAY,SAAS,MAAe,EAAiB,EAAK,GAAG,GACxE,IAAyC,CAAC;GAEhD,AAAI,EAAW,SAAS,KACvB,EAAO,KAAK;IACX,MAAM;IACN,OAAO;IACP,SAAS;IACT,KAAK;GACN,CAAC;GAGF,IAAM,IAA4B,CAAC,GAC7B,IAAmC,CAAC,GACpC,IAAkC,CAAC,GACnC,IAAgC,CAAC,GACjC,IAAsC,CAAC,GACvC,oBAAe,IAAI,IAAY,GAC/B,oBAAkB,IAAI,IAA2B;GAEvD,KAAK,IAAM,KAAY,GAAY;IAClC,IAAM,IAAO,EAAM,IAAI,CAAQ;IAC/B,IAAI,CAAC,GAAM,QAAQ;KAClB,EAAgB,KAAK,CAAQ;KAC7B;IACD;IAEA,IAAM,IAAY,EAAK;IACvB,IAAI,KAAmB,IAAY,GAAG;KACrC,IAAI,CAAC,EAAgB,IAAI,CAAS,GAAG;MACpC,IAAM,IAAM,EAAM,GAChB,QAAQ,mDAAmD,EAC3D,IAAI,CAAS;MACf,EAAgB,IAAI,GAAW,OAAO,GAAK,WAAY,WAAW,EAAI,UAAU,IAAI;KACrF;KACA,IAAI,CAAC,EAAqB,GAAiB,EAAgB,IAAI,CAAS,KAAK,IAAI,GAAG;MACnF,EAAuB,KAAK,CAAQ;MACpC;KACD;IACD,OAAO,IAAI,KAAmB,KAAa,GAAG;KAC7C,EAAuB,KAAK,CAAQ;KACpC;IACD;IAEA,IAAM,IAAW,EAAM,SACtB,MACA,GACA,EAAK,cACL,EAAK,aACL,CACD,GACM,IAAS,EAAS,MAAM,MAAiB,EAAa,OAAO,CAAQ;IAC3E,IAAI,CAAC,GAAQ;KACZ,EAAsB,KAAK,CAAQ;KACnC;IACD;IAEA,EAAQ,KAAK,CAAM;IACnB,KAAK,IAAM,KAAgB,GAAU;KACpC,IAAM,IAAa,EAAa;KAC5B,KAAc,KAAK,EAAa,IAAI,CAAU,MAClD,EAAa,IAAI,CAAU,GAC3B,EAAc,KAAK,CAAY;IAChC;GACD;GAkBA,AAhBI,EAAgB,SAAS,KAC5B,EAAO,KAAK;IACX,MAAM;IACN,OAAO;IACP,SAAS;IACT,KAAK;GACN,CAAC,GAEE,EAAuB,SAAS,KACnC,EAAO,KAAK;IACX,MAAM;IACN,OAAO;IACP,SAAS;IACT,KAAK;GACN,CAAC,GAEE,EAAsB,SAAS,KAClC,EAAO,KAAK;IACX,MAAM;IACN,OAAO;IACP,SAAS;IACT,KAAK;GACN,CAAC;GAGF,IAAI,IAAqC,CAAC;GAC1C,IAAI,EAAK,sBAAsB;IAC9B,IAAM,oBAAkB,IAAI,IAAY,GAClC,IAA2B,CAAC;IAClC,KAAK,IAAM,KAAQ,CAAC,GAAG,GAAS,GAAG,CAAa,GAC/C,AAAI,EAAK,KAAK,KAAK,CAAC,EAAgB,IAAI,EAAK,EAAE,MAC9C,EAAgB,IAAI,EAAK,EAAE,GAC3B,EAAe,KAAK,EAAK,EAAE;IAG7B,IAAe,EAAc,GAAO,GAAgB,CAAO;GAC5D;GAEA,OAAO,EAAY;IAClB;IACA,UAAU;IACV;IACA,aAAa,EAAW,QACtB,MACA,EAAgB,SAAS,CAAQ,KACjC,EAAuB,SAAS,CAAQ,KACxC,EAAsB,SAAS,CAAQ,CACzC;IACA;IACA,UAAU;KACT,SAAS;KACT,qBAAqB,EAAW;KAChC,uBAAuB,EAAQ;KAC/B,gBAAgB,EAAc;KAC9B,sBAAsB,EAAK;IAC5B;GACD,CAAC;EACF,SAAS,GAAK;GACb,OAAO,EAAa,aAAe,QAAQ,EAAI,UAAU,OAAO,CAAG,CAAC;EACrE;CACD,CACD;AACD;;;AClLA,SAAgB,EACf,GACA,IAAmC,CAAC,GACxB;CACZ,IAAM,IAAS,IAAI,EAAU;EAAE,MAAM;EAAW,SAAS;CAAQ,CAAC,GAC5D,IAAmC;EACxC;EAGA,sBACK,EAAQ,wBAA8B,EAAQ,sBAAsB,IACpE,EAAQ,mBAAmB,KAAA,IACxB,EAAsB,IADoB,EAAQ;EAG1D,kBACC,EAAQ,eAAe,KAAA,IAAkC,QAAQ,IAAI,mBAAmB,OAArD,EAAQ;CAC7C;CAQA,OANA,EAAoB,GAAQ,CAAO,GACnC,EAAsB,GAAQ,CAAO,GACrC,EAAkB,GAAQ,CAAO,GACjC,EAAoB,CAAM,GAC1B,EAAmB,CAAM,GAElB;AACR"}