codesift-mcp 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 (177) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +241 -0
  3. package/dist/cli/args.d.ts +13 -0
  4. package/dist/cli/args.d.ts.map +1 -0
  5. package/dist/cli/args.js +79 -0
  6. package/dist/cli/args.js.map +1 -0
  7. package/dist/cli/commands.d.ts +4 -0
  8. package/dist/cli/commands.d.ts.map +1 -0
  9. package/dist/cli/commands.js +336 -0
  10. package/dist/cli/commands.js.map +1 -0
  11. package/dist/cli/help.d.ts +3 -0
  12. package/dist/cli/help.d.ts.map +1 -0
  13. package/dist/cli/help.js +271 -0
  14. package/dist/cli/help.js.map +1 -0
  15. package/dist/cli.d.ts +3 -0
  16. package/dist/cli.d.ts.map +1 -0
  17. package/dist/cli.js +80 -0
  18. package/dist/cli.js.map +1 -0
  19. package/dist/config.d.ts +23 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js +49 -0
  22. package/dist/config.js.map +1 -0
  23. package/dist/parser/extractors/go.d.ts +4 -0
  24. package/dist/parser/extractors/go.d.ts.map +1 -0
  25. package/dist/parser/extractors/go.js +185 -0
  26. package/dist/parser/extractors/go.js.map +1 -0
  27. package/dist/parser/extractors/javascript.d.ts +9 -0
  28. package/dist/parser/extractors/javascript.d.ts.map +1 -0
  29. package/dist/parser/extractors/javascript.js +10 -0
  30. package/dist/parser/extractors/javascript.js.map +1 -0
  31. package/dist/parser/extractors/markdown.d.ts +15 -0
  32. package/dist/parser/extractors/markdown.d.ts.map +1 -0
  33. package/dist/parser/extractors/markdown.js +217 -0
  34. package/dist/parser/extractors/markdown.js.map +1 -0
  35. package/dist/parser/extractors/prisma.d.ts +17 -0
  36. package/dist/parser/extractors/prisma.d.ts.map +1 -0
  37. package/dist/parser/extractors/prisma.js +121 -0
  38. package/dist/parser/extractors/prisma.js.map +1 -0
  39. package/dist/parser/extractors/python.d.ts +4 -0
  40. package/dist/parser/extractors/python.d.ts.map +1 -0
  41. package/dist/parser/extractors/python.js +203 -0
  42. package/dist/parser/extractors/python.js.map +1 -0
  43. package/dist/parser/extractors/rust.d.ts +4 -0
  44. package/dist/parser/extractors/rust.d.ts.map +1 -0
  45. package/dist/parser/extractors/rust.js +178 -0
  46. package/dist/parser/extractors/rust.js.map +1 -0
  47. package/dist/parser/extractors/typescript.d.ts +4 -0
  48. package/dist/parser/extractors/typescript.d.ts.map +1 -0
  49. package/dist/parser/extractors/typescript.js +296 -0
  50. package/dist/parser/extractors/typescript.js.map +1 -0
  51. package/dist/parser/languages/tree-sitter-css.wasm +0 -0
  52. package/dist/parser/languages/tree-sitter-go.wasm +0 -0
  53. package/dist/parser/languages/tree-sitter-java.wasm +0 -0
  54. package/dist/parser/languages/tree-sitter-javascript.wasm +0 -0
  55. package/dist/parser/languages/tree-sitter-json.wasm +0 -0
  56. package/dist/parser/languages/tree-sitter-php.wasm +0 -0
  57. package/dist/parser/languages/tree-sitter-python.wasm +0 -0
  58. package/dist/parser/languages/tree-sitter-ruby.wasm +0 -0
  59. package/dist/parser/languages/tree-sitter-rust.wasm +0 -0
  60. package/dist/parser/languages/tree-sitter-tsx.wasm +0 -0
  61. package/dist/parser/languages/tree-sitter-typescript.wasm +0 -0
  62. package/dist/parser/parser-manager.d.ts +6 -0
  63. package/dist/parser/parser-manager.d.ts.map +1 -0
  64. package/dist/parser/parser-manager.js +60 -0
  65. package/dist/parser/parser-manager.js.map +1 -0
  66. package/dist/parser/symbol-extractor.d.ts +22 -0
  67. package/dist/parser/symbol-extractor.d.ts.map +1 -0
  68. package/dist/parser/symbol-extractor.js +115 -0
  69. package/dist/parser/symbol-extractor.js.map +1 -0
  70. package/dist/retrieval/codebase-retrieval.d.ts +27 -0
  71. package/dist/retrieval/codebase-retrieval.d.ts.map +1 -0
  72. package/dist/retrieval/codebase-retrieval.js +472 -0
  73. package/dist/retrieval/codebase-retrieval.js.map +1 -0
  74. package/dist/search/bm25.d.ts +22 -0
  75. package/dist/search/bm25.d.ts.map +1 -0
  76. package/dist/search/bm25.js +179 -0
  77. package/dist/search/bm25.js.map +1 -0
  78. package/dist/search/chunker.d.ts +9 -0
  79. package/dist/search/chunker.d.ts.map +1 -0
  80. package/dist/search/chunker.js +91 -0
  81. package/dist/search/chunker.js.map +1 -0
  82. package/dist/search/hybrid.d.ts +16 -0
  83. package/dist/search/hybrid.d.ts.map +1 -0
  84. package/dist/search/hybrid.js +51 -0
  85. package/dist/search/hybrid.js.map +1 -0
  86. package/dist/search/semantic.d.ts +44 -0
  87. package/dist/search/semantic.d.ts.map +1 -0
  88. package/dist/search/semantic.js +194 -0
  89. package/dist/search/semantic.js.map +1 -0
  90. package/dist/server.d.ts +2 -0
  91. package/dist/server.d.ts.map +1 -0
  92. package/dist/server.js +285 -0
  93. package/dist/server.js.map +1 -0
  94. package/dist/storage/chunk-store.d.ts +32 -0
  95. package/dist/storage/chunk-store.d.ts.map +1 -0
  96. package/dist/storage/chunk-store.js +144 -0
  97. package/dist/storage/chunk-store.js.map +1 -0
  98. package/dist/storage/embedding-store.d.ts +41 -0
  99. package/dist/storage/embedding-store.d.ts.map +1 -0
  100. package/dist/storage/embedding-store.js +149 -0
  101. package/dist/storage/embedding-store.js.map +1 -0
  102. package/dist/storage/index-store.d.ts +23 -0
  103. package/dist/storage/index-store.d.ts.map +1 -0
  104. package/dist/storage/index-store.js +95 -0
  105. package/dist/storage/index-store.js.map +1 -0
  106. package/dist/storage/registry.d.ts +35 -0
  107. package/dist/storage/registry.d.ts.map +1 -0
  108. package/dist/storage/registry.js +99 -0
  109. package/dist/storage/registry.js.map +1 -0
  110. package/dist/storage/usage-stats.d.ts +32 -0
  111. package/dist/storage/usage-stats.d.ts.map +1 -0
  112. package/dist/storage/usage-stats.js +180 -0
  113. package/dist/storage/usage-stats.js.map +1 -0
  114. package/dist/storage/usage-tracker.d.ts +35 -0
  115. package/dist/storage/usage-tracker.d.ts.map +1 -0
  116. package/dist/storage/usage-tracker.js +245 -0
  117. package/dist/storage/usage-tracker.js.map +1 -0
  118. package/dist/storage/watcher.d.ts +12 -0
  119. package/dist/storage/watcher.d.ts.map +1 -0
  120. package/dist/storage/watcher.js +66 -0
  121. package/dist/storage/watcher.js.map +1 -0
  122. package/dist/tools/context-tools.d.ts +31 -0
  123. package/dist/tools/context-tools.d.ts.map +1 -0
  124. package/dist/tools/context-tools.js +219 -0
  125. package/dist/tools/context-tools.js.map +1 -0
  126. package/dist/tools/diff-tools.d.ts +22 -0
  127. package/dist/tools/diff-tools.d.ts.map +1 -0
  128. package/dist/tools/diff-tools.js +165 -0
  129. package/dist/tools/diff-tools.js.map +1 -0
  130. package/dist/tools/generate-tools.d.ts +11 -0
  131. package/dist/tools/generate-tools.d.ts.map +1 -0
  132. package/dist/tools/generate-tools.js +135 -0
  133. package/dist/tools/generate-tools.js.map +1 -0
  134. package/dist/tools/graph-tools.d.ts +60 -0
  135. package/dist/tools/graph-tools.d.ts.map +1 -0
  136. package/dist/tools/graph-tools.js +313 -0
  137. package/dist/tools/graph-tools.js.map +1 -0
  138. package/dist/tools/index-tools.d.ts +39 -0
  139. package/dist/tools/index-tools.d.ts.map +1 -0
  140. package/dist/tools/index-tools.js +451 -0
  141. package/dist/tools/index-tools.js.map +1 -0
  142. package/dist/tools/outline-tools.d.ts +59 -0
  143. package/dist/tools/outline-tools.d.ts.map +1 -0
  144. package/dist/tools/outline-tools.js +342 -0
  145. package/dist/tools/outline-tools.js.map +1 -0
  146. package/dist/tools/search-tools.d.ts +29 -0
  147. package/dist/tools/search-tools.d.ts.map +1 -0
  148. package/dist/tools/search-tools.js +309 -0
  149. package/dist/tools/search-tools.js.map +1 -0
  150. package/dist/tools/symbol-tools.d.ts +24 -0
  151. package/dist/tools/symbol-tools.d.ts.map +1 -0
  152. package/dist/tools/symbol-tools.js +172 -0
  153. package/dist/tools/symbol-tools.js.map +1 -0
  154. package/dist/types.d.ts +91 -0
  155. package/dist/types.d.ts.map +1 -0
  156. package/dist/types.js +3 -0
  157. package/dist/types.js.map +1 -0
  158. package/dist/utils/git-validation.d.ts +11 -0
  159. package/dist/utils/git-validation.d.ts.map +1 -0
  160. package/dist/utils/git-validation.js +19 -0
  161. package/dist/utils/git-validation.js.map +1 -0
  162. package/dist/utils/test-file.d.ts +11 -0
  163. package/dist/utils/test-file.d.ts.map +1 -0
  164. package/dist/utils/test-file.js +27 -0
  165. package/dist/utils/test-file.js.map +1 -0
  166. package/package.json +62 -0
  167. package/src/parser/languages/tree-sitter-css.wasm +0 -0
  168. package/src/parser/languages/tree-sitter-go.wasm +0 -0
  169. package/src/parser/languages/tree-sitter-java.wasm +0 -0
  170. package/src/parser/languages/tree-sitter-javascript.wasm +0 -0
  171. package/src/parser/languages/tree-sitter-json.wasm +0 -0
  172. package/src/parser/languages/tree-sitter-php.wasm +0 -0
  173. package/src/parser/languages/tree-sitter-python.wasm +0 -0
  174. package/src/parser/languages/tree-sitter-ruby.wasm +0 -0
  175. package/src/parser/languages/tree-sitter-rust.wasm +0 -0
  176. package/src/parser/languages/tree-sitter-tsx.wasm +0 -0
  177. package/src/parser/languages/tree-sitter-typescript.wasm +0 -0
@@ -0,0 +1,35 @@
1
+ export interface UsageEntry {
2
+ ts: number;
3
+ tool: string;
4
+ repo: string;
5
+ args_summary: Record<string, unknown>;
6
+ elapsed_ms: number;
7
+ result_tokens: number;
8
+ result_chunks: number;
9
+ session_id: string;
10
+ }
11
+ /**
12
+ * Build a lightweight args summary for a given tool call.
13
+ * Extracts only the small, useful fields — never full source or query results.
14
+ */
15
+ export declare function buildArgsSummary(tool: string, args: Record<string, unknown>): Record<string, unknown>;
16
+ /**
17
+ * Estimate the number of discrete result items (chunks, symbols, files, etc.)
18
+ * from the tool result object.
19
+ */
20
+ export declare function extractResultChunks(data: unknown): number;
21
+ /**
22
+ * Log a usage entry to ~/.codesift/usage.jsonl.
23
+ * Non-blocking: errors are silently caught and logged to stderr.
24
+ */
25
+ export declare function trackUsage(entry: UsageEntry): Promise<void>;
26
+ /**
27
+ * High-level helper: track a completed tool call.
28
+ * Called at the end of each tool handler after the result is computed.
29
+ */
30
+ export declare function trackToolCall(tool: string, args: Record<string, unknown>, resultText: string, resultData: unknown, elapsedMs: number): void;
31
+ /**
32
+ * Get the current session ID (for testing or display).
33
+ */
34
+ export declare function getSessionId(): string;
35
+ //# sourceMappingURL=usage-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-tracker.d.ts","sourceRoot":"","sources":["../../src/storage/usage-tracker.ts"],"names":[],"mappings":"AAeA,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;CACpB;AAeD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiIzB;AAMD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAqBzD;AAQD;;;GAGG;AACH,wBAAsB,UAAU,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAiBjE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,OAAO,EACnB,SAAS,EAAE,MAAM,GAChB,IAAI,CAcN;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,CAErC"}
@@ -0,0 +1,245 @@
1
+ import { appendFile, mkdir } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { homedir } from "node:os";
4
+ import { randomUUID } from "node:crypto";
5
+ // ---------------------------------------------------------------------------
6
+ // Session ID — unique per process lifetime
7
+ // ---------------------------------------------------------------------------
8
+ const SESSION_ID = randomUUID();
9
+ // ---------------------------------------------------------------------------
10
+ // Path
11
+ // ---------------------------------------------------------------------------
12
+ function getUsagePath() {
13
+ const dataDir = process.env["CODESIFT_DATA_DIR"] ?? join(homedir(), ".codesift");
14
+ return join(dataDir, "usage.jsonl");
15
+ }
16
+ // ---------------------------------------------------------------------------
17
+ // Args summary builders — lightweight, never includes large content
18
+ // ---------------------------------------------------------------------------
19
+ /**
20
+ * Build a lightweight args summary for a given tool call.
21
+ * Extracts only the small, useful fields — never full source or query results.
22
+ */
23
+ export function buildArgsSummary(tool, args) {
24
+ const summary = {};
25
+ // Common fields — always include if present
26
+ if (typeof args["query"] === "string") {
27
+ summary["query"] = args["query"].slice(0, 200);
28
+ }
29
+ if (typeof args["repo"] === "string") {
30
+ summary["repo"] = args["repo"];
31
+ }
32
+ switch (tool) {
33
+ case "codebase_retrieval": {
34
+ const queries = args["queries"];
35
+ if (Array.isArray(queries)) {
36
+ summary["query_count"] = queries.length;
37
+ summary["query_types"] = queries.map((q) => (typeof q === "object" && q !== null ? q["type"] : "unknown"));
38
+ }
39
+ if (typeof args["token_budget"] === "number") {
40
+ summary["token_budget"] = args["token_budget"];
41
+ }
42
+ break;
43
+ }
44
+ case "search_symbols": {
45
+ if (typeof args["kind"] === "string")
46
+ summary["kind"] = args["kind"];
47
+ if (typeof args["top_k"] === "number")
48
+ summary["top_k"] = args["top_k"];
49
+ if (typeof args["file_pattern"] === "string")
50
+ summary["file_pattern"] = args["file_pattern"];
51
+ if (typeof args["include_source"] === "boolean")
52
+ summary["include_source"] = args["include_source"];
53
+ break;
54
+ }
55
+ case "search_text": {
56
+ if (typeof args["regex"] === "boolean")
57
+ summary["regex"] = args["regex"];
58
+ if (typeof args["context_lines"] === "number")
59
+ summary["context_lines"] = args["context_lines"];
60
+ if (typeof args["file_pattern"] === "string")
61
+ summary["file_pattern"] = args["file_pattern"];
62
+ if (typeof args["max_results"] === "number")
63
+ summary["max_results"] = args["max_results"];
64
+ break;
65
+ }
66
+ case "get_file_tree": {
67
+ if (typeof args["path_prefix"] === "string")
68
+ summary["path_prefix"] = args["path_prefix"];
69
+ if (typeof args["name_pattern"] === "string")
70
+ summary["name_pattern"] = args["name_pattern"];
71
+ if (typeof args["depth"] === "number")
72
+ summary["depth"] = args["depth"];
73
+ break;
74
+ }
75
+ case "get_file_outline": {
76
+ if (typeof args["file_path"] === "string")
77
+ summary["file_path"] = args["file_path"];
78
+ break;
79
+ }
80
+ case "get_symbol": {
81
+ if (typeof args["symbol_id"] === "string")
82
+ summary["symbol_id"] = args["symbol_id"];
83
+ break;
84
+ }
85
+ case "get_symbols": {
86
+ const ids = args["symbol_ids"];
87
+ if (Array.isArray(ids))
88
+ summary["symbol_count"] = ids.length;
89
+ break;
90
+ }
91
+ case "find_and_show": {
92
+ if (typeof args["include_refs"] === "boolean")
93
+ summary["include_refs"] = args["include_refs"];
94
+ break;
95
+ }
96
+ case "find_references": {
97
+ if (typeof args["symbol_name"] === "string")
98
+ summary["symbol_name"] = args["symbol_name"];
99
+ if (typeof args["file_pattern"] === "string")
100
+ summary["file_pattern"] = args["file_pattern"];
101
+ break;
102
+ }
103
+ case "trace_call_chain": {
104
+ if (typeof args["symbol_name"] === "string")
105
+ summary["symbol_name"] = args["symbol_name"];
106
+ if (typeof args["direction"] === "string")
107
+ summary["direction"] = args["direction"];
108
+ if (typeof args["depth"] === "number")
109
+ summary["depth"] = args["depth"];
110
+ break;
111
+ }
112
+ case "impact_analysis": {
113
+ if (typeof args["since"] === "string")
114
+ summary["since"] = args["since"];
115
+ if (typeof args["until"] === "string")
116
+ summary["until"] = args["until"];
117
+ if (typeof args["depth"] === "number")
118
+ summary["depth"] = args["depth"];
119
+ break;
120
+ }
121
+ case "assemble_context": {
122
+ if (typeof args["token_budget"] === "number")
123
+ summary["token_budget"] = args["token_budget"];
124
+ break;
125
+ }
126
+ case "get_knowledge_map": {
127
+ if (typeof args["focus"] === "string")
128
+ summary["focus"] = args["focus"];
129
+ if (typeof args["depth"] === "number")
130
+ summary["depth"] = args["depth"];
131
+ break;
132
+ }
133
+ case "diff_outline":
134
+ case "changed_symbols": {
135
+ if (typeof args["since"] === "string")
136
+ summary["since"] = args["since"];
137
+ if (typeof args["until"] === "string")
138
+ summary["until"] = args["until"];
139
+ break;
140
+ }
141
+ case "index_folder": {
142
+ if (typeof args["path"] === "string")
143
+ summary["path"] = args["path"];
144
+ if (typeof args["incremental"] === "boolean")
145
+ summary["incremental"] = args["incremental"];
146
+ break;
147
+ }
148
+ case "index_repo": {
149
+ if (typeof args["url"] === "string")
150
+ summary["url"] = args["url"];
151
+ if (typeof args["branch"] === "string")
152
+ summary["branch"] = args["branch"];
153
+ break;
154
+ }
155
+ case "generate_claude_md": {
156
+ if (typeof args["output_path"] === "string")
157
+ summary["output_path"] = args["output_path"];
158
+ break;
159
+ }
160
+ // list_repos, invalidate_cache, get_repo_outline, usage_stats — no extra args needed
161
+ }
162
+ return summary;
163
+ }
164
+ // ---------------------------------------------------------------------------
165
+ // Result metrics extraction
166
+ // ---------------------------------------------------------------------------
167
+ /**
168
+ * Estimate the number of discrete result items (chunks, symbols, files, etc.)
169
+ * from the tool result object.
170
+ */
171
+ export function extractResultChunks(data) {
172
+ if (Array.isArray(data))
173
+ return data.length;
174
+ if (typeof data === "object" && data !== null) {
175
+ const obj = data;
176
+ // codebase_retrieval → results array
177
+ if (Array.isArray(obj["results"]))
178
+ return obj["results"].length;
179
+ // various tools returning arrays under common keys
180
+ if (Array.isArray(obj["symbols"]))
181
+ return obj["symbols"].length;
182
+ if (Array.isArray(obj["files"]))
183
+ return obj["files"].length;
184
+ if (Array.isArray(obj["matches"]))
185
+ return obj["matches"].length;
186
+ if (Array.isArray(obj["references"]))
187
+ return obj["references"].length;
188
+ if (Array.isArray(obj["repos"]))
189
+ return obj["repos"].length;
190
+ // single item results
191
+ if (typeof obj["id"] === "string")
192
+ return 1;
193
+ }
194
+ return 0;
195
+ }
196
+ // ---------------------------------------------------------------------------
197
+ // Core tracking function
198
+ // ---------------------------------------------------------------------------
199
+ let dirEnsured = false;
200
+ /**
201
+ * Log a usage entry to ~/.codesift/usage.jsonl.
202
+ * Non-blocking: errors are silently caught and logged to stderr.
203
+ */
204
+ export async function trackUsage(entry) {
205
+ try {
206
+ const usagePath = getUsagePath();
207
+ if (!dirEnsured) {
208
+ const dataDir = process.env["CODESIFT_DATA_DIR"] ?? join(homedir(), ".codesift");
209
+ await mkdir(dataDir, { recursive: true });
210
+ dirEnsured = true;
211
+ }
212
+ const line = JSON.stringify(entry) + "\n";
213
+ await appendFile(usagePath, line, "utf-8");
214
+ }
215
+ catch (err) {
216
+ // Never throw — tracking is best-effort
217
+ const message = err instanceof Error ? err.message : String(err);
218
+ console.error(`[usage-tracker] Failed to log usage: ${message}`);
219
+ }
220
+ }
221
+ /**
222
+ * High-level helper: track a completed tool call.
223
+ * Called at the end of each tool handler after the result is computed.
224
+ */
225
+ export function trackToolCall(tool, args, resultText, resultData, elapsedMs) {
226
+ const entry = {
227
+ ts: Date.now(),
228
+ tool,
229
+ repo: typeof args["repo"] === "string" ? args["repo"] : "",
230
+ args_summary: buildArgsSummary(tool, args),
231
+ elapsed_ms: Math.round(elapsedMs),
232
+ result_tokens: Math.ceil(resultText.length / 4),
233
+ result_chunks: extractResultChunks(resultData),
234
+ session_id: SESSION_ID,
235
+ };
236
+ // Fire and forget — never block the tool response
237
+ trackUsage(entry).catch(() => { });
238
+ }
239
+ /**
240
+ * Get the current session ID (for testing or display).
241
+ */
242
+ export function getSessionId() {
243
+ return SESSION_ID;
244
+ }
245
+ //# sourceMappingURL=usage-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-tracker.js","sourceRoot":"","sources":["../../src/storage/usage-tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type FSWatcher } from "chokidar";
2
+ export type { FSWatcher };
3
+ /**
4
+ * Start watching a repo root for file changes.
5
+ * Calls onChange with the relative file path, debounced per file at 500ms.
6
+ */
7
+ export declare function startWatcher(repoRoot: string, onChange: (filePath: string) => void): FSWatcher;
8
+ /**
9
+ * Stop a file watcher and clean up all debounce timers.
10
+ */
11
+ export declare function stopWatcher(watcher: FSWatcher): Promise<void>;
12
+ //# sourceMappingURL=watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.d.ts","sourceRoot":"","sources":["../../src/storage/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAGjD,YAAY,EAAE,SAAS,EAAE,CAAC;AAqB1B;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACnC,SAAS,CAmCX;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAWnE"}
@@ -0,0 +1,66 @@
1
+ import { watch } from "chokidar";
2
+ import { relative } from "node:path";
3
+ const IGNORE_PATTERNS = [
4
+ "**/node_modules/**",
5
+ "**/.git/**",
6
+ "**/dist/**",
7
+ "**/build/**",
8
+ "**/coverage/**",
9
+ "**/.codesift/**",
10
+ "**/.next/**",
11
+ "**/__pycache__/**",
12
+ "**/.pytest_cache/**",
13
+ "**/generated/**",
14
+ "**/audit-results/**",
15
+ "**/.backup/**",
16
+ "**/jscpd-report/**",
17
+ ];
18
+ // WeakMap to track debounce timers per watcher for cleanup
19
+ const watcherTimers = new WeakMap();
20
+ /**
21
+ * Start watching a repo root for file changes.
22
+ * Calls onChange with the relative file path, debounced per file at 500ms.
23
+ */
24
+ export function startWatcher(repoRoot, onChange) {
25
+ const debounceTimers = new Map();
26
+ const debouncedOnChange = (absolutePath) => {
27
+ const relativePath = relative(repoRoot, absolutePath);
28
+ const existing = debounceTimers.get(relativePath);
29
+ if (existing !== undefined) {
30
+ clearTimeout(existing);
31
+ }
32
+ const timer = setTimeout(() => {
33
+ debounceTimers.delete(relativePath);
34
+ onChange(relativePath);
35
+ }, 500);
36
+ debounceTimers.set(relativePath, timer);
37
+ };
38
+ const watcher = watch(repoRoot, {
39
+ ignored: IGNORE_PATTERNS,
40
+ persistent: true,
41
+ ignoreInitial: true,
42
+ awaitWriteFinish: {
43
+ stabilityThreshold: 200,
44
+ pollInterval: 50,
45
+ },
46
+ });
47
+ watcher.on("add", debouncedOnChange);
48
+ watcher.on("change", debouncedOnChange);
49
+ watcherTimers.set(watcher, debounceTimers);
50
+ return watcher;
51
+ }
52
+ /**
53
+ * Stop a file watcher and clean up all debounce timers.
54
+ */
55
+ export async function stopWatcher(watcher) {
56
+ const timers = watcherTimers.get(watcher);
57
+ if (timers) {
58
+ for (const timer of timers.values()) {
59
+ clearTimeout(timer);
60
+ }
61
+ timers.clear();
62
+ watcherTimers.delete(watcher);
63
+ }
64
+ await watcher.close();
65
+ }
66
+ //# sourceMappingURL=watcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watcher.js","sourceRoot":"","sources":["../../src/storage/watcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAkB,MAAM,UAAU,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAIrC,MAAM,eAAe,GAAG;IACtB,oBAAoB;IACpB,YAAY;IACZ,YAAY;IACZ,aAAa;IACb,gBAAgB;IAChB,iBAAiB;IACjB,aAAa;IACb,mBAAmB;IACnB,qBAAqB;IACrB,iBAAiB;IACjB,qBAAqB;IACrB,eAAe;IACf,oBAAoB;CACrB,CAAC;AAEF,2DAA2D;AAC3D,MAAM,aAAa,GAAG,IAAI,OAAO,EAAyD,CAAC;AAE3F;;;GAGG;AACH,MAAM,UAAU,YAAY,CAC1B,QAAgB,EAChB,QAAoC;IAEpC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAyC,CAAC;IAExE,MAAM,iBAAiB,GAAG,CAAC,YAAoB,EAAQ,EAAE;QACvD,MAAM,YAAY,GAAG,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAC,CAAC;QAEtD,MAAM,QAAQ,GAAG,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC;QAClD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;YAC3B,YAAY,CAAC,QAAQ,CAAC,CAAC;QACzB,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,cAAc,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;YACpC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACzB,CAAC,EAAE,GAAG,CAAC,CAAC;QAER,cAAc,CAAC,GAAG,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IAC1C,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,CAAC,QAAQ,EAAE;QAC9B,OAAO,EAAE,eAAe;QACxB,UAAU,EAAE,IAAI;QAChB,aAAa,EAAE,IAAI;QACnB,gBAAgB,EAAE;YAChB,kBAAkB,EAAE,GAAG;YACvB,YAAY,EAAE,EAAE;SACjB;KACF,CAAC,CAAC;IAEH,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,iBAAiB,CAAC,CAAC;IACrC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;IAExC,aAAa,CAAC,GAAG,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAE3C,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAkB;IAClD,MAAM,MAAM,GAAG,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC1C,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACpC,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,MAAM,CAAC,KAAK,EAAE,CAAC;QACf,aAAa,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { CodeSymbol } from "../types.js";
2
+ export interface AssembleContextResult {
3
+ symbols: CodeSymbol[];
4
+ total_tokens: number;
5
+ truncated: boolean;
6
+ }
7
+ export interface KnowledgeMapModule {
8
+ path: string;
9
+ symbol_count: number;
10
+ }
11
+ export interface KnowledgeMapEdge {
12
+ from: string;
13
+ to: string;
14
+ }
15
+ export interface KnowledgeMap {
16
+ modules: KnowledgeMapModule[];
17
+ edges: KnowledgeMapEdge[];
18
+ }
19
+ /**
20
+ * Assemble a context window of relevant code for a query.
21
+ * Uses BM25 search to find the most relevant symbols and accumulates
22
+ * them until the token budget is reached.
23
+ */
24
+ export declare function assembleContext(repo: string, query: string, tokenBudget?: number): Promise<AssembleContextResult>;
25
+ /**
26
+ * Build a module dependency map for a repository.
27
+ * Parses import statements from each file's symbols to discover edges.
28
+ * Optionally filters to modules matching a focus path.
29
+ */
30
+ export declare function getKnowledgeMap(repo: string, focus?: string, depth?: number): Promise<KnowledgeMap>;
31
+ //# sourceMappingURL=context-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-tools.d.ts","sourceRoot":"","sources":["../../src/tools/context-tools.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAa,MAAM,aAAa,CAAC;AAEzD,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,KAAK,EAAE,gBAAgB,EAAE,CAAC;CAC3B;AAUD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,qBAAqB,CAAC,CA8BhC;AA8DD;;;;GAIG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,KAAK,CAAC,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC,CA8BvB"}
@@ -0,0 +1,219 @@
1
+ import { getBM25Index, getCodeIndex } from "./index-tools.js";
2
+ import { searchBM25 } from "../search/bm25.js";
3
+ import { loadConfig } from "../config.js";
4
+ /**
5
+ * Estimate token count from source text.
6
+ * Rough heuristic: ~4 characters per token.
7
+ */
8
+ function estimateTokens(source) {
9
+ return Math.ceil(source.length / 4);
10
+ }
11
+ /**
12
+ * Assemble a context window of relevant code for a query.
13
+ * Uses BM25 search to find the most relevant symbols and accumulates
14
+ * them until the token budget is reached.
15
+ */
16
+ export async function assembleContext(repo, query, tokenBudget) {
17
+ const bm25Index = await getBM25Index(repo);
18
+ if (!bm25Index) {
19
+ throw new Error(`Repository not found: ${repo}`);
20
+ }
21
+ const config = loadConfig();
22
+ const budget = tokenBudget ?? config.defaultTokenBudget;
23
+ const topK = 20;
24
+ const results = searchBM25(bm25Index, query, topK, config.bm25FieldWeights);
25
+ const symbols = [];
26
+ let totalTokens = 0;
27
+ let truncated = false;
28
+ for (const result of results) {
29
+ const source = result.symbol.source ?? "";
30
+ const tokens = estimateTokens(source);
31
+ if (totalTokens + tokens > budget) {
32
+ truncated = true;
33
+ break;
34
+ }
35
+ symbols.push(result.symbol);
36
+ totalTokens += tokens;
37
+ }
38
+ return { symbols, total_tokens: totalTokens, truncated };
39
+ }
40
+ // Patterns for detecting import statements across common languages
41
+ const IMPORT_PATTERNS = [
42
+ // ES modules: import ... from '...' or import ... from "..."
43
+ /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g,
44
+ // Dynamic import: import('...')
45
+ /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
46
+ // CommonJS: require('...')
47
+ /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g,
48
+ ];
49
+ /**
50
+ * Extract import paths from a source string.
51
+ * Returns relative paths only (skips node_modules / bare specifiers).
52
+ */
53
+ function extractImports(source) {
54
+ const imports = new Set();
55
+ for (const pattern of IMPORT_PATTERNS) {
56
+ // Reset lastIndex for global regex
57
+ pattern.lastIndex = 0;
58
+ let match;
59
+ while ((match = pattern.exec(source)) !== null) {
60
+ const importPath = match[1];
61
+ if (importPath && importPath.startsWith(".")) {
62
+ imports.add(importPath);
63
+ }
64
+ }
65
+ }
66
+ return [...imports];
67
+ }
68
+ /**
69
+ * Normalize an import path relative to the importing file.
70
+ * Resolves "./foo" and "../bar" relative to the importer's directory.
71
+ */
72
+ function resolveImportPath(importerFile, importPath) {
73
+ const importerDir = importerFile.includes("/")
74
+ ? importerFile.slice(0, importerFile.lastIndexOf("/"))
75
+ : ".";
76
+ const parts = importerDir.split("/");
77
+ for (const segment of importPath.split("/")) {
78
+ if (segment === ".")
79
+ continue;
80
+ if (segment === "..") {
81
+ parts.pop();
82
+ }
83
+ else {
84
+ parts.push(segment);
85
+ }
86
+ }
87
+ let resolved = parts.join("/");
88
+ // Strip file extension for matching (imports often omit .ts/.js)
89
+ resolved = resolved.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/, "");
90
+ return resolved;
91
+ }
92
+ /**
93
+ * Build a module dependency map for a repository.
94
+ * Parses import statements from each file's symbols to discover edges.
95
+ * Optionally filters to modules matching a focus path.
96
+ */
97
+ export async function getKnowledgeMap(repo, focus, depth) {
98
+ const index = await getCodeIndex(repo);
99
+ if (!index) {
100
+ throw new Error(`Repository not found: ${repo}`);
101
+ }
102
+ const maxDepth = depth ?? 3;
103
+ // Build module list from files
104
+ const moduleMap = new Map();
105
+ for (const file of index.files) {
106
+ moduleMap.set(file.path, {
107
+ path: file.path,
108
+ symbol_count: file.symbol_count,
109
+ });
110
+ }
111
+ // Collect all import edges by scanning symbol source
112
+ const edges = collectEdges(index, moduleMap);
113
+ // If no focus, return the full graph (limited by depth from roots)
114
+ if (!focus) {
115
+ return {
116
+ modules: [...moduleMap.values()],
117
+ edges,
118
+ };
119
+ }
120
+ // Filter to focus path and neighbors within depth
121
+ return filterToFocus(moduleMap, edges, focus, maxDepth);
122
+ }
123
+ /**
124
+ * Scan all symbols to collect import edges between modules.
125
+ */
126
+ function collectEdges(index, moduleMap) {
127
+ const edgeSet = new Set();
128
+ const edges = [];
129
+ // Build a set of normalized module paths for matching
130
+ const normalizedPaths = new Map();
131
+ for (const file of index.files) {
132
+ const normalized = file.path.replace(/\.(ts|tsx|js|jsx|mjs|cjs)$/, "");
133
+ normalizedPaths.set(normalized, file.path);
134
+ // Also handle index files: "foo/index" -> "foo"
135
+ if (normalized.endsWith("/index")) {
136
+ normalizedPaths.set(normalized.slice(0, -6), file.path);
137
+ }
138
+ }
139
+ for (const sym of index.symbols) {
140
+ if (!sym.source)
141
+ continue;
142
+ const importPaths = extractImports(sym.source);
143
+ for (const importPath of importPaths) {
144
+ const resolved = resolveImportPath(sym.file, importPath);
145
+ const targetFile = normalizedPaths.get(resolved);
146
+ if (!targetFile || targetFile === sym.file)
147
+ continue;
148
+ const edgeKey = `${sym.file}->${targetFile}`;
149
+ if (edgeSet.has(edgeKey))
150
+ continue;
151
+ edgeSet.add(edgeKey);
152
+ // Ensure both modules exist in the map
153
+ if (moduleMap.has(sym.file) && moduleMap.has(targetFile)) {
154
+ edges.push({ from: sym.file, to: targetFile });
155
+ }
156
+ }
157
+ }
158
+ return edges;
159
+ }
160
+ /**
161
+ * Filter the graph to only modules matching the focus path
162
+ * and their neighbors up to maxDepth hops.
163
+ */
164
+ function filterToFocus(moduleMap, edges, focus, maxDepth) {
165
+ // Build adjacency lists (bidirectional for neighbor traversal)
166
+ const adjacency = new Map();
167
+ for (const edge of edges) {
168
+ let fromSet = adjacency.get(edge.from);
169
+ if (!fromSet) {
170
+ fromSet = new Set();
171
+ adjacency.set(edge.from, fromSet);
172
+ }
173
+ fromSet.add(edge.to);
174
+ let toSet = adjacency.get(edge.to);
175
+ if (!toSet) {
176
+ toSet = new Set();
177
+ adjacency.set(edge.to, toSet);
178
+ }
179
+ toSet.add(edge.from);
180
+ }
181
+ // Find seed modules matching the focus path
182
+ const seeds = new Set();
183
+ for (const [path] of moduleMap) {
184
+ if (path.includes(focus)) {
185
+ seeds.add(path);
186
+ }
187
+ }
188
+ // BFS from seeds up to maxDepth
189
+ const reachable = new Set(seeds);
190
+ let frontier = [...seeds];
191
+ for (let d = 0; d < maxDepth; d++) {
192
+ const nextFrontier = [];
193
+ for (const node of frontier) {
194
+ const neighbors = adjacency.get(node);
195
+ if (!neighbors)
196
+ continue;
197
+ for (const neighbor of neighbors) {
198
+ if (!reachable.has(neighbor)) {
199
+ reachable.add(neighbor);
200
+ nextFrontier.push(neighbor);
201
+ }
202
+ }
203
+ }
204
+ if (nextFrontier.length === 0)
205
+ break;
206
+ frontier = nextFrontier;
207
+ }
208
+ // Filter modules and edges to reachable set
209
+ const filteredModules = [];
210
+ for (const path of reachable) {
211
+ const mod = moduleMap.get(path);
212
+ if (mod) {
213
+ filteredModules.push(mod);
214
+ }
215
+ }
216
+ const filteredEdges = edges.filter((e) => reachable.has(e.from) && reachable.has(e.to));
217
+ return { modules: filteredModules, edges: filteredEdges };
218
+ }
219
+ //# sourceMappingURL=context-tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-tools.js","sourceRoot":"","sources":["../../src/tools/context-tools.ts"],"names":[],"mappings":"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"}