kimi-code-memory-mcp-server 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/AGENTS.md +144 -0
  2. package/CHANGELOG.md +26 -0
  3. package/LICENSE +21 -0
  4. package/README.md +227 -0
  5. package/README.zh-CN.md +227 -0
  6. package/dist/config.d.ts +36 -0
  7. package/dist/config.js +63 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/context/wire-context.d.ts +171 -0
  10. package/dist/context/wire-context.js +586 -0
  11. package/dist/context/wire-context.js.map +1 -0
  12. package/dist/dao/index.d.ts +76 -0
  13. package/dist/dao/index.js +490 -0
  14. package/dist/dao/index.js.map +1 -0
  15. package/dist/dao/memory-store.d.ts +24 -0
  16. package/dist/dao/memory-store.js +112 -0
  17. package/dist/dao/memory-store.js.map +1 -0
  18. package/dist/refined-manager.d.ts +70 -0
  19. package/dist/refined-manager.js +369 -0
  20. package/dist/refined-manager.js.map +1 -0
  21. package/dist/server.d.ts +8 -0
  22. package/dist/server.js +71 -0
  23. package/dist/server.js.map +1 -0
  24. package/dist/theme-manager.d.ts +40 -0
  25. package/dist/theme-manager.js +88 -0
  26. package/dist/theme-manager.js.map +1 -0
  27. package/dist/tools/context-tools.d.ts +56 -0
  28. package/dist/tools/context-tools.js +332 -0
  29. package/dist/tools/context-tools.js.map +1 -0
  30. package/dist/tools/index.d.ts +835 -0
  31. package/dist/tools/index.js +370 -0
  32. package/dist/tools/index.js.map +1 -0
  33. package/dist/tools/memory-tools.d.ts +62 -0
  34. package/dist/tools/memory-tools.js +292 -0
  35. package/dist/tools/memory-tools.js.map +1 -0
  36. package/dist/tools/system-tools.d.ts +37 -0
  37. package/dist/tools/system-tools.js +195 -0
  38. package/dist/tools/system-tools.js.map +1 -0
  39. package/dist/tools/theme-tools.d.ts +34 -0
  40. package/dist/tools/theme-tools.js +186 -0
  41. package/dist/tools/theme-tools.js.map +1 -0
  42. package/dist/types.d.ts +93 -0
  43. package/dist/types.js +5 -0
  44. package/dist/types.js.map +1 -0
  45. package/dist/utils/frontmatter.d.ts +10 -0
  46. package/dist/utils/frontmatter.js +61 -0
  47. package/dist/utils/frontmatter.js.map +1 -0
  48. package/dist/utils/mutex.d.ts +11 -0
  49. package/dist/utils/mutex.js +17 -0
  50. package/dist/utils/mutex.js.map +1 -0
  51. package/dist/utils/paths.d.ts +19 -0
  52. package/dist/utils/paths.js +54 -0
  53. package/dist/utils/paths.js.map +1 -0
  54. package/dist/utils/validation.d.ts +15 -0
  55. package/dist/utils/validation.js +40 -0
  56. package/dist/utils/validation.js.map +1 -0
  57. package/dist/version.d.ts +9 -0
  58. package/dist/version.js +10 -0
  59. package/dist/version.js.map +1 -0
  60. package/docs/ARCHITECTURE.md +144 -0
  61. package/docs/CONTRIBUTING.md +83 -0
  62. package/docs/CONTRIBUTING.zh-CN.md +83 -0
  63. package/docs/search-logic.md +157 -0
  64. package/docs/search-logic.zh-CN.md +157 -0
  65. package/examples/README.md +34 -0
  66. package/examples/sample-workspace/essence/essence.md +26 -0
  67. package/examples/sample-workspace/index.json +36 -0
  68. package/examples/sample-workspace/memory/decisions/sample-decision.md +30 -0
  69. package/examples/sample-workspace/memory/knowledge/sample-knowledge.md +24 -0
  70. package/examples/sample-workspace/memory/reference/sample-reference.md +20 -0
  71. package/examples/sample-workspace/memory/rules/sample-rule.md +31 -0
  72. package/examples/sample-workspace/themes/cache-design.json +15 -0
  73. package/package.json +72 -0
  74. package/skills/memory-manage/SKILL.md +43 -0
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Markdown memory file operations.
3
+ */
4
+ import fs from 'fs';
5
+ import path from 'path';
6
+ import { parseFrontmatter, stringifyFrontmatter } from '../utils/frontmatter.js';
7
+ import { safeResolve, atomicWriteFile } from '../utils/paths.js';
8
+ function safeParseFile(filePath) {
9
+ try {
10
+ const text = fs.readFileSync(filePath, 'utf8');
11
+ return parseFrontmatter(text) || { frontmatter: {}, body: text };
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ export class MemoryStore {
18
+ storeRoot;
19
+ constructor(storeRoot) {
20
+ this.storeRoot = storeRoot;
21
+ }
22
+ resolveFilePath(folder, key) {
23
+ return safeResolve(this.storeRoot, folder, `${key}.md`);
24
+ }
25
+ exists(folder, key) {
26
+ return fs.existsSync(this.resolveFilePath(folder, key));
27
+ }
28
+ read(folder, key) {
29
+ const filePath = this.resolveFilePath(folder, key);
30
+ const parsed = safeParseFile(filePath);
31
+ if (!parsed)
32
+ return null;
33
+ return {
34
+ ...parsed.frontmatter,
35
+ content: parsed.body,
36
+ filePath,
37
+ };
38
+ }
39
+ write(folder, key, content, tags = [], options = {}) {
40
+ const filePath = this.resolveFilePath(folder, key);
41
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
42
+ const existing = this.exists(folder, key) ? safeParseFile(filePath) : null;
43
+ const now = new Date().toISOString();
44
+ const frontmatter = {
45
+ key,
46
+ title: options.title || String(existing?.frontmatter?.title || this.toTitle(key)),
47
+ tags: tags.length > 0 ? tags : existing?.frontmatter?.tags || [],
48
+ createdAt: String(existing?.frontmatter?.createdAt || now),
49
+ updatedAt: now,
50
+ };
51
+ atomicWriteFile(filePath, stringifyFrontmatter(frontmatter) + content, 'utf8');
52
+ return filePath;
53
+ }
54
+ delete(folder, key) {
55
+ const filePath = this.resolveFilePath(folder, key);
56
+ if (!fs.existsSync(filePath))
57
+ return false;
58
+ fs.unlinkSync(filePath);
59
+ return true;
60
+ }
61
+ move(oldFolder, oldKey, toFolder, newKey) {
62
+ const oldPath = this.resolveFilePath(oldFolder, oldKey);
63
+ const finalKey = newKey || oldKey;
64
+ const newPath = this.resolveFilePath(toFolder, finalKey);
65
+ if (!fs.existsSync(oldPath)) {
66
+ throw new Error(`Source memory not found: ${oldFolder}/${oldKey}`);
67
+ }
68
+ if (fs.existsSync(newPath)) {
69
+ throw new Error(`Destination already exists: ${toFolder}/${finalKey}`);
70
+ }
71
+ fs.mkdirSync(path.dirname(newPath), { recursive: true });
72
+ if (newKey) {
73
+ // Rewrite frontmatter key when renaming.
74
+ const parsed = safeParseFile(oldPath);
75
+ if (parsed) {
76
+ parsed.frontmatter.key = newKey;
77
+ parsed.frontmatter.updatedAt = new Date().toISOString();
78
+ atomicWriteFile(newPath, stringifyFrontmatter(parsed.frontmatter) + parsed.body, 'utf8');
79
+ fs.unlinkSync(oldPath);
80
+ return newPath;
81
+ }
82
+ }
83
+ fs.renameSync(oldPath, newPath);
84
+ return newPath;
85
+ }
86
+ listMarkdownFiles(dir) {
87
+ const results = [];
88
+ if (!fs.existsSync(dir))
89
+ return results;
90
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
91
+ for (const entry of entries) {
92
+ const full = path.join(dir, entry.name);
93
+ if (entry.isDirectory()) {
94
+ results.push(...this.listMarkdownFiles(full));
95
+ }
96
+ else if (entry.isFile() && entry.name.endsWith('.md')) {
97
+ results.push(full);
98
+ }
99
+ }
100
+ return results;
101
+ }
102
+ toTitle(key) {
103
+ return String(key)
104
+ .replace(/[-_]+/g, ' ')
105
+ .replace(/([a-z])([A-Z])/g, '$1 $2')
106
+ .split(' ')
107
+ .filter(Boolean)
108
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
109
+ .join(' ');
110
+ }
111
+ }
112
+ //# sourceMappingURL=memory-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../src/dao/memory-store.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAYjE,SAAS,aAAa,CAAC,QAAgB;IACrC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC/C,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IACnE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,OAAO,WAAW;IACtB,SAAS,CAAS;IAElB,YAAY,SAAiB;QAC3B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED,eAAe,CAAC,MAAc,EAAE,GAAW;QACzC,OAAO,WAAW,CAAC,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,GAAG,KAAK,CAAC,CAAC;IAC1D,CAAC;IAED,MAAM,CAAC,MAAc,EAAE,GAAW;QAChC,OAAO,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,IAAI,CAAC,MAAc,EAAE,GAAW;QAC9B,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACzB,OAAO;YACL,GAAI,MAAM,CAAC,WAA2B;YACtC,OAAO,EAAE,MAAM,CAAC,IAAI;YACpB,QAAQ;SACW,CAAC;IACxB,CAAC;IAED,KAAK,CACH,MAAc,EACd,GAAW,EACX,OAAe,EACf,OAAiB,EAAE,EACnB,UAAwB,EAAE;QAE1B,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACnD,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE1D,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC3E,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAErC,MAAM,WAAW,GAAgB;YAC/B,GAAG;YACH,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjF,IAAI,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,QAAQ,EAAE,WAAW,EAAE,IAA6B,IAAI,EAAE;YAC1F,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE,WAAW,EAAE,SAAS,IAAI,GAAG,CAAC;YAC1D,SAAS,EAAE,GAAG;SACf,CAAC;QAEF,eAAe,CAAC,QAAQ,EAAE,oBAAoB,CAAC,WAAW,CAAC,GAAG,OAAO,EAAE,MAAM,CAAC,CAAC;QAC/E,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,CAAC,MAAc,EAAE,GAAW;QAChC,MAAM,QAAQ,GAAG,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QACnD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3C,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACxB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,SAAiB,EAAE,MAAc,EAAE,QAAgB,EAAE,MAAe;QACvE,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,MAAM,IAAI,MAAM,CAAC;QAClC,MAAM,OAAO,GAAG,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEzD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,4BAA4B,SAAS,IAAI,MAAM,EAAE,CAAC,CAAC;QACrE,CAAC;QACD,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,+BAA+B,QAAQ,IAAI,QAAQ,EAAE,CAAC,CAAC;QACzE,CAAC;QAED,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEzD,IAAI,MAAM,EAAE,CAAC;YACX,yCAAyC;YACzC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;YACtC,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,WAAW,CAAC,GAAG,GAAG,MAAM,CAAC;gBAChC,MAAM,CAAC,WAAW,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBACxD,eAAe,CAAC,OAAO,EAAE,oBAAoB,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACzF,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBACvB,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QAED,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAChC,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,iBAAiB,CAAC,GAAW;QAC3B,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,OAAO,OAAO,CAAC;QACxC,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACxC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBACxB,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC;YAChD,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,OAAO,CAAC,GAAW;QACjB,OAAO,MAAM,CAAC,GAAG,CAAC;aACf,OAAO,CAAC,QAAQ,EAAE,GAAG,CAAC;aACtB,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC;aACnC,KAAK,CAAC,GAAG,CAAC;aACV,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;aAChE,IAAI,CAAC,GAAG,CAAC,CAAC;IACf,CAAC;CACF"}
@@ -0,0 +1,70 @@
1
+ /**
2
+ * Refined turn storage and extraction backed by SQLite.
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.
11
+ */
12
+ export interface RawAction {
13
+ name?: string;
14
+ args?: unknown;
15
+ result?: unknown;
16
+ }
17
+ export interface RawTurn {
18
+ turnId?: string | number;
19
+ timestamp?: string;
20
+ user?: string;
21
+ agentText?: string;
22
+ agent?: string;
23
+ actions?: RawAction[];
24
+ }
25
+ export interface RefinedTurn {
26
+ sessionId: string;
27
+ turnId: number;
28
+ timestamp: string | undefined;
29
+ summary: string;
30
+ facts: string[];
31
+ notes: string[];
32
+ entities: {
33
+ files: string[];
34
+ tools: string[];
35
+ errors: string[];
36
+ };
37
+ categories: Record<string, string[]>;
38
+ }
39
+ export interface RefinedSearchOptions {
40
+ query: string;
41
+ dateFrom?: string;
42
+ dateTo?: string;
43
+ limit?: number;
44
+ }
45
+ export interface RefinedSearchMatch {
46
+ sessionId: string;
47
+ turnId: number;
48
+ timestamp: string | undefined;
49
+ summary: string;
50
+ facts: string[];
51
+ notes: string[];
52
+ score: number;
53
+ }
54
+ export declare class RefinedManager {
55
+ refinedRoot: string;
56
+ private dbPath;
57
+ private db;
58
+ private mutex;
59
+ constructor(refinedRoot: string);
60
+ private initDb;
61
+ refineTurn(turn: RawTurn, sessionId: string): RefinedTurn;
62
+ private rowToTurn;
63
+ saveRefinedTurns(sessionId: string, refinedTurns: RefinedTurn[]): Promise<void>;
64
+ loadRefinedTurns(sessionId: string): RefinedTurn[];
65
+ private loadRefinedTurnsSync;
66
+ getDbPath(): string;
67
+ loadRefinedTurn(sessionId: string, turnId: number): RefinedTurn | undefined;
68
+ searchRefinedTurns(options: RefinedSearchOptions): RefinedSearchMatch[];
69
+ close(): void;
70
+ }
@@ -0,0 +1,369 @@
1
+ /**
2
+ * Refined turn storage and extraction backed by SQLite.
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.
11
+ */
12
+ import fs from 'fs';
13
+ import path from 'path';
14
+ import Database from 'better-sqlite3';
15
+ 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
+ }
131
+ export class RefinedManager {
132
+ refinedRoot;
133
+ dbPath;
134
+ db;
135
+ mutex;
136
+ constructor(refinedRoot) {
137
+ this.refinedRoot = refinedRoot;
138
+ this.dbPath = path.join(refinedRoot, 'refined.sqlite');
139
+ fs.mkdirSync(refinedRoot, { recursive: true });
140
+ this.db = new Database(this.dbPath);
141
+ 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
+ }
161
+ 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
+ };
267
+ }
268
+ async saveRefinedTurns(sessionId, refinedTurns) {
269
+ 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();
284
+ });
285
+ }
286
+ loadRefinedTurns(sessionId) {
287
+ return this.loadRefinedTurnsSync(sessionId);
288
+ }
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));
293
+ }
294
+ 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;
301
+ }
302
+ 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);
364
+ }
365
+ close() {
366
+ this.db.close();
367
+ }
368
+ }
369
+ //# sourceMappingURL=refined-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"refined-manager.js","sourceRoot":"","sources":["../src/refined-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Kimi Code Memory MCP Server
4
+ *
5
+ * A local stdio MCP server providing cross-session memory for Kimi Code CLI.
6
+ * Data is stored as Markdown files; no external database is required.
7
+ */
8
+ export {};
package/dist/server.js ADDED
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Kimi Code Memory MCP Server
4
+ *
5
+ * A local stdio MCP server providing cross-session memory for Kimi Code CLI.
6
+ * Data is stored as Markdown files; no external database is required.
7
+ */
8
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
9
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
10
+ import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
11
+ import fs from 'fs';
12
+ import path from 'path';
13
+ import { getStoreRoot } from './config.js';
14
+ import { computeWorkspaceId } from './utils/paths.js';
15
+ import { IndexDao } from './dao/index.js';
16
+ import { MemoryStore } from './dao/memory-store.js';
17
+ import { ThemeManager } from './theme-manager.js';
18
+ import { RefinedManager } from './refined-manager.js';
19
+ import { createTools } from './tools/index.js';
20
+ import { VERSION } from './version.js';
21
+ const cwd = process.cwd().replace(/\\/g, '/');
22
+ const workspaceId = computeWorkspaceId(cwd);
23
+ const storeRoot = path.join(getStoreRoot(), workspaceId);
24
+ // Ensure base directories exist.
25
+ for (const dir of ['memory', 'notes', 'essence', 'themes', 'refined']) {
26
+ fs.mkdirSync(path.join(storeRoot, dir), { recursive: true });
27
+ }
28
+ const indexDao = new IndexDao(storeRoot);
29
+ const memoryStore = new MemoryStore(storeRoot);
30
+ const themeManager = new ThemeManager(path.join(storeRoot, 'themes'));
31
+ const refinedManager = new RefinedManager(path.join(storeRoot, 'refined'));
32
+ const ctx = {
33
+ cwd,
34
+ workspaceId,
35
+ storeRoot,
36
+ indexDao,
37
+ memoryStore,
38
+ themeManager,
39
+ refinedManager,
40
+ };
41
+ const tools = createTools(ctx);
42
+ const server = new Server({ name: 'kimi-code-memory', version: VERSION }, { capabilities: { tools: {} } });
43
+ server.setRequestHandler(ListToolsRequestSchema, async () => ({
44
+ tools: tools.toolSchemas,
45
+ }));
46
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
47
+ try {
48
+ return await tools.dispatch(request.params.name, request.params.arguments || {});
49
+ }
50
+ catch (err) {
51
+ return {
52
+ content: [
53
+ {
54
+ type: 'text',
55
+ text: JSON.stringify({ error: err instanceof Error ? err.message : String(err) }, null, 2),
56
+ },
57
+ ],
58
+ isError: true,
59
+ };
60
+ }
61
+ });
62
+ async function main() {
63
+ const transport = new StdioServerTransport();
64
+ await server.connect(transport);
65
+ }
66
+ main().catch((err) => {
67
+ const message = err instanceof Error ? err.message : String(err);
68
+ process.stderr.write(`Fatal error: ${message}\n`);
69
+ process.exit(1);
70
+ });
71
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}