codestrate 0.6.2 → 0.6.3

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 (223) hide show
  1. package/README.md +97 -101
  2. package/dist/constants.d.ts +1 -1
  3. package/dist/constants.d.ts.map +1 -1
  4. package/dist/constants.js +54 -4
  5. package/dist/constants.js.map +1 -1
  6. package/dist/index.d.ts +3 -2
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +198 -119
  9. package/dist/index.js.map +1 -1
  10. package/dist/install.d.ts +0 -0
  11. package/dist/install.d.ts.map +0 -0
  12. package/dist/install.js +2 -2
  13. package/dist/install.js.map +1 -1
  14. package/dist/profiles.d.ts +28 -0
  15. package/dist/profiles.d.ts.map +1 -0
  16. package/dist/profiles.js +89 -0
  17. package/dist/profiles.js.map +1 -0
  18. package/dist/schemas/index.d.ts +1441 -126
  19. package/dist/schemas/index.d.ts.map +1 -1
  20. package/dist/schemas/index.js +221 -10
  21. package/dist/schemas/index.js.map +1 -1
  22. package/dist/security/guard.d.ts +15 -2
  23. package/dist/security/guard.d.ts.map +1 -1
  24. package/dist/security/guard.js +42 -8
  25. package/dist/security/guard.js.map +1 -1
  26. package/dist/services/code-chunker.d.ts +50 -0
  27. package/dist/services/code-chunker.d.ts.map +1 -0
  28. package/dist/services/code-chunker.js +148 -0
  29. package/dist/services/code-chunker.js.map +1 -0
  30. package/dist/services/code-searcher.d.ts +6 -2
  31. package/dist/services/code-searcher.d.ts.map +1 -1
  32. package/dist/services/code-searcher.js +111 -17
  33. package/dist/services/code-searcher.js.map +1 -1
  34. package/dist/services/context-builder.d.ts +0 -11
  35. package/dist/services/context-builder.d.ts.map +1 -1
  36. package/dist/services/context-builder.js +74 -128
  37. package/dist/services/context-builder.js.map +1 -1
  38. package/dist/services/embedding-runtime.d.ts +41 -0
  39. package/dist/services/embedding-runtime.d.ts.map +1 -0
  40. package/dist/services/embedding-runtime.js +636 -0
  41. package/dist/services/embedding-runtime.js.map +1 -0
  42. package/dist/services/embedding.d.ts +79 -0
  43. package/dist/services/embedding.d.ts.map +1 -0
  44. package/dist/services/embedding.js +257 -0
  45. package/dist/services/embedding.js.map +1 -0
  46. package/dist/services/index-state.d.ts +74 -0
  47. package/dist/services/index-state.d.ts.map +1 -0
  48. package/dist/services/index-state.js +151 -0
  49. package/dist/services/index-state.js.map +1 -0
  50. package/dist/services/index-worker.d.ts +60 -0
  51. package/dist/services/index-worker.d.ts.map +1 -0
  52. package/dist/services/index-worker.js +182 -0
  53. package/dist/services/index-worker.js.map +1 -0
  54. package/dist/services/logger.d.ts +48 -0
  55. package/dist/services/logger.d.ts.map +1 -0
  56. package/dist/services/logger.js +106 -0
  57. package/dist/services/logger.js.map +1 -0
  58. package/dist/services/memory-store.d.ts +9 -7
  59. package/dist/services/memory-store.d.ts.map +1 -1
  60. package/dist/services/memory-store.js +93 -7
  61. package/dist/services/memory-store.js.map +1 -1
  62. package/dist/services/repository-parser.d.ts +0 -0
  63. package/dist/services/repository-parser.d.ts.map +0 -0
  64. package/dist/services/repository-parser.js +0 -0
  65. package/dist/services/repository-parser.js.map +0 -0
  66. package/dist/services/symbol-indexer.d.ts +0 -0
  67. package/dist/services/symbol-indexer.d.ts.map +1 -1
  68. package/dist/services/symbol-indexer.js +25 -13
  69. package/dist/services/symbol-indexer.js.map +1 -1
  70. package/dist/services/tree-sitter.d.ts +0 -0
  71. package/dist/services/tree-sitter.d.ts.map +0 -0
  72. package/dist/services/tree-sitter.js +0 -0
  73. package/dist/services/tree-sitter.js.map +0 -0
  74. package/dist/services/validation-runner.d.ts +0 -0
  75. package/dist/services/validation-runner.d.ts.map +1 -1
  76. package/dist/services/validation-runner.js +9 -9
  77. package/dist/services/validation-runner.js.map +1 -1
  78. package/dist/services/vector-indexer.d.ts +53 -0
  79. package/dist/services/vector-indexer.d.ts.map +1 -0
  80. package/dist/services/vector-indexer.js +230 -0
  81. package/dist/services/vector-indexer.js.map +1 -0
  82. package/dist/store/index.d.ts +0 -0
  83. package/dist/store/index.d.ts.map +0 -0
  84. package/dist/store/index.js +0 -0
  85. package/dist/store/index.js.map +0 -0
  86. package/dist/store/interface.d.ts +70 -1
  87. package/dist/store/interface.d.ts.map +1 -1
  88. package/dist/store/interface.js +0 -0
  89. package/dist/store/interface.js.map +0 -0
  90. package/dist/store/memory.d.ts +0 -0
  91. package/dist/store/memory.d.ts.map +0 -0
  92. package/dist/store/memory.js +0 -0
  93. package/dist/store/memory.js.map +0 -0
  94. package/dist/store/service.d.ts +49 -0
  95. package/dist/store/service.d.ts.map +1 -0
  96. package/dist/store/service.js +147 -0
  97. package/dist/store/service.js.map +1 -0
  98. package/dist/store/sqlite.d.ts +68 -3
  99. package/dist/store/sqlite.d.ts.map +1 -1
  100. package/dist/store/sqlite.js +708 -58
  101. package/dist/store/sqlite.js.map +1 -1
  102. package/dist/store/vector-store.d.ts +66 -0
  103. package/dist/store/vector-store.d.ts.map +1 -0
  104. package/dist/store/vector-store.js +330 -0
  105. package/dist/store/vector-store.js.map +1 -0
  106. package/dist/tools/analyze-impact.d.ts +0 -0
  107. package/dist/tools/analyze-impact.d.ts.map +1 -1
  108. package/dist/tools/analyze-impact.js +101 -39
  109. package/dist/tools/analyze-impact.js.map +1 -1
  110. package/dist/tools/deep-explore.d.ts +0 -0
  111. package/dist/tools/deep-explore.d.ts.map +1 -1
  112. package/dist/tools/deep-explore.js +18 -4
  113. package/dist/tools/deep-explore.js.map +1 -1
  114. package/dist/tools/detect-cycles.d.ts +3 -0
  115. package/dist/tools/detect-cycles.d.ts.map +1 -0
  116. package/dist/tools/detect-cycles.js +61 -0
  117. package/dist/tools/detect-cycles.js.map +1 -0
  118. package/dist/tools/detect-dead-code.d.ts +0 -0
  119. package/dist/tools/detect-dead-code.d.ts.map +1 -1
  120. package/dist/tools/detect-dead-code.js +1 -0
  121. package/dist/tools/detect-dead-code.js.map +1 -1
  122. package/dist/tools/explore.d.ts +13 -0
  123. package/dist/tools/explore.d.ts.map +1 -1
  124. package/dist/tools/explore.js +122 -88
  125. package/dist/tools/explore.js.map +1 -1
  126. package/dist/tools/get-context.d.ts +15 -0
  127. package/dist/tools/get-context.d.ts.map +1 -1
  128. package/dist/tools/get-context.js +66 -61
  129. package/dist/tools/get-context.js.map +1 -1
  130. package/dist/tools/graph-explain.d.ts +3 -0
  131. package/dist/tools/graph-explain.d.ts.map +1 -0
  132. package/dist/tools/graph-explain.js +140 -0
  133. package/dist/tools/graph-explain.js.map +1 -0
  134. package/dist/tools/graph-stats.d.ts +3 -0
  135. package/dist/tools/graph-stats.d.ts.map +1 -0
  136. package/dist/tools/graph-stats.js +73 -0
  137. package/dist/tools/graph-stats.js.map +1 -0
  138. package/dist/tools/inspect-symbol.d.ts +10 -0
  139. package/dist/tools/inspect-symbol.d.ts.map +1 -1
  140. package/dist/tools/inspect-symbol.js +112 -101
  141. package/dist/tools/inspect-symbol.js.map +1 -1
  142. package/dist/tools/ping.d.ts +0 -0
  143. package/dist/tools/ping.d.ts.map +1 -1
  144. package/dist/tools/ping.js +2 -3
  145. package/dist/tools/ping.js.map +1 -1
  146. package/dist/tools/profile.d.ts +9 -0
  147. package/dist/tools/profile.d.ts.map +1 -0
  148. package/dist/tools/profile.js +101 -0
  149. package/dist/tools/profile.js.map +1 -0
  150. package/dist/tools/query-graph.d.ts +3 -0
  151. package/dist/tools/query-graph.d.ts.map +1 -0
  152. package/dist/tools/query-graph.js +157 -0
  153. package/dist/tools/query-graph.js.map +1 -0
  154. package/dist/tools/recall-experience.d.ts +0 -0
  155. package/dist/tools/recall-experience.d.ts.map +1 -1
  156. package/dist/tools/recall-experience.js +5 -5
  157. package/dist/tools/recall-experience.js.map +1 -1
  158. package/dist/tools/record-experience.d.ts +0 -0
  159. package/dist/tools/record-experience.d.ts.map +1 -1
  160. package/dist/tools/record-experience.js +2 -5
  161. package/dist/tools/record-experience.js.map +1 -1
  162. package/dist/tools/reflect.d.ts +4 -0
  163. package/dist/tools/reflect.d.ts.map +1 -0
  164. package/dist/tools/reflect.js +99 -0
  165. package/dist/tools/reflect.js.map +1 -0
  166. package/dist/tools/register.d.ts +5 -2
  167. package/dist/tools/register.d.ts.map +1 -1
  168. package/dist/tools/register.js +31 -1
  169. package/dist/tools/register.js.map +1 -1
  170. package/dist/tools/reindex.d.ts +0 -0
  171. package/dist/tools/reindex.d.ts.map +1 -1
  172. package/dist/tools/reindex.js +102 -21
  173. package/dist/tools/reindex.js.map +1 -1
  174. package/dist/tools/repo-overview.d.ts +0 -0
  175. package/dist/tools/repo-overview.d.ts.map +1 -1
  176. package/dist/tools/repo-overview.js +8 -6
  177. package/dist/tools/repo-overview.js.map +1 -1
  178. package/dist/tools/run-validation.d.ts +0 -0
  179. package/dist/tools/run-validation.d.ts.map +1 -1
  180. package/dist/tools/run-validation.js +15 -1
  181. package/dist/tools/run-validation.js.map +1 -1
  182. package/dist/tools/search-code.d.ts +0 -0
  183. package/dist/tools/search-code.d.ts.map +1 -1
  184. package/dist/tools/search-code.js +11 -4
  185. package/dist/tools/search-code.js.map +1 -1
  186. package/dist/tools/search-history.d.ts +0 -0
  187. package/dist/tools/search-history.d.ts.map +0 -0
  188. package/dist/tools/search-history.js +0 -0
  189. package/dist/tools/search-history.js.map +0 -0
  190. package/dist/tools/session-heartbeat.d.ts +0 -0
  191. package/dist/tools/session-heartbeat.d.ts.map +1 -1
  192. package/dist/tools/session-heartbeat.js +1 -0
  193. package/dist/tools/session-heartbeat.js.map +1 -1
  194. package/dist/tools/session-status.d.ts +0 -0
  195. package/dist/tools/session-status.d.ts.map +1 -1
  196. package/dist/tools/session-status.js +1 -0
  197. package/dist/tools/session-status.js.map +1 -1
  198. package/dist/tools/status.d.ts +0 -0
  199. package/dist/tools/status.d.ts.map +1 -1
  200. package/dist/tools/status.js +87 -24
  201. package/dist/tools/status.js.map +1 -1
  202. package/dist/tools/trace-bfs.d.ts +13 -0
  203. package/dist/tools/trace-bfs.d.ts.map +1 -0
  204. package/dist/tools/trace-bfs.js +251 -0
  205. package/dist/tools/trace-bfs.js.map +1 -0
  206. package/dist/tools/trace-flow.d.ts +1 -1
  207. package/dist/tools/trace-flow.d.ts.map +1 -1
  208. package/dist/tools/trace-flow.js +113 -69
  209. package/dist/tools/trace-flow.js.map +1 -1
  210. package/dist/types.d.ts +75 -13
  211. package/dist/types.d.ts.map +1 -1
  212. package/dist/types.js +15 -0
  213. package/dist/types.js.map +1 -1
  214. package/grammars/tree-sitter-c.wasm +0 -0
  215. package/grammars/tree-sitter-cpp.wasm +0 -0
  216. package/grammars/tree-sitter-go.wasm +0 -0
  217. package/grammars/tree-sitter-java.wasm +0 -0
  218. package/grammars/tree-sitter-javascript.wasm +0 -0
  219. package/grammars/tree-sitter-python.wasm +0 -0
  220. package/grammars/tree-sitter-rust.wasm +0 -0
  221. package/grammars/tree-sitter-tsx.wasm +0 -0
  222. package/grammars/tree-sitter-typescript.wasm +0 -0
  223. package/package.json +8 -6
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Index Worker — content-hash based incremental indexing with atomic generation swap.
3
+ *
4
+ * Architecture:
5
+ * - Each index run produces an immutable "generation" stored in SQLite.
6
+ * - Files are hashed (SHA-256 of content) to detect changes.
7
+ * - Only changed files are re-parsed; unchanged entries carry forward.
8
+ * - Generation pointer is atomically swapped on success.
9
+ * - Supports cancellation via AbortSignal.
10
+ *
11
+ * This eliminates: full rebuilds on every index, blocking event loop,
12
+ * and mixed-state reads during indexing.
13
+ */
14
+ import { createHash } from "crypto";
15
+ import { readFileSync } from "fs";
16
+ import { indexSymbols } from "./symbol-indexer.js";
17
+ import { getStore } from "../store/sqlite.js";
18
+ import { createLogger } from "./logger.js";
19
+ const log = createLogger("index-worker");
20
+ // ─── Content hashing ─────────────────────────────────────
21
+ /**
22
+ * Compute SHA-256 hash of a file's content.
23
+ * Returns hex string, or null if file unreadable.
24
+ */
25
+ function fileHash(filePath) {
26
+ try {
27
+ const content = readFileSync(filePath);
28
+ return createHash("sha256").update(content).digest("hex");
29
+ }
30
+ catch {
31
+ return null;
32
+ }
33
+ }
34
+ /**
35
+ * Compare current file hashes against stored hashes to determine
36
+ * which files need re-indexing.
37
+ */
38
+ export function computeIndexPlan(allFiles) {
39
+ const store = getStore();
40
+ const previousHashes = {};
41
+ // Load previous generation metadata from SQLite
42
+ try {
43
+ const prev = store.getRepoFingerprint();
44
+ // Previous hashes stored in index_generation table
45
+ const hashRows = store.db?.prepare("SELECT file, content_hash FROM index_generation").all() ?? [];
46
+ for (const row of hashRows) {
47
+ previousHashes[row.file] = row.content_hash;
48
+ }
49
+ }
50
+ catch {
51
+ // No previous generation — full index
52
+ }
53
+ const currentFiles = new Set(allFiles.map(f => f.path));
54
+ const changed = [];
55
+ const removed = [];
56
+ const unchanged = [];
57
+ // Detect removed files
58
+ for (const prevFile of Object.keys(previousHashes)) {
59
+ if (!currentFiles.has(prevFile)) {
60
+ removed.push(prevFile);
61
+ }
62
+ }
63
+ // Detect changed/unchanged
64
+ for (const file of allFiles) {
65
+ const prevHash = previousHashes[file.path];
66
+ if (!prevHash) {
67
+ changed.push(file.path);
68
+ continue;
69
+ }
70
+ const hash = fileHash(file.path);
71
+ if (hash === null) {
72
+ removed.push(file.path);
73
+ }
74
+ else if (hash !== prevHash) {
75
+ changed.push(file.path);
76
+ }
77
+ else {
78
+ unchanged.push(file.path);
79
+ }
80
+ }
81
+ return { changed, removed, unchanged };
82
+ }
83
+ /**
84
+ * Create a new index generation, atomically swapping the active pointer.
85
+ *
86
+ * Process:
87
+ * 1. Start SQLite transaction
88
+ * 2. Parse changed files
89
+ * 3. Remove stale entries
90
+ * 4. Insert new entries + carry-forward hashes
91
+ * 5. Update generation pointer
92
+ * 6. Commit
93
+ */
94
+ export async function createGeneration(allFiles, plan, repoPath, commitSha, repoFingerprint, signal) {
95
+ if (signal?.aborted)
96
+ throw new DOMException("Index cancelled", "AbortError");
97
+ const store = getStore();
98
+ const startTime = Date.now();
99
+ log.info("Generating index", {
100
+ changed: plan.changed.length,
101
+ removed: plan.removed.length,
102
+ unchanged: plan.unchanged.length,
103
+ total: allFiles.length,
104
+ });
105
+ // Parse changed files (only parse what changed)
106
+ const filesToParse = allFiles.filter(f => plan.changed.includes(f.path) || plan.unchanged.includes(f.path));
107
+ if (signal?.aborted)
108
+ throw new DOMException("Index cancelled", "AbortError");
109
+ const { symbols, relations } = await indexSymbols({
110
+ repoPath,
111
+ files: allFiles,
112
+ commitSha,
113
+ repoFingerprint,
114
+ });
115
+ if (signal?.aborted)
116
+ throw new DOMException("Index cancelled", "AbortError");
117
+ // Atomic swap: write new generation, update pointer
118
+ store.db?.transaction(() => {
119
+ // Clear stale entries
120
+ for (const removedFile of plan.removed) {
121
+ store.removeSymbolsByFile(removedFile);
122
+ store.removeGraphForFile(removedFile);
123
+ }
124
+ // Re-insert changed file symbols
125
+ const changedSymbols = symbols.filter(s => plan.changed.includes(s.file));
126
+ if (changedSymbols.length > 0) {
127
+ // Remove and re-add for changed files
128
+ for (const file of plan.changed) {
129
+ store.removeSymbolsByFile(file);
130
+ store.removeGraphForFile(file);
131
+ }
132
+ store.addSymbols(changedSymbols);
133
+ }
134
+ // Insert relations (cleared and re-built only for changed file scope)
135
+ store.clearRelations();
136
+ store.addRelations(relations);
137
+ // Update graph
138
+ try {
139
+ store.populateGraph(symbols, relations);
140
+ }
141
+ catch (err) {
142
+ log.warn("populateGraph failed (non-fatal)", { error: String(err) });
143
+ }
144
+ })();
145
+ // Compute and store content hashes for the next incremental check
146
+ const contentHashes = {};
147
+ for (const file of allFiles) {
148
+ if (plan.changed.includes(file.path) || plan.unchanged.includes(file.path)) {
149
+ const hash = fileHash(file.path);
150
+ if (hash)
151
+ contentHashes[file.path] = hash;
152
+ }
153
+ }
154
+ const generation = {
155
+ id: Date.now(),
156
+ timestamp: new Date().toISOString(),
157
+ fileCount: allFiles.length,
158
+ symbolCount: symbols.length,
159
+ relationCount: relations.length,
160
+ contentHashes,
161
+ };
162
+ const elapsed = Date.now() - startTime;
163
+ log.info("Index generation complete", {
164
+ id: generation.id,
165
+ symbols: generation.symbolCount,
166
+ relations: generation.relationCount,
167
+ elapsedMs: elapsed,
168
+ });
169
+ return generation;
170
+ }
171
+ /**
172
+ * Full re-index (no incremental).
173
+ */
174
+ export async function fullReindex(allFiles, repoPath, commitSha, repoFingerprint, signal) {
175
+ const plan = {
176
+ changed: allFiles.map(f => f.path),
177
+ removed: [],
178
+ unchanged: [],
179
+ };
180
+ return createGeneration(allFiles, plan, repoPath, commitSha, repoFingerprint, signal);
181
+ }
182
+ //# sourceMappingURL=index-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-worker.js","sourceRoot":"","sources":["../../src/services/index-worker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Structured Logger — leveled, structured logging for observability.
3
+ *
4
+ * Provides:
5
+ * - Log levels (debug, info, warn, error)
6
+ * - Structured JSON output with timestamp, level, module, message
7
+ * - Optional OpenTelemetry-compatible span context
8
+ * - Off-by-default telemetry (privacy by default)
9
+ */
10
+ export type LogLevel = "debug" | "info" | "warn" | "error";
11
+ export type LogMetadata = Record<string, unknown>;
12
+ export interface LogEntry {
13
+ timestamp: string;
14
+ level: LogLevel;
15
+ module: string;
16
+ message: string;
17
+ metadata?: LogMetadata;
18
+ /** OpenTelemetry span ID (when telemetry is enabled) */
19
+ spanId?: string;
20
+ /** OpenTelemetry trace ID (when telemetry is enabled) */
21
+ traceId?: string;
22
+ }
23
+ /**
24
+ * Set the active log level.
25
+ */
26
+ export declare function setLogLevel(level: LogLevel): void;
27
+ /**
28
+ * Enable or disable telemetry collection.
29
+ */
30
+ export declare function setTelemetryEnabled(enabled: boolean): void;
31
+ /**
32
+ * Check if telemetry is enabled.
33
+ */
34
+ export declare function isTelemetryEnabled(): boolean;
35
+ export declare function debug(module: string, message: string, metadata?: LogMetadata): void;
36
+ export declare function info(module: string, message: string, metadata?: LogMetadata): void;
37
+ export declare function warn(module: string, message: string, metadata?: LogMetadata): void;
38
+ export declare function error(module: string, message: string, metadata?: LogMetadata): void;
39
+ /**
40
+ * Create a child logger with a fixed module prefix.
41
+ */
42
+ export declare function createLogger(module: string): {
43
+ debug: (msg: string, meta?: LogMetadata) => void;
44
+ info: (msg: string, meta?: LogMetadata) => void;
45
+ warn: (msg: string, meta?: LogMetadata) => void;
46
+ error: (msg: string, meta?: LogMetadata) => void;
47
+ };
48
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/services/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAwB3D,MAAM,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAElD,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,QAAQ,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAEjD;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE1D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AA0CD,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI,CAEnF;AAED,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI,CAElF;AAED,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI,CAElF;AAED,wBAAgB,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,GAAG,IAAI,CAEnF;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM;iBAE1B,MAAM,SAAS,WAAW;gBAC3B,MAAM,SAAS,WAAW;gBAC1B,MAAM,SAAS,WAAW;iBACzB,MAAM,SAAS,WAAW;EAE1C"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Structured Logger — leveled, structured logging for observability.
3
+ *
4
+ * Provides:
5
+ * - Log levels (debug, info, warn, error)
6
+ * - Structured JSON output with timestamp, level, module, message
7
+ * - Optional OpenTelemetry-compatible span context
8
+ * - Off-by-default telemetry (privacy by default)
9
+ */
10
+ const LOG_LEVELS = {
11
+ debug: 0,
12
+ info: 1,
13
+ warn: 2,
14
+ error: 3,
15
+ };
16
+ const LOG_LEVEL_NAMES = {
17
+ debug: "DBG",
18
+ info: "INF",
19
+ warn: "WRN",
20
+ error: "ERR",
21
+ };
22
+ let currentLevel = process.env.CI_MCP_LOG_LEVEL === "debug" ? "debug"
23
+ : process.env.CI_MCP_LOG_LEVEL === "info" ? "info"
24
+ : process.env.CI_MCP_LOG_LEVEL === "warn" ? "warn"
25
+ : process.env.CI_MCP_LOG_LEVEL === "error" ? "error"
26
+ : "info";
27
+ let telemetryEnabled = process.env.CI_MCP_TELEMETRY === "1";
28
+ /**
29
+ * Set the active log level.
30
+ */
31
+ export function setLogLevel(level) {
32
+ currentLevel = level;
33
+ }
34
+ /**
35
+ * Enable or disable telemetry collection.
36
+ */
37
+ export function setTelemetryEnabled(enabled) {
38
+ telemetryEnabled = enabled;
39
+ }
40
+ /**
41
+ * Check if telemetry is enabled.
42
+ */
43
+ export function isTelemetryEnabled() {
44
+ return telemetryEnabled;
45
+ }
46
+ /**
47
+ * Format a log entry as structured JSON (for production parsing)
48
+ * or as human-readable text (for stderr).
49
+ */
50
+ function formatEntry(entry, json) {
51
+ if (json) {
52
+ return JSON.stringify(entry);
53
+ }
54
+ const prefix = `[${entry.timestamp}] [${LOG_LEVEL_NAMES[entry.level]}] [${entry.module}]`;
55
+ const meta = entry.metadata ? ` ${JSON.stringify(entry.metadata)}` : "";
56
+ return `${prefix} ${entry.message}${meta}`;
57
+ }
58
+ function shouldLog(level) {
59
+ return LOG_LEVELS[level] >= LOG_LEVELS[currentLevel];
60
+ }
61
+ function log(level, module, message, metadata) {
62
+ if (!shouldLog(level))
63
+ return;
64
+ const entry = {
65
+ timestamp: new Date().toISOString(),
66
+ level,
67
+ module,
68
+ message,
69
+ metadata,
70
+ };
71
+ const output = formatEntry(entry, false);
72
+ if (level === "error") {
73
+ console.error(output);
74
+ }
75
+ else if (level === "warn") {
76
+ console.warn(output);
77
+ }
78
+ else {
79
+ console.log(output);
80
+ }
81
+ }
82
+ // ─── Public API ──────────────────────────────────────────
83
+ export function debug(module, message, metadata) {
84
+ log("debug", module, message, metadata);
85
+ }
86
+ export function info(module, message, metadata) {
87
+ log("info", module, message, metadata);
88
+ }
89
+ export function warn(module, message, metadata) {
90
+ log("warn", module, message, metadata);
91
+ }
92
+ export function error(module, message, metadata) {
93
+ log("error", module, message, metadata);
94
+ }
95
+ /**
96
+ * Create a child logger with a fixed module prefix.
97
+ */
98
+ export function createLogger(module) {
99
+ return {
100
+ debug: (msg, meta) => debug(module, msg, meta),
101
+ info: (msg, meta) => info(module, msg, meta),
102
+ warn: (msg, meta) => warn(module, msg, meta),
103
+ error: (msg, meta) => error(module, msg, meta),
104
+ };
105
+ }
106
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/services/logger.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,10 @@
1
1
  /**
2
2
  * Memory Store Service — business logic for memory/experience management.
3
- * Delegates persistence to store/memory.ts, adds validation and quality scoring.
3
+ * Uses SQLite as single source of truth via store/service.ts.
4
4
  */
5
- import { searchExperiences, searchMemories, recallAll, loadMemoryStore, saveMemoryStore } from "../store/memory.js";
5
+ import { getAllExperiences, getAllMemories } from "../store/service.js";
6
6
  import type { Experience, ExperienceEvidence, Memory, MemoryType } from "../types.js";
7
- export { loadMemoryStore, saveMemoryStore, searchExperiences, searchMemories, recallAll };
8
- /**
9
- * Store a verified experience. Only accepts with complete evidence.
10
- */
7
+ export { getAllExperiences, getAllMemories };
11
8
  export declare function storeExperience(input: {
12
9
  task: string;
13
10
  diagnosis: string;
@@ -25,7 +22,12 @@ export declare function storeExperience(input: {
25
22
  export declare function storeKnowledge(type: MemoryType, content: string, symbols: string[], files: string[], commit: string | null, repo: string): Memory;
26
23
  /**
27
24
  * Hybrid recall combining experiences and memories.
25
+ * Falls back to list-based recall since SQLiteStore doesn't have
26
+ * semantic search yet.
28
27
  */
29
28
  export declare function hybridRecall(query: string, repo?: string, topK?: number, types?: MemoryType[]): (Experience | Memory)[];
30
- export { getExperience } from "../store/memory.js";
29
+ /**
30
+ * Get a single experience by ID.
31
+ */
32
+ export declare function getExperience(id: string): Experience | undefined;
31
33
  //# sourceMappingURL=memory-store.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../src/services/memory-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAEL,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,eAAe,EACf,eAAe,EAEhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEtF,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC;AAE1F;;GAEG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE;IACL,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,EACD,QAAQ,EAAE,kBAAkB,EAC5B,eAAe,EAAE,MAAM,GACtB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAGjC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,IAAI,EAAE,MAAM,GACX,MAAM,CAER;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,EACb,IAAI,GAAE,MAAU,EAChB,KAAK,CAAC,EAAE,UAAU,EAAE,GACnB,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,CAEzB;AAED,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../src/services/memory-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EACL,iBAAiB,EACjB,cAAc,EAEf,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAItF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,CAAC;AA4B7C,wBAAgB,eAAe,CAC7B,KAAK,EAAE;IACL,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B,EACD,QAAQ,EAAE,kBAAkB,EAC5B,eAAe,EAAE,MAAM,GACtB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAgCjC;AAED;;GAEG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EAAE,EACjB,KAAK,EAAE,MAAM,EAAE,EACf,MAAM,EAAE,MAAM,GAAG,IAAI,EACrB,IAAI,EAAE,MAAM,GACX,MAAM,CAeR;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE,MAAM,EACb,IAAI,GAAE,MAAU,EAChB,KAAK,CAAC,EAAE,UAAU,EAAE,GACnB,CAAC,UAAU,GAAG,MAAM,CAAC,EAAE,CAuBzB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAEhE"}
@@ -1,27 +1,113 @@
1
1
  /**
2
2
  * Memory Store Service — business logic for memory/experience management.
3
- * Delegates persistence to store/memory.ts, adds validation and quality scoring.
3
+ * Uses SQLite as single source of truth via store/service.ts.
4
4
  */
5
- import { addExperience as storeAddExperience, searchExperiences, searchMemories, recallAll, loadMemoryStore, saveMemoryStore, addMemory as storeAddMemory, } from "../store/memory.js";
6
- export { loadMemoryStore, saveMemoryStore, searchExperiences, searchMemories, recallAll };
5
+ import { getStore } from "../store/sqlite.js";
6
+ import { loadConfig } from "../constants.js";
7
+ import * as fs from "fs";
8
+ import * as path from "path";
9
+ import { getAllExperiences, getAllMemories, getExperience as serviceGetExperience, } from "../store/service.js";
10
+ // ─── Re-export SQLite-backed operations ────────────────
11
+ export { getAllExperiences, getAllMemories };
7
12
  /**
8
13
  * Store a verified experience. Only accepts with complete evidence.
9
14
  */
15
+ function updateSteeringFile(repoPath, experiences) {
16
+ const claudeMdPath = path.join(repoPath, "CLAUDE.md");
17
+ const cursorrulesPath = path.join(repoPath, ".cursorrules");
18
+ const targetPath = fs.existsSync(claudeMdPath) ? claudeMdPath : cursorrulesPath;
19
+ const rules = experiences.map(e => `- ${e.task}: ${e.solution.substring(0, 100)}`).join("\n");
20
+ const steeringContent = `# Coding Intelligence MCP — Steering Rules
21
+
22
+ **Core Workflow:**
23
+ 1. Khởi động task bằng \`ci_get_context\` để lấy Canvas (Bản đồ Mermaid).
24
+ 2. Dùng ID trên Canvas để drill-down chi tiết (Chỉ lật file khi cần thiết).
25
+ 3. Gọi \`ci_run_validation\` sau mỗi lần sửa (Log lỗi dài sẽ tự động được offload, chỉ trả về error canvas).
26
+ 4. Gọi \`ci_record_experience\` sau khi fix thành công (Lưu thành L1 Memory).
27
+
28
+ **Codebase SOPs (L3 Memory - Generated from past experiences):**
29
+ ${rules}
30
+ `;
31
+ fs.writeFileSync(targetPath, steeringContent, "utf8");
32
+ }
10
33
  export function storeExperience(input, evidence, repoFingerprint) {
11
- const exp = storeAddExperience(input, evidence, repoFingerprint);
34
+ // Compute quality from evidence
35
+ const quality = Math.min(1.0, (evidence.buildPassed ? 0.3 : 0) +
36
+ (evidence.testsPassed ? 0.3 : 0) +
37
+ (evidence.humanAccepted ? 0.2 : 0) +
38
+ (evidence.commitCreated ? 0.2 : 0)) || 0.5;
39
+ const exp = {
40
+ id: `exp-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
41
+ type: "episodic",
42
+ task: input.task,
43
+ diagnosis: input.diagnosis,
44
+ solution: input.solution,
45
+ changedFiles: input.changedFiles,
46
+ commit: input.commit,
47
+ failedAttempts: input.failedAttempts,
48
+ validation: [],
49
+ evidence,
50
+ quality,
51
+ timestamp: new Date().toISOString(),
52
+ repo: repoFingerprint,
53
+ };
54
+ getStore().addExperience(exp);
55
+ const config = loadConfig();
56
+ const allExperiences = getAllExperiences(repoFingerprint) ?? [];
57
+ if (config.repoPath) {
58
+ updateSteeringFile(config.repoPath, allExperiences);
59
+ }
12
60
  return { id: exp.id, quality: exp.quality };
13
61
  }
14
62
  /**
15
63
  * Store unvalidated knowledge (semantic, procedural, negative).
16
64
  */
17
65
  export function storeKnowledge(type, content, symbols, files, commit, repo) {
18
- return storeAddMemory({ type, content, symbols, files, commit, repo, source: "manual" });
66
+ const mem = {
67
+ id: `mem-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
68
+ type,
69
+ content,
70
+ symbols,
71
+ files,
72
+ commit,
73
+ repo,
74
+ source: "manual",
75
+ quality: 0.5,
76
+ timestamp: new Date().toISOString(),
77
+ };
78
+ getStore().addMemory(mem);
79
+ return mem;
19
80
  }
20
81
  /**
21
82
  * Hybrid recall combining experiences and memories.
83
+ * Falls back to list-based recall since SQLiteStore doesn't have
84
+ * semantic search yet.
22
85
  */
23
86
  export function hybridRecall(query, repo, topK = 5, types) {
24
- return recallAll(query, repo, topK, types);
87
+ const allExperiences = getAllExperiences(repo) ?? [];
88
+ const allMemories = getAllMemories(repo) ?? [];
89
+ // Simple lexical scoring: count query term matches
90
+ const terms = query.toLowerCase().split(/\s+/);
91
+ function score(item) {
92
+ const text = [item.content, item.task, item.observation]
93
+ .filter(Boolean).join(" ").toLowerCase();
94
+ return terms.filter(t => text.includes(t)).length / terms.length;
95
+ }
96
+ const results = [
97
+ ...allExperiences,
98
+ ...allMemories,
99
+ ]
100
+ .map(item => ({ item, score: score(item) }))
101
+ .filter(({ score }) => score > 0)
102
+ .sort((a, b) => b.score - a.score)
103
+ .slice(0, topK)
104
+ .map(({ item }) => item);
105
+ return results;
106
+ }
107
+ /**
108
+ * Get a single experience by ID.
109
+ */
110
+ export function getExperience(id) {
111
+ return serviceGetExperience(id);
25
112
  }
26
- export { getExperience } from "../store/memory.js";
27
113
  //# sourceMappingURL=memory-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../src/services/memory-store.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,aAAa,IAAI,kBAAkB,EACnC,iBAAiB,EACjB,cAAc,EACd,SAAS,EACT,eAAe,EACf,eAAe,EACf,SAAS,IAAI,cAAc,GAC5B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,iBAAiB,EAAE,cAAc,EAAE,SAAS,EAAE,CAAC;AAE1F;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,KAOC,EACD,QAA4B,EAC5B,eAAuB;IAEvB,MAAM,GAAG,GAAG,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,eAAe,CAAC,CAAC;IACjE,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;AAC9C,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAgB,EAChB,OAAe,EACf,OAAiB,EACjB,KAAe,EACf,MAAqB,EACrB,IAAY;IAEZ,OAAO,cAAc,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC3F,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAC1B,KAAa,EACb,IAAa,EACb,OAAe,CAAC,EAChB,KAAoB;IAEpB,OAAO,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;AAC7C,CAAC;AAED,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../src/services/memory-store.ts"],"names":[],"mappings":"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"}
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -1 +1 @@
1
- {"version":3,"file":"symbol-indexer.d.ts","sourceRoot":"","sources":["../../src/services/symbol-indexer.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAc,cAAc,EAAE,MAAM,aAAa,CAAC;AAE1E,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB;AAwJD,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC;IAC9D,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B,CAAC,CA4ID"}
1
+ {"version":3,"file":"symbol-indexer.d.ts","sourceRoot":"","sources":["../../src/services/symbol-indexer.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,UAAU,EAAc,cAAc,EAAE,MAAM,aAAa,CAAC;AAoB1E,UAAU,YAAY;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CACzB;AAwJD,wBAAsB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC;IAC9D,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,SAAS,EAAE,cAAc,EAAE,CAAC;CAC7B,CAAC,CA2ID"}