cccmemory 1.8.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 (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +349 -0
  3. package/dist/ConversationMemory.d.ts +231 -0
  4. package/dist/ConversationMemory.d.ts.map +1 -0
  5. package/dist/ConversationMemory.js +357 -0
  6. package/dist/ConversationMemory.js.map +1 -0
  7. package/dist/cache/QueryCache.d.ts +215 -0
  8. package/dist/cache/QueryCache.d.ts.map +1 -0
  9. package/dist/cache/QueryCache.js +294 -0
  10. package/dist/cache/QueryCache.js.map +1 -0
  11. package/dist/cli/commands.d.ts +9 -0
  12. package/dist/cli/commands.d.ts.map +1 -0
  13. package/dist/cli/commands.js +954 -0
  14. package/dist/cli/commands.js.map +1 -0
  15. package/dist/cli/help.d.ts +16 -0
  16. package/dist/cli/help.d.ts.map +1 -0
  17. package/dist/cli/help.js +361 -0
  18. package/dist/cli/help.js.map +1 -0
  19. package/dist/cli/index.d.ts +30 -0
  20. package/dist/cli/index.d.ts.map +1 -0
  21. package/dist/cli/index.js +111 -0
  22. package/dist/cli/index.js.map +1 -0
  23. package/dist/context/ContextInjector.d.ts +38 -0
  24. package/dist/context/ContextInjector.d.ts.map +1 -0
  25. package/dist/context/ContextInjector.js +235 -0
  26. package/dist/context/ContextInjector.js.map +1 -0
  27. package/dist/documentation/CodeAnalyzer.d.ts +29 -0
  28. package/dist/documentation/CodeAnalyzer.d.ts.map +1 -0
  29. package/dist/documentation/CodeAnalyzer.js +122 -0
  30. package/dist/documentation/CodeAnalyzer.js.map +1 -0
  31. package/dist/documentation/ConversationAnalyzer.d.ts +19 -0
  32. package/dist/documentation/ConversationAnalyzer.d.ts.map +1 -0
  33. package/dist/documentation/ConversationAnalyzer.js +157 -0
  34. package/dist/documentation/ConversationAnalyzer.js.map +1 -0
  35. package/dist/documentation/CrossReferencer.d.ts +67 -0
  36. package/dist/documentation/CrossReferencer.d.ts.map +1 -0
  37. package/dist/documentation/CrossReferencer.js +247 -0
  38. package/dist/documentation/CrossReferencer.js.map +1 -0
  39. package/dist/documentation/DocumentationGenerator.d.ts +22 -0
  40. package/dist/documentation/DocumentationGenerator.d.ts.map +1 -0
  41. package/dist/documentation/DocumentationGenerator.js +57 -0
  42. package/dist/documentation/DocumentationGenerator.js.map +1 -0
  43. package/dist/documentation/MarkdownFormatter.d.ts +26 -0
  44. package/dist/documentation/MarkdownFormatter.d.ts.map +1 -0
  45. package/dist/documentation/MarkdownFormatter.js +301 -0
  46. package/dist/documentation/MarkdownFormatter.js.map +1 -0
  47. package/dist/documentation/types.d.ts +176 -0
  48. package/dist/documentation/types.d.ts.map +1 -0
  49. package/dist/documentation/types.js +5 -0
  50. package/dist/documentation/types.js.map +1 -0
  51. package/dist/embeddings/ConfigManager.d.ts +46 -0
  52. package/dist/embeddings/ConfigManager.d.ts.map +1 -0
  53. package/dist/embeddings/ConfigManager.js +177 -0
  54. package/dist/embeddings/ConfigManager.js.map +1 -0
  55. package/dist/embeddings/EmbeddingConfig.d.ts +39 -0
  56. package/dist/embeddings/EmbeddingConfig.d.ts.map +1 -0
  57. package/dist/embeddings/EmbeddingConfig.js +132 -0
  58. package/dist/embeddings/EmbeddingConfig.js.map +1 -0
  59. package/dist/embeddings/EmbeddingGenerator.d.ts +51 -0
  60. package/dist/embeddings/EmbeddingGenerator.d.ts.map +1 -0
  61. package/dist/embeddings/EmbeddingGenerator.js +157 -0
  62. package/dist/embeddings/EmbeddingGenerator.js.map +1 -0
  63. package/dist/embeddings/EmbeddingProvider.d.ts +34 -0
  64. package/dist/embeddings/EmbeddingProvider.d.ts.map +1 -0
  65. package/dist/embeddings/EmbeddingProvider.js +6 -0
  66. package/dist/embeddings/EmbeddingProvider.js.map +1 -0
  67. package/dist/embeddings/ModelRegistry.d.ts +48 -0
  68. package/dist/embeddings/ModelRegistry.d.ts.map +1 -0
  69. package/dist/embeddings/ModelRegistry.js +170 -0
  70. package/dist/embeddings/ModelRegistry.js.map +1 -0
  71. package/dist/embeddings/VectorStore.d.ts +114 -0
  72. package/dist/embeddings/VectorStore.d.ts.map +1 -0
  73. package/dist/embeddings/VectorStore.js +393 -0
  74. package/dist/embeddings/VectorStore.js.map +1 -0
  75. package/dist/embeddings/providers/OllamaEmbeddings.d.ts +38 -0
  76. package/dist/embeddings/providers/OllamaEmbeddings.d.ts.map +1 -0
  77. package/dist/embeddings/providers/OllamaEmbeddings.js +125 -0
  78. package/dist/embeddings/providers/OllamaEmbeddings.js.map +1 -0
  79. package/dist/embeddings/providers/OpenAIEmbeddings.d.ts +40 -0
  80. package/dist/embeddings/providers/OpenAIEmbeddings.d.ts.map +1 -0
  81. package/dist/embeddings/providers/OpenAIEmbeddings.js +129 -0
  82. package/dist/embeddings/providers/OpenAIEmbeddings.js.map +1 -0
  83. package/dist/embeddings/providers/TransformersEmbeddings.d.ts +38 -0
  84. package/dist/embeddings/providers/TransformersEmbeddings.d.ts.map +1 -0
  85. package/dist/embeddings/providers/TransformersEmbeddings.js +115 -0
  86. package/dist/embeddings/providers/TransformersEmbeddings.js.map +1 -0
  87. package/dist/handoff/SessionHandoffStore.d.ts +80 -0
  88. package/dist/handoff/SessionHandoffStore.d.ts.map +1 -0
  89. package/dist/handoff/SessionHandoffStore.js +314 -0
  90. package/dist/handoff/SessionHandoffStore.js.map +1 -0
  91. package/dist/index.d.ts +7 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +115 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/mcp-server.d.ts +27 -0
  96. package/dist/mcp-server.d.ts.map +1 -0
  97. package/dist/mcp-server.js +157 -0
  98. package/dist/mcp-server.js.map +1 -0
  99. package/dist/memory/WorkingMemoryStore.d.ts +83 -0
  100. package/dist/memory/WorkingMemoryStore.d.ts.map +1 -0
  101. package/dist/memory/WorkingMemoryStore.js +318 -0
  102. package/dist/memory/WorkingMemoryStore.js.map +1 -0
  103. package/dist/memory/types.d.ts +192 -0
  104. package/dist/memory/types.d.ts.map +1 -0
  105. package/dist/memory/types.js +8 -0
  106. package/dist/memory/types.js.map +1 -0
  107. package/dist/parsers/CodexConversationParser.d.ts +51 -0
  108. package/dist/parsers/CodexConversationParser.d.ts.map +1 -0
  109. package/dist/parsers/CodexConversationParser.js +301 -0
  110. package/dist/parsers/CodexConversationParser.js.map +1 -0
  111. package/dist/parsers/ConversationParser.d.ts +286 -0
  112. package/dist/parsers/ConversationParser.d.ts.map +1 -0
  113. package/dist/parsers/ConversationParser.js +795 -0
  114. package/dist/parsers/ConversationParser.js.map +1 -0
  115. package/dist/parsers/DecisionExtractor.d.ts +144 -0
  116. package/dist/parsers/DecisionExtractor.d.ts.map +1 -0
  117. package/dist/parsers/DecisionExtractor.js +434 -0
  118. package/dist/parsers/DecisionExtractor.js.map +1 -0
  119. package/dist/parsers/GitIntegrator.d.ts +156 -0
  120. package/dist/parsers/GitIntegrator.d.ts.map +1 -0
  121. package/dist/parsers/GitIntegrator.js +348 -0
  122. package/dist/parsers/GitIntegrator.js.map +1 -0
  123. package/dist/parsers/MistakeExtractor.d.ts +151 -0
  124. package/dist/parsers/MistakeExtractor.d.ts.map +1 -0
  125. package/dist/parsers/MistakeExtractor.js +460 -0
  126. package/dist/parsers/MistakeExtractor.js.map +1 -0
  127. package/dist/parsers/RequirementsExtractor.d.ts +166 -0
  128. package/dist/parsers/RequirementsExtractor.d.ts.map +1 -0
  129. package/dist/parsers/RequirementsExtractor.js +338 -0
  130. package/dist/parsers/RequirementsExtractor.js.map +1 -0
  131. package/dist/realtime/ConversationWatcher.d.ts +87 -0
  132. package/dist/realtime/ConversationWatcher.d.ts.map +1 -0
  133. package/dist/realtime/ConversationWatcher.js +204 -0
  134. package/dist/realtime/ConversationWatcher.js.map +1 -0
  135. package/dist/realtime/IncrementalParser.d.ts +83 -0
  136. package/dist/realtime/IncrementalParser.d.ts.map +1 -0
  137. package/dist/realtime/IncrementalParser.js +232 -0
  138. package/dist/realtime/IncrementalParser.js.map +1 -0
  139. package/dist/realtime/LiveExtractor.d.ts +72 -0
  140. package/dist/realtime/LiveExtractor.d.ts.map +1 -0
  141. package/dist/realtime/LiveExtractor.js +288 -0
  142. package/dist/realtime/LiveExtractor.js.map +1 -0
  143. package/dist/search/SemanticSearch.d.ts +121 -0
  144. package/dist/search/SemanticSearch.d.ts.map +1 -0
  145. package/dist/search/SemanticSearch.js +823 -0
  146. package/dist/search/SemanticSearch.js.map +1 -0
  147. package/dist/storage/BackupManager.d.ts +58 -0
  148. package/dist/storage/BackupManager.d.ts.map +1 -0
  149. package/dist/storage/BackupManager.js +223 -0
  150. package/dist/storage/BackupManager.js.map +1 -0
  151. package/dist/storage/ConversationStorage.d.ts +341 -0
  152. package/dist/storage/ConversationStorage.d.ts.map +1 -0
  153. package/dist/storage/ConversationStorage.js +792 -0
  154. package/dist/storage/ConversationStorage.js.map +1 -0
  155. package/dist/storage/DeletionService.d.ts +70 -0
  156. package/dist/storage/DeletionService.d.ts.map +1 -0
  157. package/dist/storage/DeletionService.js +253 -0
  158. package/dist/storage/DeletionService.js.map +1 -0
  159. package/dist/storage/GlobalIndex.d.ts +133 -0
  160. package/dist/storage/GlobalIndex.d.ts.map +1 -0
  161. package/dist/storage/GlobalIndex.js +310 -0
  162. package/dist/storage/GlobalIndex.js.map +1 -0
  163. package/dist/storage/SQLiteManager.d.ts +114 -0
  164. package/dist/storage/SQLiteManager.d.ts.map +1 -0
  165. package/dist/storage/SQLiteManager.js +636 -0
  166. package/dist/storage/SQLiteManager.js.map +1 -0
  167. package/dist/storage/migrations.d.ts +54 -0
  168. package/dist/storage/migrations.d.ts.map +1 -0
  169. package/dist/storage/migrations.js +285 -0
  170. package/dist/storage/migrations.js.map +1 -0
  171. package/dist/storage/schema.sql +436 -0
  172. package/dist/tools/ToolDefinitions.d.ts +946 -0
  173. package/dist/tools/ToolDefinitions.d.ts.map +1 -0
  174. package/dist/tools/ToolDefinitions.js +937 -0
  175. package/dist/tools/ToolDefinitions.js.map +1 -0
  176. package/dist/tools/ToolHandlers.d.ts +791 -0
  177. package/dist/tools/ToolHandlers.d.ts.map +1 -0
  178. package/dist/tools/ToolHandlers.js +3262 -0
  179. package/dist/tools/ToolHandlers.js.map +1 -0
  180. package/dist/types/ToolTypes.d.ts +824 -0
  181. package/dist/types/ToolTypes.d.ts.map +1 -0
  182. package/dist/types/ToolTypes.js +6 -0
  183. package/dist/types/ToolTypes.js.map +1 -0
  184. package/dist/utils/Logger.d.ts +70 -0
  185. package/dist/utils/Logger.d.ts.map +1 -0
  186. package/dist/utils/Logger.js +131 -0
  187. package/dist/utils/Logger.js.map +1 -0
  188. package/dist/utils/McpConfig.d.ts +54 -0
  189. package/dist/utils/McpConfig.d.ts.map +1 -0
  190. package/dist/utils/McpConfig.js +136 -0
  191. package/dist/utils/McpConfig.js.map +1 -0
  192. package/dist/utils/ProjectMigration.d.ts +82 -0
  193. package/dist/utils/ProjectMigration.d.ts.map +1 -0
  194. package/dist/utils/ProjectMigration.js +416 -0
  195. package/dist/utils/ProjectMigration.js.map +1 -0
  196. package/dist/utils/constants.d.ts +75 -0
  197. package/dist/utils/constants.d.ts.map +1 -0
  198. package/dist/utils/constants.js +105 -0
  199. package/dist/utils/constants.js.map +1 -0
  200. package/dist/utils/safeJson.d.ts +37 -0
  201. package/dist/utils/safeJson.d.ts.map +1 -0
  202. package/dist/utils/safeJson.js +48 -0
  203. package/dist/utils/safeJson.js.map +1 -0
  204. package/dist/utils/sanitization.d.ts +45 -0
  205. package/dist/utils/sanitization.d.ts.map +1 -0
  206. package/dist/utils/sanitization.js +153 -0
  207. package/dist/utils/sanitization.js.map +1 -0
  208. package/dist/utils/worktree.d.ts +15 -0
  209. package/dist/utils/worktree.d.ts.map +1 -0
  210. package/dist/utils/worktree.js +86 -0
  211. package/dist/utils/worktree.js.map +1 -0
  212. package/package.json +98 -0
  213. package/scripts/changelog-check.sh +62 -0
  214. package/scripts/check-node.js +17 -0
  215. package/scripts/dev-config.js +56 -0
  216. package/scripts/postinstall.js +117 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Safe JSON parsing utilities
3
+ *
4
+ * Provides crash-safe JSON parsing with fallback values.
5
+ * Use this instead of raw JSON.parse() when parsing data from:
6
+ * - Database rows (may be corrupted)
7
+ * - User input
8
+ * - External sources
9
+ */
10
+ /**
11
+ * Safely parse JSON with a fallback value on error.
12
+ *
13
+ * Unlike JSON.parse(), this function:
14
+ * - Never throws
15
+ * - Handles null/undefined input
16
+ * - Handles non-string input
17
+ * - Returns the fallback on any parse error
18
+ *
19
+ * @param value - The JSON string to parse
20
+ * @param fallback - Value to return if parsing fails
21
+ * @returns Parsed value or fallback
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * // Safe object parsing
26
+ * const data = safeJsonParse(row.metadata, {});
27
+ *
28
+ * // Safe array parsing
29
+ * const files = safeJsonParse(row.files_changed, []);
30
+ *
31
+ * // With specific type
32
+ * interface Config { debug: boolean }
33
+ * const config = safeJsonParse<Config>(jsonStr, { debug: false });
34
+ * ```
35
+ */
36
+ export function safeJsonParse(value, fallback) {
37
+ // Handle non-string input
38
+ if (typeof value !== "string" || value === "") {
39
+ return fallback;
40
+ }
41
+ try {
42
+ return JSON.parse(value);
43
+ }
44
+ catch (_error) {
45
+ return fallback;
46
+ }
47
+ }
48
+ //# sourceMappingURL=safeJson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safeJson.js","sourceRoot":"","sources":["../../src/utils/safeJson.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,aAAa,CAAI,KAAgC,EAAE,QAAW;IAC5E,0BAA0B;IAC1B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;QAC9C,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAM,CAAC;IAChC,CAAC;IAAC,OAAO,MAAM,EAAE,CAAC;QAChB,OAAO,QAAQ,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Input sanitization utilities for SQL LIKE queries and path validation
3
+ */
4
+ /**
5
+ * Sanitize string for use in SQL LIKE patterns
6
+ * Escapes special LIKE characters: %, _, "
7
+ */
8
+ export declare function sanitizeForLike(input: string): string;
9
+ /**
10
+ * Validate and sanitize file path
11
+ * Cross-platform: prevents path traversal attacks and blocks system directories
12
+ */
13
+ export declare function validateFilePath(filePath: string): string;
14
+ /**
15
+ * Validate and normalize project path
16
+ * Cross-platform: handles both Unix (/) and Windows (\) paths
17
+ * Used for converting file paths to Claude project directory names
18
+ */
19
+ export declare function sanitizeProjectPath(path: string): string;
20
+ /**
21
+ * Sanitize SQL identifier (table/column name)
22
+ * Only allows alphanumeric and underscore
23
+ */
24
+ export declare function sanitizeSQLIdentifier(identifier: string): string;
25
+ /**
26
+ * Escape a table name for use in double-quoted SQL identifiers
27
+ * Doubles any embedded double-quotes per SQL standard
28
+ */
29
+ export declare function escapeTableName(tableName: string): string;
30
+ /**
31
+ * Validate database path for use in ATTACH DATABASE statement
32
+ * Prevents SQL injection via path manipulation
33
+ */
34
+ export declare function validateDatabasePath(dbPath: string): string;
35
+ /**
36
+ * Convert a project path to Claude Code's project folder name
37
+ * Cross-platform compatible - handles both Unix and Windows paths
38
+ *
39
+ * Examples:
40
+ * - macOS/Linux: /Users/joker/github/project → -Users-joker-github-project
41
+ * - Windows: C:\Users\user\project → C-Users-user-project
42
+ * - Windows UNC: \\server\share\project → -server-share-project
43
+ */
44
+ export declare function pathToProjectFolderName(projectPath: string): string;
45
+ //# sourceMappingURL=sanitization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitization.d.ts","sourceRoot":"","sources":["../../src/utils/sanitization.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAYD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CA+CzD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAmBxD;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAKhE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAMzD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAqB3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAWnE"}
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Input sanitization utilities for SQL LIKE queries and path validation
3
+ */
4
+ import { normalize, sep } from 'path';
5
+ /**
6
+ * Sanitize string for use in SQL LIKE patterns
7
+ * Escapes special LIKE characters: %, _, "
8
+ */
9
+ export function sanitizeForLike(input) {
10
+ return input.replace(/[%_"\\]/g, '\\$&');
11
+ }
12
+ /**
13
+ * Check if a path contains path traversal attempts
14
+ * Only rejects actual '..' path segments, not filenames containing '..'
15
+ */
16
+ function hasPathTraversal(pathStr) {
17
+ // Split on both Unix and Windows separators
18
+ const segments = pathStr.split(/[\\/]/);
19
+ return segments.some(segment => segment === '..');
20
+ }
21
+ /**
22
+ * Validate and sanitize file path
23
+ * Cross-platform: prevents path traversal attacks and blocks system directories
24
+ */
25
+ export function validateFilePath(filePath) {
26
+ // Remove any null bytes
27
+ const cleaned = filePath.replace(/\0/g, '');
28
+ // Check for path traversal attempts (only actual '..' segments)
29
+ if (hasPathTraversal(cleaned)) {
30
+ throw new Error('Path traversal detected: .. is not allowed in file paths');
31
+ }
32
+ // Check for absolute paths outside allowed directories (platform-specific)
33
+ const isWindows = process.platform === 'win32';
34
+ if (isWindows) {
35
+ // Windows system directories (case-insensitive)
36
+ const forbidden = [
37
+ /^[A-Z]:\\Windows\\/i,
38
+ /^[A-Z]:\\Program Files/i,
39
+ /^[A-Z]:\\ProgramData/i,
40
+ /^[A-Z]:\\System/i,
41
+ /^[A-Z]:\\System32/i,
42
+ /^[A-Z]:\\Boot/i,
43
+ ];
44
+ if (forbidden.some(pattern => pattern.test(cleaned))) {
45
+ throw new Error('Access to system directories is not allowed');
46
+ }
47
+ }
48
+ else {
49
+ // Unix system directories - comprehensive list
50
+ const forbiddenPaths = [
51
+ '/etc',
52
+ '/sys',
53
+ '/proc',
54
+ '/dev',
55
+ '/boot',
56
+ '/sbin',
57
+ '/bin',
58
+ '/lib',
59
+ '/lib64',
60
+ '/usr/sbin',
61
+ '/var/run',
62
+ '/var/lock',
63
+ ];
64
+ if (forbiddenPaths.some(dir => cleaned === dir || cleaned.startsWith(dir + '/'))) {
65
+ throw new Error('Access to system directories is not allowed');
66
+ }
67
+ }
68
+ return cleaned;
69
+ }
70
+ /**
71
+ * Validate and normalize project path
72
+ * Cross-platform: handles both Unix (/) and Windows (\) paths
73
+ * Used for converting file paths to Claude project directory names
74
+ */
75
+ export function sanitizeProjectPath(path) {
76
+ // Remove null bytes
77
+ const cleaned = path.replace(/\0/g, '');
78
+ // Check for path traversal
79
+ if (cleaned.includes('..')) {
80
+ throw new Error('Path traversal detected in project path');
81
+ }
82
+ // First normalize with Node's native path module for current platform
83
+ let normalized = normalize(cleaned);
84
+ // Then handle any remaining separators from other platforms
85
+ // Replace multiple consecutive slashes/backslashes with single separator
86
+ normalized = normalized.replace(/[\\/]+/g, sep);
87
+ // Remove trailing path separator
88
+ const trailingSepRegex = new RegExp(`${sep.replace(/\\/g, '\\\\')}+$`);
89
+ return normalized.replace(trailingSepRegex, '');
90
+ }
91
+ /**
92
+ * Sanitize SQL identifier (table/column name)
93
+ * Only allows alphanumeric and underscore
94
+ */
95
+ export function sanitizeSQLIdentifier(identifier) {
96
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(identifier)) {
97
+ throw new Error(`Invalid SQL identifier: ${identifier}`);
98
+ }
99
+ return identifier;
100
+ }
101
+ /**
102
+ * Escape a table name for use in double-quoted SQL identifiers
103
+ * Doubles any embedded double-quotes per SQL standard
104
+ */
105
+ export function escapeTableName(tableName) {
106
+ if (!tableName || tableName.length === 0) {
107
+ throw new Error("Table name cannot be empty");
108
+ }
109
+ // Double any embedded double-quotes (SQL standard escaping)
110
+ return tableName.replace(/"/g, '""');
111
+ }
112
+ /**
113
+ * Validate database path for use in ATTACH DATABASE statement
114
+ * Prevents SQL injection via path manipulation
115
+ */
116
+ export function validateDatabasePath(dbPath) {
117
+ if (!dbPath || dbPath.length === 0) {
118
+ throw new Error("Database path cannot be empty");
119
+ }
120
+ // Check for single quotes which could break SQL string
121
+ if (dbPath.includes("'")) {
122
+ throw new Error("Database path cannot contain single quotes");
123
+ }
124
+ // Check for null bytes
125
+ if (dbPath.includes("\0")) {
126
+ throw new Error("Database path cannot contain null bytes");
127
+ }
128
+ // Check for path traversal
129
+ if (dbPath.includes("..")) {
130
+ throw new Error("Path traversal detected in database path");
131
+ }
132
+ return dbPath;
133
+ }
134
+ /**
135
+ * Convert a project path to Claude Code's project folder name
136
+ * Cross-platform compatible - handles both Unix and Windows paths
137
+ *
138
+ * Examples:
139
+ * - macOS/Linux: /Users/joker/github/project → -Users-joker-github-project
140
+ * - Windows: C:\Users\user\project → C-Users-user-project
141
+ * - Windows UNC: \\server\share\project → -server-share-project
142
+ */
143
+ export function pathToProjectFolderName(projectPath) {
144
+ // Normalize the path first
145
+ const normalized = sanitizeProjectPath(projectPath);
146
+ // Replace Windows drive letters (C: → C, D: → D)
147
+ // Replace both forward and backward slashes with dashes
148
+ const folderName = normalized
149
+ .replace(/^([A-Z]):/i, '$1') // Remove colon from drive letter
150
+ .replace(/[\\/]+/g, '-'); // Replace / or \ with -
151
+ return folderName;
152
+ }
153
+ //# sourceMappingURL=sanitization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitization.js","sourceRoot":"","sources":["../../src/utils/sanitization.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ export interface WorktreeInfo {
2
+ canonicalPath: string;
3
+ worktreePaths: string[];
4
+ isGitRepo: boolean;
5
+ commonDir?: string;
6
+ }
7
+ export declare function getGitCommonDir(projectPath: string): string | null;
8
+ export declare function getCanonicalProjectPath(projectPath: string): {
9
+ canonicalPath: string;
10
+ commonDir?: string;
11
+ isGitRepo: boolean;
12
+ };
13
+ export declare function listWorktreePaths(projectPath: string): string[];
14
+ export declare function getWorktreeInfo(projectPath: string): WorktreeInfo;
15
+ //# sourceMappingURL=worktree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.d.ts","sourceRoot":"","sources":["../../src/utils/worktree.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4BD,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAOlE;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,MAAM,GAAG;IAC5D,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB,CAYA;AAED,wBAAgB,iBAAiB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAuB/D;AAED,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,YAAY,CAiBjE"}
@@ -0,0 +1,86 @@
1
+ import { execFileSync } from "child_process";
2
+ import { basename, dirname, isAbsolute, resolve } from "path";
3
+ import { realpathSync } from "fs";
4
+ function normalizePath(inputPath) {
5
+ const resolved = resolve(inputPath);
6
+ try {
7
+ return realpathSync(resolved);
8
+ }
9
+ catch (_error) {
10
+ return resolved;
11
+ }
12
+ }
13
+ function runGit(args, cwd) {
14
+ try {
15
+ return execFileSync("git", args, {
16
+ cwd,
17
+ encoding: "utf-8",
18
+ stdio: ["ignore", "pipe", "ignore"],
19
+ }).trim();
20
+ }
21
+ catch (_error) {
22
+ return null;
23
+ }
24
+ }
25
+ function resolveGitPath(rawPath, cwd) {
26
+ const resolved = isAbsolute(rawPath) ? rawPath : resolve(cwd, rawPath);
27
+ return normalizePath(resolved);
28
+ }
29
+ export function getGitCommonDir(projectPath) {
30
+ const normalizedProjectPath = normalizePath(projectPath);
31
+ const output = runGit(["rev-parse", "--git-common-dir"], normalizedProjectPath);
32
+ if (!output) {
33
+ return null;
34
+ }
35
+ return resolveGitPath(output, normalizedProjectPath);
36
+ }
37
+ export function getCanonicalProjectPath(projectPath) {
38
+ const normalizedProjectPath = normalizePath(projectPath);
39
+ const commonDir = getGitCommonDir(normalizedProjectPath);
40
+ if (!commonDir) {
41
+ return { canonicalPath: normalizedProjectPath, isGitRepo: false };
42
+ }
43
+ const commonBase = basename(commonDir);
44
+ const canonicalPath = commonBase === ".git" ? normalizePath(dirname(commonDir)) : commonDir;
45
+ return { canonicalPath, commonDir, isGitRepo: true };
46
+ }
47
+ export function listWorktreePaths(projectPath) {
48
+ const normalizedProjectPath = normalizePath(projectPath);
49
+ const output = runGit(["worktree", "list", "--porcelain"], normalizedProjectPath);
50
+ if (!output) {
51
+ return [];
52
+ }
53
+ const worktrees = [];
54
+ for (const line of output.split(/\r?\n/)) {
55
+ if (!line.startsWith("worktree ")) {
56
+ continue;
57
+ }
58
+ const rawPath = line.slice("worktree ".length).trim();
59
+ if (!rawPath) {
60
+ continue;
61
+ }
62
+ const resolved = resolveGitPath(rawPath, normalizedProjectPath);
63
+ if (!worktrees.includes(resolved)) {
64
+ worktrees.push(resolved);
65
+ }
66
+ }
67
+ return worktrees;
68
+ }
69
+ export function getWorktreeInfo(projectPath) {
70
+ const normalizedProjectPath = normalizePath(projectPath);
71
+ const { canonicalPath, commonDir, isGitRepo } = getCanonicalProjectPath(normalizedProjectPath);
72
+ let worktreePaths = listWorktreePaths(normalizedProjectPath);
73
+ if (worktreePaths.length === 0) {
74
+ worktreePaths = [normalizedProjectPath];
75
+ }
76
+ else if (!worktreePaths.includes(normalizedProjectPath)) {
77
+ worktreePaths.push(normalizedProjectPath);
78
+ }
79
+ return {
80
+ canonicalPath,
81
+ worktreePaths,
82
+ isGitRepo,
83
+ commonDir,
84
+ };
85
+ }
86
+ //# sourceMappingURL=worktree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worktree.js","sourceRoot":"","sources":["../../src/utils/worktree.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,98 @@
1
+ {
2
+ "name": "cccmemory",
3
+ "version": "1.8.0",
4
+ "description": "MCP server for indexing and searching Claude Code conversation history with decision tracking, git integration, and project migration/merge",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "cccmemory": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "scripts",
13
+ "README.md",
14
+ "LICENSE"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc && npm run postbuild",
18
+ "postbuild": "cp src/storage/schema.sql dist/storage/",
19
+ "preinstall": "node scripts/check-node.js",
20
+ "postinstall": "node scripts/postinstall.js",
21
+ "dev": "tsc --watch",
22
+ "dev:config": "node scripts/dev-config.js",
23
+ "start": "node dist/index.js",
24
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
25
+ "lint": "eslint .",
26
+ "lint:fix": "eslint . --fix",
27
+ "type-check": "tsc --noEmit",
28
+ "clean": "rm -rf dist",
29
+ "docs": "typedoc --out docs src",
30
+ "test:watch": "npm test -- --watch",
31
+ "test:coverage": "npm test -- --coverage",
32
+ "changelog:check": "bash scripts/changelog-check.sh",
33
+ "pre-push": "npm run type-check && npm run lint && npm run build",
34
+ "prepublishOnly": "npm run build",
35
+ "prepare": "husky"
36
+ },
37
+ "keywords": [
38
+ "mcp",
39
+ "claude",
40
+ "conversation",
41
+ "memory",
42
+ "semantic-search",
43
+ "decision-tracking"
44
+ ],
45
+ "author": "xiaolai",
46
+ "license": "MIT",
47
+ "repository": {
48
+ "type": "git",
49
+ "url": "git+https://github.com/xiaolai/cccmemory.git"
50
+ },
51
+ "bugs": {
52
+ "url": "https://github.com/xiaolai/cccmemory/issues"
53
+ },
54
+ "homepage": "https://github.com/xiaolai/cccmemory#readme",
55
+ "dependencies": {
56
+ "@modelcontextprotocol/sdk": "^1.0.4",
57
+ "@xenova/transformers": "^2.17.2",
58
+ "better-sqlite3": "^11.10.0",
59
+ "chalk": "^5.3.0",
60
+ "chokidar": "^5.0.0",
61
+ "cli-table3": "^0.6.5",
62
+ "commander": "^12.1.0",
63
+ "lru-cache": "^10.0.0",
64
+ "nanoid": "^5.0.0",
65
+ "prompts": "^2.4.2",
66
+ "simple-git": "^3.25.0",
67
+ "sqlite-vec": "^0.1.6"
68
+ },
69
+ "optionalDependencies": {
70
+ "openai": "^6.9.1"
71
+ },
72
+ "devDependencies": {
73
+ "@types/better-sqlite3": "^7.6.11",
74
+ "@types/jest": "^29.5.14",
75
+ "@types/node": "^22.10.5",
76
+ "@types/prompts": "^2.4.9",
77
+ "@typescript-eslint/eslint-plugin": "^8.19.1",
78
+ "@typescript-eslint/parser": "^8.19.1",
79
+ "eslint": "^9.18.0",
80
+ "globals": "^16.5.0",
81
+ "husky": "^9.1.7",
82
+ "jest": "^29.7.0",
83
+ "lint-staged": "^16.2.6",
84
+ "prettier": "^3.6.2",
85
+ "ts-jest": "^29.2.5",
86
+ "ts-node": "^10.9.2",
87
+ "typescript": "^5.7.3"
88
+ },
89
+ "engines": {
90
+ "node": ">=20 <23"
91
+ },
92
+ "lint-staged": {
93
+ "*.ts": [
94
+ "eslint --fix",
95
+ "prettier --write"
96
+ ]
97
+ }
98
+ }
@@ -0,0 +1,62 @@
1
+ #!/bin/bash
2
+ # Changelog checker - Verifies CHANGELOG.md is up to date for releases
3
+
4
+ set -e
5
+
6
+ # Colors for output
7
+ RED='\033[0;31m'
8
+ GREEN='\033[0;32m'
9
+ YELLOW='\033[1;33m'
10
+ NC='\033[0m' # No Color
11
+
12
+ # Get the current version from package.json
13
+ CURRENT_VERSION=$(node -p "require('./package.json').version")
14
+
15
+ # Check if CHANGELOG.md exists
16
+ if [ ! -f "CHANGELOG.md" ]; then
17
+ echo -e "${RED}❌ CHANGELOG.md not found${NC}"
18
+ exit 1
19
+ fi
20
+
21
+ # Check if current version is documented in CHANGELOG
22
+ if ! grep -q "\[$CURRENT_VERSION\]" CHANGELOG.md; then
23
+ echo -e "${YELLOW}⚠️ Warning: Version $CURRENT_VERSION not found in CHANGELOG.md${NC}"
24
+ echo ""
25
+ echo "Please add an entry for version $CURRENT_VERSION to CHANGELOG.md"
26
+ echo ""
27
+ echo "Template:"
28
+ echo "----------------------------------------"
29
+ echo "## [$CURRENT_VERSION] - $(date +%Y-%m-%d)"
30
+ echo ""
31
+ echo "### Added"
32
+ echo "- New feature description"
33
+ echo ""
34
+ echo "### Changed"
35
+ echo "- Changed functionality description"
36
+ echo ""
37
+ echo "### Fixed"
38
+ echo "- Bug fix description"
39
+ echo "----------------------------------------"
40
+ echo ""
41
+ exit 1
42
+ fi
43
+
44
+ # Check if [Unreleased] section has content
45
+ UNRELEASED_CONTENT=$(sed -n '/## \[Unreleased\]/,/## \[[0-9]/p' CHANGELOG.md | grep -v "^## " | grep -v "^$" | wc -l)
46
+
47
+ if [ "$UNRELEASED_CONTENT" -gt 0 ]; then
48
+ echo -e "${YELLOW}⚠️ [Unreleased] section has content${NC}"
49
+ echo ""
50
+ echo "Remember to move unreleased changes to the versioned section before releasing"
51
+ echo ""
52
+ fi
53
+
54
+ # Success
55
+ echo -e "${GREEN}✅ CHANGELOG.md looks good for version $CURRENT_VERSION${NC}"
56
+
57
+ # Show recent entries
58
+ echo ""
59
+ echo "Recent entries:"
60
+ echo "----------------------------------------"
61
+ sed -n '/## \['$CURRENT_VERSION'\]/,/^## /p' CHANGELOG.md | head -20
62
+ echo "----------------------------------------"
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+ /* eslint-env node */
3
+ /* eslint-disable no-console */
4
+
5
+ const rawVersion = process.versions.node || "0.0.0";
6
+ const major = Number(rawVersion.split(".")[0] || 0);
7
+ const minMajor = 20;
8
+ const maxMajorExclusive = 23;
9
+
10
+ if (Number.isNaN(major) || major < minMajor || major >= maxMajorExclusive) {
11
+ console.error("❌ cccmemory supports Node.js 20 or 22 LTS only.");
12
+ console.error(` Detected Node.js ${rawVersion}.`);
13
+ console.error(" Please switch to Node 20/22 and reinstall:");
14
+ console.error(" - nvm install 22 && nvm use 22");
15
+ console.error(" - npm install -g cccmemory");
16
+ process.exit(1);
17
+ }
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Generate MCP configuration for local development testing.
4
+ *
5
+ * Usage: npm run dev:config
6
+ *
7
+ * This outputs the JSON configuration to add to your Claude Code settings
8
+ * for testing the local build instead of the published npm package.
9
+ */
10
+
11
+ import { resolve, dirname } from "path";
12
+ import { fileURLToPath } from "url";
13
+
14
+ const __filename = fileURLToPath(import.meta.url);
15
+ const __dirname = dirname(__filename);
16
+ const projectRoot = resolve(__dirname, "..");
17
+ const entryPoint = resolve(projectRoot, "dist", "index.js");
18
+
19
+ const config = {
20
+ "cccmemory": {
21
+ command: "node",
22
+ args: [entryPoint],
23
+ },
24
+ };
25
+
26
+ console.log(`
27
+ ╔══════════════════════════════════════════════════════════════════╗
28
+ ║ Local Development MCP Configuration ║
29
+ ╚══════════════════════════════════════════════════════════════════╝
30
+
31
+ Add this to your Claude Code MCP settings (~/.claude.json or VS Code settings):
32
+
33
+ ${JSON.stringify({ mcpServers: config }, null, 2)}
34
+
35
+ Or just the server entry:
36
+
37
+ ${JSON.stringify(config, null, 2)}
38
+
39
+ ────────────────────────────────────────────────────────────────────
40
+ Entry point: ${entryPoint}
41
+
42
+ Steps to test local changes:
43
+ 1. Make your code changes
44
+ 2. Run: npm run build
45
+ 3. Restart Claude Code (Cmd+Shift+P > "Developer: Reload Window" in VS Code)
46
+ 4. Test your changes
47
+
48
+ To switch back to published version, use:
49
+ {
50
+ "cccmemory": {
51
+ "command": "npx",
52
+ "args": ["-y", "cccmemory"]
53
+ }
54
+ }
55
+ ────────────────────────────────────────────────────────────────────
56
+ `);