kimi-code-memory-mcp-server 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/CHANGELOG.md +28 -1
  2. package/README.en.md +349 -0
  3. package/README.md +223 -137
  4. package/assets/contextFlow.svg +144 -0
  5. package/dist/config.d.ts +13 -0
  6. package/dist/config.js +13 -0
  7. package/dist/config.js.map +1 -1
  8. package/dist/context/wire-context.d.ts +3 -0
  9. package/dist/context/wire-context.js +20 -50
  10. package/dist/context/wire-context.js.map +1 -1
  11. package/dist/dao/constants.d.ts +33 -0
  12. package/dist/dao/constants.js +17 -0
  13. package/dist/dao/constants.js.map +1 -0
  14. package/dist/dao/index-catalog.d.ts +19 -0
  15. package/dist/dao/index-catalog.js +94 -0
  16. package/dist/dao/index-catalog.js.map +1 -0
  17. package/dist/dao/index-reconciler.d.ts +13 -0
  18. package/dist/dao/index-reconciler.js +162 -0
  19. package/dist/dao/index-reconciler.js.map +1 -0
  20. package/dist/dao/index-store.d.ts +31 -0
  21. package/dist/dao/index-store.js +128 -0
  22. package/dist/dao/index-store.js.map +1 -0
  23. package/dist/dao/index.d.ts +12 -31
  24. package/dist/dao/index.js +50 -404
  25. package/dist/dao/index.js.map +1 -1
  26. package/dist/dao/memory-store.js +2 -10
  27. package/dist/dao/memory-store.js.map +1 -1
  28. package/dist/dao/memory-tree-renderer.d.ts +22 -0
  29. package/dist/dao/memory-tree-renderer.js +75 -0
  30. package/dist/dao/memory-tree-renderer.js.map +1 -0
  31. package/dist/prompts/index.d.ts +26 -0
  32. package/dist/prompts/index.js +103 -0
  33. package/dist/prompts/index.js.map +1 -0
  34. package/dist/refine/adapter.d.ts +6 -0
  35. package/dist/refine/adapter.js +28 -0
  36. package/dist/refine/adapter.js.map +1 -0
  37. package/dist/refine/constants.d.ts +35 -0
  38. package/dist/refine/constants.js +107 -0
  39. package/dist/refine/constants.js.map +1 -0
  40. package/dist/refine/extractor.d.ts +12 -0
  41. package/dist/refine/extractor.js +122 -0
  42. package/dist/refine/extractor.js.map +1 -0
  43. package/dist/refine/store.d.ts +23 -0
  44. package/dist/refine/store.js +153 -0
  45. package/dist/refine/store.js.map +1 -0
  46. package/dist/refine/types.d.ts +56 -0
  47. package/dist/refine/types.js +5 -0
  48. package/dist/refine/types.js.map +1 -0
  49. package/dist/refined-manager.d.ts +14 -56
  50. package/dist/refined-manager.js +27 -341
  51. package/dist/refined-manager.js.map +1 -1
  52. package/dist/resources/index.d.ts +15 -0
  53. package/dist/resources/index.js +134 -0
  54. package/dist/resources/index.js.map +1 -0
  55. package/dist/server.js +46 -2
  56. package/dist/server.js.map +1 -1
  57. package/dist/theme-manager.d.ts +1 -0
  58. package/dist/theme-manager.js +7 -0
  59. package/dist/theme-manager.js.map +1 -1
  60. package/dist/tools/context-tools.d.ts +16 -51
  61. package/dist/tools/context-tools.js +303 -55
  62. package/dist/tools/context-tools.js.map +1 -1
  63. package/dist/tools/index.d.ts +5 -827
  64. package/dist/tools/index.js +23 -354
  65. package/dist/tools/index.js.map +1 -1
  66. package/dist/tools/memory-tools.d.ts +4 -60
  67. package/dist/tools/memory-tools.js +129 -79
  68. package/dist/tools/memory-tools.js.map +1 -1
  69. package/dist/tools/system-tools.d.ts +3 -34
  70. package/dist/tools/system-tools.js +110 -33
  71. package/dist/tools/system-tools.js.map +1 -1
  72. package/dist/tools/theme-tools.d.ts +3 -31
  73. package/dist/tools/theme-tools.js +101 -22
  74. package/dist/tools/theme-tools.js.map +1 -1
  75. package/dist/tools/types.d.ts +21 -0
  76. package/dist/tools/types.js +13 -0
  77. package/dist/tools/types.js.map +1 -0
  78. package/dist/types.d.ts +11 -2
  79. package/dist/utils/action-entities.d.ts +16 -0
  80. package/dist/utils/action-entities.js +35 -0
  81. package/dist/utils/action-entities.js.map +1 -0
  82. package/dist/utils/date.d.ts +11 -0
  83. package/dist/utils/date.js +13 -0
  84. package/dist/utils/date.js.map +1 -0
  85. package/dist/utils/file-helpers.d.ts +10 -0
  86. package/dist/utils/file-helpers.js +28 -0
  87. package/dist/utils/file-helpers.js.map +1 -0
  88. package/dist/utils/headings.d.ts +5 -0
  89. package/dist/utils/headings.js +21 -0
  90. package/dist/utils/headings.js.map +1 -0
  91. package/dist/utils/search.d.ts +17 -0
  92. package/dist/utils/search.js +60 -0
  93. package/dist/utils/search.js.map +1 -0
  94. package/dist/utils/tools.d.ts +5 -0
  95. package/dist/utils/tools.js +10 -0
  96. package/dist/utils/tools.js.map +1 -0
  97. package/dist/version.d.ts +1 -1
  98. package/dist/version.js +1 -1
  99. package/dist/vis/api.d.ts +117 -0
  100. package/dist/vis/api.js +426 -0
  101. package/dist/vis/api.js.map +1 -0
  102. package/dist/vis/auto-start.d.ts +12 -0
  103. package/dist/vis/auto-start.js +87 -0
  104. package/dist/vis/auto-start.js.map +1 -0
  105. package/dist/vis/server.d.ts +14 -0
  106. package/dist/vis/server.js +337 -0
  107. package/dist/vis/server.js.map +1 -0
  108. package/dist/vis/static/api.js +57 -0
  109. package/dist/vis/static/app.js +1468 -0
  110. package/dist/vis/static/index.html +25 -0
  111. package/dist/vis/static/state.js +26 -0
  112. package/dist/vis/static/style.css +1553 -0
  113. package/dist/vis/static/utils/helpers.js +94 -0
  114. package/dist/vis/static/utils/markdown.js +81 -0
  115. package/dist/vis-cli.d.ts +7 -0
  116. package/dist/vis-cli.js +140 -0
  117. package/dist/vis-cli.js.map +1 -0
  118. package/docs/0.agent-memory-market-research.md +354 -0
  119. package/docs/1.memory-system-proposal-for-kimi-code.md +688 -0
  120. package/docs/2.memory-architecture-overview.md +417 -0
  121. package/docs/3.memory-skill-prompt-design.md +430 -0
  122. package/docs/4.kimi-code-native-evolution-roadmap.md +559 -0
  123. package/docs/5.decision-guard-design-notes.md +500 -0
  124. package/docs/ARCHITECTURE.md +2 -2
  125. package/docs/design-story.md +350 -0
  126. package/docs/three-layer-memory-model.md +153 -0
  127. package/docs/three-layer-memory-model.zh-CN.md +153 -0
  128. package/package.json +12 -6
  129. package/README.zh-CN.md +0 -292
@@ -1,369 +1,55 @@
1
1
  /**
2
- * Refined turn storage and extraction backed by SQLite.
2
+ * Refined turn orchestrator.
3
3
  *
4
- * Refined turns are a local derived index / cache of conversation wires.
5
- * They are not user-facing memory assets; user memory stays in Markdown files.
6
- *
7
- * Extraction rules are intentionally local and deterministic: we look for
8
- * explicit structural cues (list items, action-keywords, headings) rather than
9
- * calling an LLM. This keeps the operation fast, free, and reproducible across
10
- * Chinese and English agent outputs.
4
+ * Delegates extraction, storage, and row mapping to focused modules under
5
+ * src/refine/. This file keeps the original public API and owns cross-cutting
6
+ * concerns such as the write mutex.
11
7
  */
12
- import fs from 'fs';
13
- import path from 'path';
14
- import Database from 'better-sqlite3';
15
8
  import { Mutex } from './utils/mutex.js';
16
- /** Action / conclusion keywords in both English and Chinese. */
17
- const ACTION_KEYWORDS = [
18
- // English - past tense / conclusions
19
- 'Implemented',
20
- 'Refactored',
21
- 'Confirmed',
22
- 'Completed',
23
- 'Decided',
24
- 'Changed',
25
- 'Updated',
26
- 'Removed',
27
- 'Fixed',
28
- 'Added',
29
- 'Done',
30
- // English - planning / status
31
- 'Next step',
32
- 'Next',
33
- 'Blocker',
34
- 'Blocked by',
35
- 'Blocked',
36
- 'Result',
37
- 'Results',
38
- 'Summary',
39
- 'Status',
40
- 'Objective',
41
- 'Plan',
42
- 'Goal',
43
- 'Action',
44
- 'Actions',
45
- 'Note',
46
- 'Notes',
47
- // Chinese - past tense / conclusions
48
- '已完成',
49
- '完成',
50
- '修复了',
51
- '修复',
52
- '添加了',
53
- '添加',
54
- '删除了',
55
- '删除',
56
- '更新了',
57
- '更新',
58
- '决定了',
59
- '决定',
60
- '确认了',
61
- '确认',
62
- '实现了',
63
- '实现',
64
- '重构了',
65
- '重构',
66
- // Chinese - planning / status
67
- '下一步',
68
- '阻塞项',
69
- '阻塞',
70
- '被阻塞',
71
- '原因',
72
- '结果',
73
- '状态',
74
- '注意',
75
- '计划',
76
- '目标',
77
- '行动',
78
- '备注',
79
- ];
80
- /** Markdown headings that group the following list items into categories. */
81
- const CATEGORY_HEADINGS = {
82
- focus: ['Current Focus', '当前任务', '当前聚焦', 'Focus'],
83
- completed: ['Completed', 'Done', '已完成', '完成'],
84
- next: ['Next Steps', 'Next', '下一步', '后续'],
85
- blockers: ['Blockers', 'Blocked', '阻塞', '阻塞项', 'Blocked by'],
86
- status: ['Status', '当前状态', '状态'],
87
- summary: ['Summary', '总结', '摘要'],
88
- decisions: ['Decisions', '决定', '决策'],
89
- notes: ['Notes', '备注', 'Note'],
90
- };
91
- function buildActionRegex() {
92
- // Sort longer phrases first so "Next step" wins over "Next".
93
- const sorted = [...ACTION_KEYWORDS].sort((a, b) => b.length - a.length);
94
- const escaped = sorted.map((k) => k.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
95
- // Support both English colon and Chinese full-width colon, optional whitespace.
96
- return new RegExp(`^(?:${escaped.join('|')})(:|:)?\\s*`, 'i');
97
- }
98
- const ACTION_REGEX = buildActionRegex();
99
- const HEADING_REGEX = /^(#{1,6})\s+(.+?)(?:\s+[::])?\s*$/;
100
- function normalizeHeading(text) {
101
- return text.trim().replace(/[::]\s*$/g, '');
102
- }
103
- function matchCategory(heading) {
104
- const normalized = normalizeHeading(heading).toLowerCase();
105
- for (const [category, labels] of Object.entries(CATEGORY_HEADINGS)) {
106
- for (const label of labels) {
107
- if (normalized === label.toLowerCase())
108
- return category;
109
- // Also match "## Current Focus" style where label might be embedded.
110
- if (normalized.includes(label.toLowerCase()))
111
- return category;
112
- }
113
- }
114
- return null;
115
- }
116
- function isSentenceLike(text) {
117
- if (text.length < 10 || text.length > 200)
118
- return false;
119
- // End with sentence terminator or colon.
120
- return /[.。!!??::]$/.test(text);
121
- }
122
- function pickAgentLead(agentText) {
123
- const first = agentText.split(/\r?\n/).find((line) => line.trim().length > 0);
124
- if (!first)
125
- return null;
126
- const trimmed = first.trim();
127
- return trimmed.length > 0 && trimmed.length <= 120 && !trimmed.startsWith('#')
128
- ? trimmed
129
- : null;
130
- }
9
+ import { RefinedStore } from './refine/store.js';
10
+ import { extract } from './refine/extractor.js';
131
11
  export class RefinedManager {
132
12
  refinedRoot;
133
- dbPath;
134
- db;
13
+ store;
135
14
  mutex;
136
15
  constructor(refinedRoot) {
137
16
  this.refinedRoot = refinedRoot;
138
- this.dbPath = path.join(refinedRoot, 'refined.sqlite');
139
- fs.mkdirSync(refinedRoot, { recursive: true });
140
- this.db = new Database(this.dbPath);
17
+ this.store = new RefinedStore(refinedRoot);
141
18
  this.mutex = new Mutex();
142
- this.initDb();
143
- }
144
- initDb() {
145
- this.db.exec(`
146
- CREATE TABLE IF NOT EXISTS refined_turns (
147
- session_id TEXT NOT NULL,
148
- turn_id INTEGER NOT NULL,
149
- timestamp TEXT,
150
- summary TEXT,
151
- facts TEXT,
152
- notes TEXT,
153
- entities TEXT,
154
- categories TEXT,
155
- PRIMARY KEY (session_id, turn_id)
156
- );
157
- CREATE INDEX IF NOT EXISTS idx_refined_session ON refined_turns(session_id);
158
- CREATE INDEX IF NOT EXISTS idx_refined_timestamp ON refined_turns(timestamp);
159
- `);
160
19
  }
161
20
  refineTurn(turn, sessionId) {
162
- const files = new Set();
163
- const tools = new Set();
164
- const errors = new Set();
165
- for (const action of turn.actions || []) {
166
- if (action.name)
167
- tools.add(action.name);
168
- const args = typeof action.args === 'object' && action.args !== null
169
- ? action.args
170
- : {};
171
- for (const key of ['path', 'file', 'filePath', 'cwd']) {
172
- const value = args[key];
173
- if (typeof value === 'string') {
174
- if (key === 'cwd' && value.includes('node_modules'))
175
- continue;
176
- files.add(value);
177
- }
178
- }
179
- const result = action.result || '';
180
- if (typeof result === 'string' &&
181
- (result.toLowerCase().includes('error') || result.toLowerCase().includes('failed'))) {
182
- errors.add(result.split('\n')[0].slice(0, 200));
183
- }
184
- }
185
- const userText = (turn.user || '').slice(0, 200).trim();
186
- const toolNames = Array.from(tools);
187
- const agentText = turn.agentText || turn.agent || '';
188
- const agentLead = pickAgentLead(agentText);
189
- let summary = userText;
190
- if (toolNames.length > 0) {
191
- summary = `${userText ? `${userText} · ` : ''}${toolNames.join(', ')}`;
192
- }
193
- if (agentLead && agentLead !== userText) {
194
- summary = summary ? `${summary} · ${agentLead}` : agentLead;
195
- }
196
- const facts = [];
197
- const notes = [];
198
- const categories = {};
199
- let currentCategory = null;
200
- const lines = String(agentText).split(/\r?\n/);
201
- for (const rawLine of lines) {
202
- const line = rawLine.trim();
203
- if (!line) {
204
- currentCategory = null;
205
- continue;
206
- }
207
- // Markdown / Chinese heading detection.
208
- const headingMatch = line.match(HEADING_REGEX);
209
- if (headingMatch) {
210
- currentCategory = matchCategory(headingMatch[2]);
211
- continue;
212
- }
213
- let extracted = null;
214
- // List item.
215
- if (line.startsWith('- ') || line.startsWith('* ')) {
216
- extracted = line.slice(2).trim();
217
- }
218
- // Numbered list item like "1. xxx" or "1) xxx".
219
- else if (/^(\d+)[.)]\s+/.test(line)) {
220
- extracted = line.replace(/^\d+[.)]\s+/, '').trim();
221
- }
222
- // Action / conclusion sentence.
223
- else {
224
- const actionMatch = line.match(ACTION_REGEX);
225
- if (actionMatch) {
226
- extracted = line.slice(actionMatch[0].length).trim();
227
- }
228
- }
229
- if (extracted) {
230
- const item = extracted;
231
- if (currentCategory) {
232
- (categories[currentCategory] ||= []).push(item);
233
- }
234
- facts.push(item);
235
- }
236
- else if (isSentenceLike(line)) {
237
- // Fallback: keep short declarative sentences that did not match keywords.
238
- notes.push(line);
239
- }
240
- }
241
- return {
242
- sessionId,
243
- turnId: parseInt(String(turn.turnId), 10),
244
- timestamp: turn.timestamp,
245
- summary,
246
- facts: facts.slice(0, 8),
247
- notes: notes.slice(0, 8),
248
- entities: {
249
- files: Array.from(files).slice(0, 10),
250
- tools: toolNames.slice(0, 10),
251
- errors: Array.from(errors).slice(0, 5),
252
- },
253
- categories,
254
- };
255
- }
256
- rowToTurn(row) {
257
- return {
258
- sessionId: row.session_id,
259
- turnId: row.turn_id,
260
- timestamp: row.timestamp ?? undefined,
261
- summary: row.summary,
262
- facts: JSON.parse(row.facts || '[]'),
263
- notes: JSON.parse(row.notes || '[]'),
264
- entities: JSON.parse(row.entities || '{"files":[],"tools":[],"errors":[]}'),
265
- categories: JSON.parse(row.categories || '{}'),
266
- };
21
+ return extract(turn, sessionId);
267
22
  }
268
23
  async saveRefinedTurns(sessionId, refinedTurns) {
269
24
  return this.mutex.runExclusive(() => {
270
- const insert = this.db.prepare(`INSERT OR REPLACE INTO refined_turns
271
- (session_id, turn_id, timestamp, summary, facts, notes, entities, categories)
272
- VALUES (?, ?, ?, ?, ?, ?, ?, ?)`);
273
- const existing = this.loadRefinedTurnsSync(sessionId);
274
- const merged = new Map(existing.map((t) => [t.turnId, t]));
275
- for (const turn of refinedTurns) {
276
- merged.set(turn.turnId, turn);
277
- }
278
- const transaction = this.db.transaction(() => {
279
- for (const turn of merged.values()) {
280
- insert.run(turn.sessionId, turn.turnId, turn.timestamp ?? null, turn.summary, JSON.stringify(turn.facts), JSON.stringify(turn.notes), JSON.stringify(turn.entities), JSON.stringify(turn.categories));
281
- }
282
- });
283
- transaction();
25
+ this.store.saveRefinedTurns(sessionId, refinedTurns);
284
26
  });
285
27
  }
286
28
  loadRefinedTurns(sessionId) {
287
- return this.loadRefinedTurnsSync(sessionId);
29
+ return this.store.loadRefinedTurns(sessionId);
288
30
  }
289
- loadRefinedTurnsSync(sessionId) {
290
- const stmt = this.db.prepare('SELECT * FROM refined_turns WHERE session_id = ? ORDER BY turn_id');
291
- const rows = stmt.all(sessionId);
292
- return rows.map((r) => this.rowToTurn(r));
31
+ loadRefinedTurn(sessionId, turnId) {
32
+ return this.store.loadRefinedTurn(sessionId, turnId);
293
33
  }
294
34
  getDbPath() {
295
- return this.dbPath;
296
- }
297
- loadRefinedTurn(sessionId, turnId) {
298
- const stmt = this.db.prepare('SELECT * FROM refined_turns WHERE session_id = ? AND turn_id = ?');
299
- const row = stmt.get(sessionId, turnId);
300
- return row ? this.rowToTurn(row) : undefined;
35
+ return this.store.getDbPath();
301
36
  }
302
37
  searchRefinedTurns(options) {
303
- const rawQuery = typeof options.query === 'string' ? options.query.trim() : '';
304
- if (!rawQuery)
305
- return [];
306
- const terms = rawQuery
307
- .toLowerCase()
308
- .split(/\s+/)
309
- .filter((t) => t.length > 0);
310
- if (terms.length === 0)
311
- return [];
312
- const limit = typeof options.limit === 'number' ? Math.max(1, Math.floor(options.limit)) : 100;
313
- const dateFrom = options.dateFrom || null;
314
- const dateTo = options.dateTo || null;
315
- const conditions = [];
316
- const params = [];
317
- for (const term of terms) {
318
- const escaped = term.split('%').join('\\%').split('_').join('\\_');
319
- const like = `%${escaped}%`;
320
- conditions.push("(summary LIKE ? ESCAPE '\\' OR facts LIKE ? ESCAPE '\\' OR notes LIKE ? ESCAPE '\\')");
321
- params.push(like, like, like);
322
- }
323
- if (dateFrom) {
324
- conditions.push('timestamp >= ?');
325
- params.push(`${dateFrom}T00:00:00.000Z`);
326
- }
327
- if (dateTo) {
328
- conditions.push('timestamp <= ?');
329
- params.push(`${dateTo}T23:59:59.999Z`);
330
- }
331
- const sql = `SELECT session_id, turn_id, timestamp, summary, facts, notes
332
- FROM refined_turns
333
- WHERE ${conditions.join(' AND ')}
334
- ORDER BY timestamp DESC
335
- LIMIT ?`;
336
- params.push(limit * 4);
337
- const stmt = this.db.prepare(sql);
338
- const rows = stmt.all(...params);
339
- const matches = [];
340
- for (const row of rows) {
341
- const haystack = `${row.summary}\n${row.facts}\n${row.notes}`.toLowerCase();
342
- let score = 0;
343
- for (const term of terms) {
344
- const pattern = term.replace(/[.*+?^${}()|[\]\\]/g, (ch) => `\\${ch}`);
345
- const re = new RegExp(pattern, 'gi');
346
- const m = haystack.match(re);
347
- if (m)
348
- score += m.length;
349
- }
350
- if (score === 0)
351
- continue;
352
- matches.push({
353
- sessionId: row.session_id,
354
- turnId: row.turn_id,
355
- timestamp: row.timestamp ?? undefined,
356
- summary: row.summary,
357
- facts: JSON.parse(row.facts || '[]'),
358
- notes: JSON.parse(row.notes || '[]'),
359
- score,
360
- });
361
- }
362
- matches.sort((a, b) => b.score - a.score);
363
- return matches.slice(0, limit);
38
+ return this.store.searchRefinedTurns(options);
39
+ }
40
+ countAll() {
41
+ return this.store.countAll();
42
+ }
43
+ listRecentTurns(limit) {
44
+ return this.store.listRecentTurns(limit);
45
+ }
46
+ async deleteRefinedTurns(refs) {
47
+ return this.mutex.runExclusive(() => {
48
+ return this.store.deleteRefinedTurns(refs);
49
+ });
364
50
  }
365
51
  close() {
366
- this.db.close();
52
+ this.store.close();
367
53
  }
368
54
  }
369
55
  //# sourceMappingURL=refined-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"refined-manager.js","sourceRoot":"","sources":["../src/refined-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"refined-manager.js","sourceRoot":"","sources":["../src/refined-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAgBhD,MAAM,OAAO,cAAc;IACzB,WAAW,CAAS;IACZ,KAAK,CAAe;IACpB,KAAK,CAAQ;IAErB,YAAY,WAAmB;QAC7B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,KAAK,GAAG,IAAI,YAAY,CAAC,WAAW,CAAC,CAAC;QAC3C,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;IAC3B,CAAC;IAED,UAAU,CAAC,IAAa,EAAE,SAAiB;QACzC,OAAO,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAClC,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,SAAiB,EAAE,YAA2B;QACnE,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE;YAClC,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;QACvD,CAAC,CAAC,CAAC;IACL,CAAC;IAED,gBAAgB,CAAC,SAAiB;QAChC,OAAO,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAChD,CAAC;IAED,eAAe,CAAC,SAAiB,EAAE,MAAc;QAC/C,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACvD,CAAC;IAED,SAAS;QACP,OAAO,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC;IAChC,CAAC;IAED,kBAAkB,CAAC,OAA6B;QAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAC/B,CAAC;IAED,eAAe,CAAC,KAAa;QAC3B,OAAO,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,IAAkD;QACzE,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,GAAG,EAAE;YAClC,OAAO,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * MCP Resources for the Kimi Code Memory server.
3
+ *
4
+ * Resources expose workspace memory files, themes, and the workspace essence
5
+ * as addressable URIs that clients can read through the MCP protocol.
6
+ */
7
+ import type { Resource, TextResourceContents } from '@modelcontextprotocol/sdk/types.js';
8
+ import type { Ctx } from '../types.js';
9
+ export interface ResourceProvider {
10
+ resources: () => Resource[];
11
+ readResource: (uri: string) => {
12
+ contents: TextResourceContents[];
13
+ };
14
+ }
15
+ export declare function createResources(ctx: Ctx): ResourceProvider;
@@ -0,0 +1,134 @@
1
+ /**
2
+ * MCP Resources for the Kimi Code Memory server.
3
+ *
4
+ * Resources expose workspace memory files, themes, and the workspace essence
5
+ * as addressable URIs that clients can read through the MCP protocol.
6
+ */
7
+ import fs from 'fs';
8
+ import path from 'path';
9
+ export function createResources(ctx) {
10
+ function listMemoryResources() {
11
+ const refs = ctx.indexDao.listRefs().filter((ref) => ref.folder.startsWith('memory/'));
12
+ return refs.map((ref) => ({
13
+ uri: `memory://${ref.folder}/${ref.key}`,
14
+ name: ref.title || ref.key,
15
+ mimeType: 'text/markdown',
16
+ description: `Memory in ${ref.folder}${ref.tags.length ? ` (tags: ${ref.tags.join(', ')})` : ''}`,
17
+ }));
18
+ }
19
+ function listThemeResources() {
20
+ return ctx.themeManager.listThemes().map((theme) => ({
21
+ uri: `theme://${theme}`,
22
+ name: theme,
23
+ mimeType: 'text/markdown',
24
+ description: `Theme association summary for "${theme}"`,
25
+ }));
26
+ }
27
+ function listEssenceResource() {
28
+ const essencePath = path.join(ctx.storeRoot, 'essence', 'essence.md');
29
+ if (!fs.existsSync(essencePath))
30
+ return [];
31
+ return [
32
+ {
33
+ uri: 'essence://essence',
34
+ name: 'Workspace Essence',
35
+ mimeType: 'text/markdown',
36
+ description: 'Condensed workspace essence derived from memory.',
37
+ },
38
+ ];
39
+ }
40
+ function resources() {
41
+ return [...listMemoryResources(), ...listThemeResources(), ...listEssenceResource()];
42
+ }
43
+ function readMemoryResource(uri, folder, key) {
44
+ const result = ctx.memoryStore.read(folder, key);
45
+ if (!result) {
46
+ throw new Error(`Memory resource not found: ${uri}`);
47
+ }
48
+ return [
49
+ {
50
+ uri,
51
+ mimeType: 'text/markdown',
52
+ text: result.content,
53
+ },
54
+ ];
55
+ }
56
+ function readThemeResource(uri, theme) {
57
+ const association = ctx.themeManager.loadTheme(theme);
58
+ if (!association) {
59
+ throw new Error(`Theme resource not found: ${uri}`);
60
+ }
61
+ const lines = [
62
+ `# Theme: ${association.displayName || association.theme}`,
63
+ '',
64
+ `- Created: ${association.createdAt}`,
65
+ `- Updated: ${association.updatedAt}`,
66
+ `- Memories: ${association.memories.length}`,
67
+ `- Turns: ${association.turns.length}`,
68
+ '',
69
+ '## Memories',
70
+ ];
71
+ if (association.memories.length === 0) {
72
+ lines.push('_No memories associated yet._');
73
+ }
74
+ else {
75
+ for (const memory of association.memories) {
76
+ lines.push(`- ${memory.folder}/${memory.key} (${memory.title})`);
77
+ }
78
+ }
79
+ lines.push('', '## Turns');
80
+ if (association.turns.length === 0) {
81
+ lines.push('_No turns associated yet._');
82
+ }
83
+ else {
84
+ for (const turn of association.turns) {
85
+ lines.push(`- Session ${turn.sessionId}, turn ${turn.turnId} (${turn.timestamp})`);
86
+ }
87
+ }
88
+ return [
89
+ {
90
+ uri,
91
+ mimeType: 'text/markdown',
92
+ text: lines.join('\n'),
93
+ },
94
+ ];
95
+ }
96
+ function readEssenceResource(uri) {
97
+ const essencePath = path.join(ctx.storeRoot, 'essence', 'essence.md');
98
+ if (!fs.existsSync(essencePath)) {
99
+ throw new Error(`Essence resource not found: ${uri}`);
100
+ }
101
+ return [
102
+ {
103
+ uri,
104
+ mimeType: 'text/markdown',
105
+ text: fs.readFileSync(essencePath, 'utf8'),
106
+ },
107
+ ];
108
+ }
109
+ function readResource(uri) {
110
+ if (uri.startsWith('memory://')) {
111
+ const rest = uri.slice('memory://'.length);
112
+ const lastSlash = rest.lastIndexOf('/');
113
+ if (lastSlash <= 0) {
114
+ throw new Error(`Invalid memory resource URI: ${uri}`);
115
+ }
116
+ const folder = rest.slice(0, lastSlash);
117
+ const key = rest.slice(lastSlash + 1);
118
+ return { contents: readMemoryResource(uri, folder, key) };
119
+ }
120
+ if (uri.startsWith('theme://')) {
121
+ const theme = uri.slice('theme://'.length);
122
+ if (!theme) {
123
+ throw new Error(`Invalid theme resource URI: ${uri}`);
124
+ }
125
+ return { contents: readThemeResource(uri, theme) };
126
+ }
127
+ if (uri === 'essence://essence') {
128
+ return { contents: readEssenceResource(uri) };
129
+ }
130
+ throw new Error(`Unsupported resource URI scheme: ${uri}`);
131
+ }
132
+ return { resources, readResource };
133
+ }
134
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/resources/index.ts"],"names":[],"mappings":"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"}
package/dist/server.js CHANGED
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
9
9
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
- import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
10
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
11
11
  import fs from 'fs';
12
12
  import path from 'path';
13
13
  import { getStoreRoot } from './config.js';
@@ -17,7 +17,10 @@ import { MemoryStore } from './dao/memory-store.js';
17
17
  import { ThemeManager } from './theme-manager.js';
18
18
  import { RefinedManager } from './refined-manager.js';
19
19
  import { createTools } from './tools/index.js';
20
+ import { prompts, getPrompt } from './prompts/index.js';
21
+ import { createResources } from './resources/index.js';
20
22
  import { VERSION } from './version.js';
23
+ import { maybeStartVisServer, stopVisServer } from './vis/auto-start.js';
21
24
  const cwd = process.cwd().replace(/\\/g, '/');
22
25
  const workspaceId = computeWorkspaceId(cwd);
23
26
  const storeRoot = path.join(getStoreRoot(), workspaceId);
@@ -39,7 +42,14 @@ const ctx = {
39
42
  refinedManager,
40
43
  };
41
44
  const tools = createTools(ctx);
42
- const server = new Server({ name: 'kimi-code-memory', version: VERSION }, { capabilities: { tools: {} } });
45
+ const resources = createResources(ctx);
46
+ const server = new Server({ name: 'kimi-code-memory', version: VERSION }, {
47
+ capabilities: {
48
+ tools: {},
49
+ prompts: {},
50
+ resources: { list: true, subscribe: false },
51
+ },
52
+ });
43
53
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
44
54
  tools: tools.toolSchemas,
45
55
  }));
@@ -59,10 +69,44 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
59
69
  };
60
70
  }
61
71
  });
72
+ server.setRequestHandler(ListPromptsRequestSchema, async () => ({
73
+ prompts,
74
+ }));
75
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
76
+ const name = request.params.name;
77
+ const args = request.params.arguments || {};
78
+ return getPrompt(name, args);
79
+ });
80
+ server.setRequestHandler(ListResourcesRequestSchema, async () => ({
81
+ resources: resources.resources(),
82
+ }));
83
+ server.setRequestHandler(ReadResourceRequestSchema, async (request) => resources.readResource(request.params.uri));
62
84
  async function main() {
63
85
  const transport = new StdioServerTransport();
64
86
  await server.connect(transport);
87
+ const visResult = await maybeStartVisServer(ctx);
88
+ if (visResult.started && visResult.url) {
89
+ process.stderr.write(`[kimi-memory] vis dashboard ready at ${visResult.url}\n`);
90
+ try {
91
+ const { default: openBrowser } = await import('open');
92
+ await openBrowser(visResult.url);
93
+ }
94
+ catch {
95
+ // Browser may not be available in headless/server environments; ignore.
96
+ }
97
+ }
98
+ else if (visResult.error) {
99
+ process.stderr.write(`[kimi-memory] vis dashboard failed to start: ${visResult.error}\n`);
100
+ }
65
101
  }
102
+ process.on('SIGINT', () => {
103
+ stopVisServer();
104
+ process.exit(0);
105
+ });
106
+ process.on('SIGTERM', () => {
107
+ stopVisServer();
108
+ process.exit(0);
109
+ });
66
110
  main().catch((err) => {
67
111
  const message = err instanceof Error ? err.message : String(err);
68
112
  process.stderr.write(`Fatal error: ${message}\n`);