@usewhisper/mcp-server 0.1.0 → 0.3.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 (70) hide show
  1. package/README.md +26 -24
  2. package/dist/autosubscribe-6EDKPBE2.js +4068 -0
  3. package/dist/autosubscribe-GHO6YR5A.js +4068 -0
  4. package/dist/autosubscribe-ISDETQIB.js +436 -0
  5. package/dist/autosubscribe-ISDETQIB.js.map +1 -0
  6. package/dist/chunk-3WGYBAYR.js +8387 -0
  7. package/dist/chunk-52VJYCZ7.js +455 -0
  8. package/dist/chunk-5KBZQHDL.js +189 -0
  9. package/dist/chunk-5KIJNY6Z.js +370 -0
  10. package/dist/chunk-7SN3CKDK.js +1076 -0
  11. package/dist/chunk-B3VWOHUA.js +271 -0
  12. package/dist/chunk-C57DHKTL.js +459 -0
  13. package/dist/chunk-EI5CE3EY.js +616 -0
  14. package/dist/chunk-FTWUJBAH.js +387 -0
  15. package/dist/chunk-FTWUJBAH.js.map +1 -0
  16. package/dist/chunk-H3HSKH2P.js +4841 -0
  17. package/dist/chunk-JO3ORBZD.js +616 -0
  18. package/dist/chunk-L6DXSM2U.js +457 -0
  19. package/dist/chunk-L6DXSM2U.js.map +1 -0
  20. package/dist/chunk-LMEYV4JD.js +368 -0
  21. package/dist/chunk-MEFLJ4PV.js +8385 -0
  22. package/dist/chunk-OBLI4FE4.js +276 -0
  23. package/dist/chunk-OBLI4FE4.js.map +1 -0
  24. package/dist/chunk-PPGYJJED.js +271 -0
  25. package/dist/chunk-QGM4M3NI.js +37 -0
  26. package/dist/chunk-T7KMSTWP.js +399 -0
  27. package/dist/chunk-TWEIYHI6.js +399 -0
  28. package/dist/chunk-UYWE7HSU.js +369 -0
  29. package/dist/chunk-UYWE7HSU.js.map +1 -0
  30. package/dist/chunk-X2DL2GWT.js +33 -0
  31. package/dist/chunk-X2DL2GWT.js.map +1 -0
  32. package/dist/chunk-X7HNNNJJ.js +1079 -0
  33. package/dist/consolidation-2GCKI4RE.js +220 -0
  34. package/dist/consolidation-4JOPW6BG.js +220 -0
  35. package/dist/consolidation-FOVQTWNQ.js +222 -0
  36. package/dist/consolidation-IFQ52E44.js +210 -0
  37. package/dist/consolidation-IFQ52E44.js.map +1 -0
  38. package/dist/context-sharing-4ITCNKG4.js +307 -0
  39. package/dist/context-sharing-6CCFIAKL.js +276 -0
  40. package/dist/context-sharing-6CCFIAKL.js.map +1 -0
  41. package/dist/context-sharing-GYKLXHZA.js +307 -0
  42. package/dist/context-sharing-PH64JTXS.js +308 -0
  43. package/dist/context-sharing-Y6LTZZOF.js +307 -0
  44. package/dist/cost-optimization-6OIKRSBV.js +196 -0
  45. package/dist/cost-optimization-6OIKRSBV.js.map +1 -0
  46. package/dist/cost-optimization-7DVSTL6R.js +307 -0
  47. package/dist/cost-optimization-BH5NAX33.js +287 -0
  48. package/dist/cost-optimization-BH5NAX33.js.map +1 -0
  49. package/dist/cost-optimization-F3L5BS5F.js +303 -0
  50. package/dist/ingest-2LPTWUUM.js +16 -0
  51. package/dist/ingest-7T5FAZNC.js +15 -0
  52. package/dist/ingest-EBNIE7XB.js +15 -0
  53. package/dist/ingest-FSHT5BCS.js +15 -0
  54. package/dist/ingest-QE2BTV72.js +15 -0
  55. package/dist/ingest-QE2BTV72.js.map +1 -0
  56. package/dist/oracle-3RLQF3DP.js +259 -0
  57. package/dist/oracle-FKRTQUUG.js +282 -0
  58. package/dist/oracle-J47QCSEW.js +263 -0
  59. package/dist/oracle-MDP5MZRC.js +257 -0
  60. package/dist/oracle-MDP5MZRC.js.map +1 -0
  61. package/dist/search-BLVHWLWC.js +14 -0
  62. package/dist/search-CZ5NYL5B.js +13 -0
  63. package/dist/search-CZ5NYL5B.js.map +1 -0
  64. package/dist/search-EG6TYWWW.js +13 -0
  65. package/dist/search-I22QQA7T.js +13 -0
  66. package/dist/search-T7H5G6DW.js +13 -0
  67. package/dist/server.d.ts +2 -0
  68. package/dist/server.js +914 -1503
  69. package/dist/server.js.map +1 -1
  70. package/package.json +6 -7
@@ -0,0 +1,436 @@
1
+ import {
2
+ ingestDocument
3
+ } from "./chunk-FTWUJBAH.js";
4
+ import {
5
+ db
6
+ } from "./chunk-X2DL2GWT.js";
7
+
8
+ // src/engine/autosubscribe.ts
9
+ import { Octokit } from "@octokit/rest";
10
+
11
+ // src/connectors/npm_package.ts
12
+ async function syncNpmPackage(sourceId, projectId, config) {
13
+ const { packageName, includeReadme = true } = config;
14
+ let indexed = 0;
15
+ const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`);
16
+ if (!res.ok) throw new Error(`npm registry error: ${res.status}`);
17
+ const pkg = await res.json();
18
+ const latest = pkg["dist-tags"]?.latest;
19
+ const latestVersion = latest ? pkg.versions?.[latest] : null;
20
+ const overview = [
21
+ `# ${packageName}`,
22
+ pkg.description ? `
23
+ ${pkg.description}` : "",
24
+ `
25
+ Latest version: ${latest || "unknown"}`,
26
+ pkg.license ? `License: ${pkg.license}` : "",
27
+ pkg.homepage ? `Homepage: ${pkg.homepage}` : "",
28
+ pkg.repository?.url ? `Repository: ${pkg.repository.url}` : "",
29
+ latestVersion?.keywords?.length ? `
30
+ Keywords: ${latestVersion.keywords.join(", ")}` : ""
31
+ ].filter(Boolean).join("\n");
32
+ if (latestVersion?.dependencies) {
33
+ const deps = Object.entries(latestVersion.dependencies).map(([name, ver]) => `- ${name}: ${ver}`).join("\n");
34
+ await ingestDocument({
35
+ sourceId,
36
+ projectId,
37
+ externalId: `npm-${packageName}-deps`,
38
+ title: `${packageName} \u2014 Dependencies`,
39
+ content: `# ${packageName} Dependencies
40
+
41
+ ${deps}`,
42
+ metadata: { source: "npm", packageName, section: "dependencies" }
43
+ });
44
+ indexed++;
45
+ }
46
+ if (latestVersion?.main || latestVersion?.types || latestVersion?.exports) {
47
+ const entryPoints = [
48
+ latestVersion.main ? `Main: ${latestVersion.main}` : "",
49
+ latestVersion.types ? `Types: ${latestVersion.types}` : "",
50
+ latestVersion.module ? `Module: ${latestVersion.module}` : ""
51
+ ].filter(Boolean).join("\n");
52
+ await ingestDocument({
53
+ sourceId,
54
+ projectId,
55
+ externalId: `npm-${packageName}-overview`,
56
+ title: `${packageName} \u2014 Overview`,
57
+ content: `${overview}
58
+
59
+ ## Entry Points
60
+ ${entryPoints}`,
61
+ metadata: { source: "npm", packageName, version: latest, section: "overview" }
62
+ });
63
+ indexed++;
64
+ }
65
+ if (includeReadme && pkg.readme) {
66
+ await ingestDocument({
67
+ sourceId,
68
+ projectId,
69
+ externalId: `npm-${packageName}-readme`,
70
+ title: `${packageName} \u2014 README`,
71
+ content: pkg.readme,
72
+ metadata: { source: "npm", packageName, section: "readme" }
73
+ });
74
+ indexed++;
75
+ }
76
+ return { documentsIndexed: indexed };
77
+ }
78
+
79
+ // src/connectors/pypi_package.ts
80
+ async function syncPyPIPackage(sourceId, projectId, config) {
81
+ const { packageName, includeDescription = true } = config;
82
+ let indexed = 0;
83
+ const res = await fetch(`https://pypi.org/pypi/${encodeURIComponent(packageName)}/json`);
84
+ if (!res.ok) throw new Error(`PyPI API error: ${res.status}`);
85
+ const data = await res.json();
86
+ const info = data.info || {};
87
+ const overview = [
88
+ `# ${info.name || packageName}`,
89
+ info.summary ? `
90
+ ${info.summary}` : "",
91
+ `
92
+ Version: ${info.version || "unknown"}`,
93
+ info.license ? `License: ${info.license}` : "",
94
+ info.author ? `Author: ${info.author}` : "",
95
+ info.home_page ? `Homepage: ${info.home_page}` : "",
96
+ info.project_urls?.Documentation ? `Docs: ${info.project_urls.Documentation}` : "",
97
+ info.project_urls?.Repository || info.project_urls?.Source ? `Repository: ${info.project_urls.Repository || info.project_urls.Source}` : "",
98
+ info.requires_python ? `
99
+ Python: ${info.requires_python}` : "",
100
+ info.keywords ? `Keywords: ${info.keywords}` : ""
101
+ ].filter(Boolean).join("\n");
102
+ await ingestDocument({
103
+ sourceId,
104
+ projectId,
105
+ externalId: `pypi-${packageName}-overview`,
106
+ title: `${packageName} \u2014 Overview`,
107
+ content: overview,
108
+ metadata: { source: "pypi", packageName, version: info.version, section: "overview" }
109
+ });
110
+ indexed++;
111
+ if (info.requires_dist?.length) {
112
+ const deps = info.requires_dist.filter((d) => !d.includes("extra ==")).map((d) => `- ${d}`).join("\n");
113
+ if (deps) {
114
+ await ingestDocument({
115
+ sourceId,
116
+ projectId,
117
+ externalId: `pypi-${packageName}-deps`,
118
+ title: `${packageName} \u2014 Dependencies`,
119
+ content: `# ${packageName} Dependencies
120
+
121
+ ${deps}`,
122
+ metadata: { source: "pypi", packageName, section: "dependencies" }
123
+ });
124
+ indexed++;
125
+ }
126
+ }
127
+ if (includeDescription && info.description) {
128
+ await ingestDocument({
129
+ sourceId,
130
+ projectId,
131
+ externalId: `pypi-${packageName}-description`,
132
+ title: `${packageName} \u2014 Description`,
133
+ content: info.description,
134
+ metadata: {
135
+ source: "pypi",
136
+ packageName,
137
+ section: "description",
138
+ contentType: info.description_content_type || "text/plain"
139
+ }
140
+ });
141
+ indexed++;
142
+ }
143
+ return { documentsIndexed: indexed };
144
+ }
145
+
146
+ // src/engine/autosubscribe.ts
147
+ async function parsePackageJson(content) {
148
+ try {
149
+ const pkg = JSON.parse(content);
150
+ const deps = [];
151
+ if (pkg.dependencies) {
152
+ for (const [name, version] of Object.entries(pkg.dependencies)) {
153
+ deps.push({
154
+ name,
155
+ version: String(version),
156
+ ecosystem: "npm"
157
+ });
158
+ }
159
+ }
160
+ if (pkg.devDependencies) {
161
+ for (const [name, version] of Object.entries(pkg.devDependencies)) {
162
+ deps.push({
163
+ name,
164
+ version: String(version),
165
+ ecosystem: "npm"
166
+ });
167
+ }
168
+ }
169
+ return deps;
170
+ } catch (error) {
171
+ console.error("Failed to parse package.json:", error);
172
+ return [];
173
+ }
174
+ }
175
+ function parseRequirementsTxt(content) {
176
+ const deps = [];
177
+ const lines = content.split("\n");
178
+ for (const line of lines) {
179
+ const trimmed = line.trim();
180
+ if (!trimmed || trimmed.startsWith("#")) continue;
181
+ const match = trimmed.match(/^([a-zA-Z0-9_-]+)([><=!~]+)?(.+)?$/);
182
+ if (match) {
183
+ deps.push({
184
+ name: match[1],
185
+ version: match[3] || "latest",
186
+ ecosystem: "pypi"
187
+ });
188
+ }
189
+ }
190
+ return deps;
191
+ }
192
+ function parseCargoToml(content) {
193
+ const deps = [];
194
+ const depsMatch = content.match(/\[dependencies\]([\s\S]*?)(\[|$)/);
195
+ if (!depsMatch) return deps;
196
+ const depsSection = depsMatch[1];
197
+ const lines = depsSection.split("\n");
198
+ for (const line of lines) {
199
+ const match = line.match(/^([a-zA-Z0-9_-]+)\s*=\s*"([^"]+)"/);
200
+ if (match) {
201
+ deps.push({
202
+ name: match[1],
203
+ version: match[2],
204
+ ecosystem: "cargo"
205
+ });
206
+ }
207
+ }
208
+ return deps;
209
+ }
210
+ function parseDependencyFile(filename, content) {
211
+ if (filename === "package.json") {
212
+ return parsePackageJson(content);
213
+ } else if (filename === "requirements.txt" || filename.endsWith(".txt")) {
214
+ return parseRequirementsTxt(content);
215
+ } else if (filename === "Cargo.toml") {
216
+ return parseCargoToml(content);
217
+ }
218
+ return [];
219
+ }
220
+ async function fetchDependencyFile(params) {
221
+ const { owner, repo, branch = "main", githubToken } = params;
222
+ const octokit = new Octokit({
223
+ auth: githubToken || process.env.GITHUB_TOKEN
224
+ });
225
+ const files = [
226
+ "package.json",
227
+ "requirements.txt",
228
+ "Cargo.toml",
229
+ "pom.xml",
230
+ // Maven
231
+ "build.gradle"
232
+ // Gradle
233
+ ];
234
+ for (const filename of files) {
235
+ try {
236
+ const { data } = await octokit.repos.getContent({
237
+ owner,
238
+ repo,
239
+ path: filename,
240
+ ref: branch
241
+ });
242
+ if ("content" in data && data.content) {
243
+ const content = Buffer.from(data.content, "base64").toString("utf-8");
244
+ return { filename, content };
245
+ }
246
+ } catch (error) {
247
+ continue;
248
+ }
249
+ }
250
+ return null;
251
+ }
252
+ async function resolveDocsUrl(dep) {
253
+ switch (dep.ecosystem) {
254
+ case "npm":
255
+ try {
256
+ const response = await fetch(`https://registry.npmjs.org/${dep.name}`);
257
+ const data = await response.json();
258
+ if (data.homepage) return data.homepage;
259
+ if (data.repository?.url) {
260
+ const url = data.repository.url.replace("git+", "").replace(".git", "").replace("git://", "https://");
261
+ return url;
262
+ }
263
+ return `https://www.npmjs.com/package/${dep.name}`;
264
+ } catch (error) {
265
+ return `https://www.npmjs.com/package/${dep.name}`;
266
+ }
267
+ case "pypi":
268
+ try {
269
+ const response = await fetch(`https://pypi.org/pypi/${dep.name}/json`);
270
+ const data = await response.json();
271
+ if (data.info.home_page) return data.info.home_page;
272
+ if (data.info.project_urls?.Documentation) {
273
+ return data.info.project_urls.Documentation;
274
+ }
275
+ return `https://pypi.org/project/${dep.name}/`;
276
+ } catch (error) {
277
+ return `https://pypi.org/project/${dep.name}/`;
278
+ }
279
+ case "cargo":
280
+ return `https://docs.rs/${dep.name}`;
281
+ default:
282
+ return null;
283
+ }
284
+ }
285
+ async function autosubscribe(params) {
286
+ const { projectId, orgId, source, indexLimit = 50 } = params;
287
+ const result = {
288
+ discovered: 0,
289
+ indexed: 0,
290
+ skipped: 0,
291
+ errors: []
292
+ };
293
+ try {
294
+ let depFile = null;
295
+ if (source.type === "github" && source.owner && source.repo) {
296
+ depFile = await fetchDependencyFile({
297
+ owner: source.owner,
298
+ repo: source.repo,
299
+ branch: source.branch
300
+ });
301
+ } else if (source.type === "local" && source.filePath) {
302
+ const fs = await import("fs");
303
+ const content = fs.readFileSync(source.filePath, "utf-8");
304
+ const filename = source.filePath.split("/").pop() || "package.json";
305
+ depFile = { filename, content };
306
+ }
307
+ if (!depFile) {
308
+ result.errors.push("No dependency file found");
309
+ return result;
310
+ }
311
+ const dependencies = parseDependencyFile(depFile.filename, depFile.content);
312
+ result.discovered = dependencies.length;
313
+ console.log(`\u{1F4E6} Discovered ${dependencies.length} dependencies`);
314
+ const toIndex = dependencies.slice(0, indexLimit);
315
+ for (const dep of toIndex) {
316
+ try {
317
+ const existing = await db.package.findFirst({
318
+ where: {
319
+ orgId,
320
+ ecosystem: dep.ecosystem,
321
+ name: dep.name
322
+ }
323
+ });
324
+ if (existing) {
325
+ console.log(`\u23ED\uFE0F Skipping ${dep.name} (already indexed)`);
326
+ result.skipped++;
327
+ continue;
328
+ }
329
+ const docsUrl = await resolveDocsUrl(dep);
330
+ if (!docsUrl) {
331
+ result.errors.push(`No docs URL for ${dep.name}`);
332
+ continue;
333
+ }
334
+ console.log(`\u{1F4DA} Indexing ${dep.name} from ${docsUrl}`);
335
+ await db.package.create({
336
+ data: {
337
+ orgId,
338
+ name: dep.name,
339
+ ecosystem: dep.ecosystem,
340
+ version: dep.version,
341
+ registryUrl: docsUrl,
342
+ autoSync: true
343
+ }
344
+ });
345
+ if (dep.ecosystem === "npm") {
346
+ await syncNpmPackage({
347
+ packageName: dep.name,
348
+ version: dep.version,
349
+ projectId,
350
+ orgId
351
+ });
352
+ } else if (dep.ecosystem === "pypi") {
353
+ await syncPyPIPackage({
354
+ packageName: dep.name,
355
+ version: dep.version,
356
+ projectId,
357
+ orgId
358
+ });
359
+ }
360
+ result.indexed++;
361
+ console.log(`\u2705 Indexed ${dep.name}`);
362
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
363
+ } catch (error) {
364
+ result.errors.push(`Failed to index ${dep.name}: ${error}`);
365
+ console.error(`\u274C Failed to index ${dep.name}:`, error);
366
+ }
367
+ }
368
+ if (dependencies.length > indexLimit) {
369
+ result.errors.push(
370
+ `Only indexed first ${indexLimit} of ${dependencies.length} packages (limit reached)`
371
+ );
372
+ }
373
+ return result;
374
+ } catch (error) {
375
+ result.errors.push(`Autosubscribe failed: ${error}`);
376
+ return result;
377
+ }
378
+ }
379
+ async function autoSyncPackages(orgId) {
380
+ const packages = await db.package.findMany({
381
+ where: {
382
+ orgId,
383
+ autoSync: true
384
+ }
385
+ });
386
+ console.log(`\u{1F504} Auto-syncing ${packages.length} packages...`);
387
+ for (const pkg of packages) {
388
+ try {
389
+ const shouldUpdate = await checkPackageUpdated(pkg);
390
+ if (shouldUpdate) {
391
+ console.log(`\u{1F4E6} Re-indexing ${pkg.name}...`);
392
+ if (pkg.ecosystem === "npm") {
393
+ await syncNpmPackage({
394
+ packageName: pkg.name,
395
+ version: pkg.version,
396
+ projectId: "",
397
+ // Will need project context
398
+ orgId
399
+ });
400
+ } else if (pkg.ecosystem === "pypi") {
401
+ await syncPyPIPackage({
402
+ packageName: pkg.name,
403
+ version: pkg.version,
404
+ projectId: "",
405
+ orgId
406
+ });
407
+ }
408
+ await db.package.update({
409
+ where: { id: pkg.id },
410
+ data: { lastIndexedAt: /* @__PURE__ */ new Date() }
411
+ });
412
+ }
413
+ } catch (error) {
414
+ console.error(`Failed to sync ${pkg.name}:`, error);
415
+ }
416
+ }
417
+ console.log("\u2705 Auto-sync complete");
418
+ }
419
+ async function checkPackageUpdated(pkg) {
420
+ if (!pkg.lastIndexedAt) return true;
421
+ const daysSinceIndex = Math.floor(
422
+ (Date.now() - pkg.lastIndexedAt.getTime()) / (1e3 * 60 * 60 * 24)
423
+ );
424
+ return daysSinceIndex > 7;
425
+ }
426
+ export {
427
+ autoSyncPackages,
428
+ autosubscribe,
429
+ fetchDependencyFile,
430
+ parseCargoToml,
431
+ parseDependencyFile,
432
+ parsePackageJson,
433
+ parseRequirementsTxt,
434
+ resolveDocsUrl
435
+ };
436
+ //# sourceMappingURL=autosubscribe-ISDETQIB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/engine/autosubscribe.ts","../../src/connectors/npm_package.ts","../../src/connectors/pypi_package.ts"],"sourcesContent":["/**\n * Autosubscribe - Auto-index package dependencies\n * Parses package.json/requirements.txt and automatically indexes documentation\n * Like Nia's autosubscribe feature\n */\n\nimport { Octokit } from \"@octokit/rest\";\nimport { db } from \"../db/index.js\";\nimport { syncNpmPackage } from \"../connectors/npm_package.js\";\nimport { syncPyPIPackage } from \"../connectors/pypi_package.js\";\n\ninterface PackageDependency {\n name: string;\n version: string;\n ecosystem: \"npm\" | \"pypi\" | \"maven\" | \"cargo\";\n}\n\n/**\n * Parse package.json and extract dependencies\n */\nexport async function parsePackageJson(content: string): Promise<PackageDependency[]> {\n try {\n const pkg = JSON.parse(content);\n const deps: PackageDependency[] = [];\n\n // Regular dependencies\n if (pkg.dependencies) {\n for (const [name, version] of Object.entries(pkg.dependencies)) {\n deps.push({\n name,\n version: String(version),\n ecosystem: \"npm\",\n });\n }\n }\n\n // Dev dependencies\n if (pkg.devDependencies) {\n for (const [name, version] of Object.entries(pkg.devDependencies)) {\n deps.push({\n name,\n version: String(version),\n ecosystem: \"npm\",\n });\n }\n }\n\n return deps;\n } catch (error) {\n console.error(\"Failed to parse package.json:\", error);\n return [];\n }\n}\n\n/**\n * Parse requirements.txt and extract Python dependencies\n */\nexport function parseRequirementsTxt(content: string): PackageDependency[] {\n const deps: PackageDependency[] = [];\n const lines = content.split(\"\\n\");\n\n for (const line of lines) {\n const trimmed = line.trim();\n\n // Skip comments and empty lines\n if (!trimmed || trimmed.startsWith(\"#\")) continue;\n\n // Parse \"package==version\" or \"package>=version\"\n const match = trimmed.match(/^([a-zA-Z0-9_-]+)([><=!~]+)?(.+)?$/);\n if (match) {\n deps.push({\n name: match[1],\n version: match[3] || \"latest\",\n ecosystem: \"pypi\",\n });\n }\n }\n\n return deps;\n}\n\n/**\n * Parse Cargo.toml (Rust)\n */\nexport function parseCargoToml(content: string): PackageDependency[] {\n const deps: PackageDependency[] = [];\n\n // Simple parser for [dependencies] section\n const depsMatch = content.match(/\\[dependencies\\]([\\s\\S]*?)(\\[|$)/);\n if (!depsMatch) return deps;\n\n const depsSection = depsMatch[1];\n const lines = depsSection.split(\"\\n\");\n\n for (const line of lines) {\n const match = line.match(/^([a-zA-Z0-9_-]+)\\s*=\\s*\"([^\"]+)\"/);\n if (match) {\n deps.push({\n name: match[1],\n version: match[2],\n ecosystem: \"cargo\",\n });\n }\n }\n\n return deps;\n}\n\n/**\n * Auto-detect and parse dependency file\n */\nexport function parseDependencyFile(\n filename: string,\n content: string\n): PackageDependency[] {\n if (filename === \"package.json\") {\n return parsePackageJson(content);\n } else if (filename === \"requirements.txt\" || filename.endsWith(\".txt\")) {\n return parseRequirementsTxt(content);\n } else if (filename === \"Cargo.toml\") {\n return parseCargoToml(content);\n }\n\n return [];\n}\n\n/**\n * Fetch dependency file from GitHub repo\n */\nexport async function fetchDependencyFile(params: {\n owner: string;\n repo: string;\n branch?: string;\n githubToken?: string;\n}): Promise<{ filename: string; content: string } | null> {\n const { owner, repo, branch = \"main\", githubToken } = params;\n\n const octokit = new Octokit({\n auth: githubToken || process.env.GITHUB_TOKEN,\n });\n\n // Try common dependency files\n const files = [\n \"package.json\",\n \"requirements.txt\",\n \"Cargo.toml\",\n \"pom.xml\", // Maven\n \"build.gradle\", // Gradle\n ];\n\n for (const filename of files) {\n try {\n const { data } = await octokit.repos.getContent({\n owner,\n repo,\n path: filename,\n ref: branch,\n });\n\n if (\"content\" in data && data.content) {\n const content = Buffer.from(data.content, \"base64\").toString(\"utf-8\");\n return { filename, content };\n }\n } catch (error) {\n // File doesn't exist, try next\n continue;\n }\n }\n\n return null;\n}\n\n/**\n * Resolve documentation URL for a package\n */\nexport async function resolveDocsUrl(dep: PackageDependency): Promise<string | null> {\n switch (dep.ecosystem) {\n case \"npm\":\n // Try npmjs.com first\n try {\n const response = await fetch(`https://registry.npmjs.org/${dep.name}`);\n const data = await response.json();\n\n // Try homepage, repository, or default to npmjs\n if (data.homepage) return data.homepage;\n if (data.repository?.url) {\n const url = data.repository.url\n .replace(\"git+\", \"\")\n .replace(\".git\", \"\")\n .replace(\"git://\", \"https://\");\n return url;\n }\n\n return `https://www.npmjs.com/package/${dep.name}`;\n } catch (error) {\n return `https://www.npmjs.com/package/${dep.name}`;\n }\n\n case \"pypi\":\n // PyPI packages\n try {\n const response = await fetch(`https://pypi.org/pypi/${dep.name}/json`);\n const data = await response.json();\n\n if (data.info.home_page) return data.info.home_page;\n if (data.info.project_urls?.Documentation) {\n return data.info.project_urls.Documentation;\n }\n\n return `https://pypi.org/project/${dep.name}/`;\n } catch (error) {\n return `https://pypi.org/project/${dep.name}/`;\n }\n\n case \"cargo\":\n // Rust crates\n return `https://docs.rs/${dep.name}`;\n\n default:\n return null;\n }\n}\n\n/**\n * Main autosubscribe function\n * Automatically index all dependencies from a project\n */\nexport async function autosubscribe(params: {\n projectId: string;\n orgId: string;\n source: {\n type: \"github\" | \"local\";\n owner?: string;\n repo?: string;\n branch?: string;\n filePath?: string; // For local files\n };\n indexLimit?: number; // Max packages to index (to avoid blowing up costs)\n}): Promise<{\n discovered: number;\n indexed: number;\n skipped: number;\n errors: string[];\n}> {\n const { projectId, orgId, source, indexLimit = 50 } = params;\n\n const result = {\n discovered: 0,\n indexed: 0,\n skipped: 0,\n errors: [] as string[],\n };\n\n try {\n // Step 1: Fetch dependency file\n let depFile: { filename: string; content: string } | null = null;\n\n if (source.type === \"github\" && source.owner && source.repo) {\n depFile = await fetchDependencyFile({\n owner: source.owner,\n repo: source.repo,\n branch: source.branch,\n });\n } else if (source.type === \"local\" && source.filePath) {\n const fs = await import(\"fs\");\n const content = fs.readFileSync(source.filePath, \"utf-8\");\n const filename = source.filePath.split(\"/\").pop() || \"package.json\";\n depFile = { filename, content };\n }\n\n if (!depFile) {\n result.errors.push(\"No dependency file found\");\n return result;\n }\n\n // Step 2: Parse dependencies\n const dependencies = parseDependencyFile(depFile.filename, depFile.content);\n result.discovered = dependencies.length;\n\n console.log(`📦 Discovered ${dependencies.length} dependencies`);\n\n // Step 3: Index each dependency (up to limit)\n const toIndex = dependencies.slice(0, indexLimit);\n\n for (const dep of toIndex) {\n try {\n // Check if already indexed\n const existing = await db.package.findFirst({\n where: {\n orgId,\n ecosystem: dep.ecosystem,\n name: dep.name,\n },\n });\n\n if (existing) {\n console.log(`⏭️ Skipping ${dep.name} (already indexed)`);\n result.skipped++;\n continue;\n }\n\n // Resolve docs URL\n const docsUrl = await resolveDocsUrl(dep);\n if (!docsUrl) {\n result.errors.push(`No docs URL for ${dep.name}`);\n continue;\n }\n\n console.log(`📚 Indexing ${dep.name} from ${docsUrl}`);\n\n // Create package record\n await db.package.create({\n data: {\n orgId,\n name: dep.name,\n ecosystem: dep.ecosystem,\n version: dep.version,\n registryUrl: docsUrl,\n autoSync: true,\n },\n });\n\n // Index the package docs\n if (dep.ecosystem === \"npm\") {\n await syncNpmPackage({\n packageName: dep.name,\n version: dep.version,\n projectId,\n orgId,\n });\n } else if (dep.ecosystem === \"pypi\") {\n await syncPyPIPackage({\n packageName: dep.name,\n version: dep.version,\n projectId,\n orgId,\n });\n }\n\n result.indexed++;\n console.log(`✅ Indexed ${dep.name}`);\n\n // Small delay to avoid rate limits\n await new Promise((resolve) => setTimeout(resolve, 1000));\n } catch (error) {\n result.errors.push(`Failed to index ${dep.name}: ${error}`);\n console.error(`❌ Failed to index ${dep.name}:`, error);\n }\n }\n\n if (dependencies.length > indexLimit) {\n result.errors.push(\n `Only indexed first ${indexLimit} of ${dependencies.length} packages (limit reached)`\n );\n }\n\n return result;\n } catch (error) {\n result.errors.push(`Autosubscribe failed: ${error}`);\n return result;\n }\n}\n\n/**\n * Auto-sync: Re-index packages when they're updated\n */\nexport async function autoSyncPackages(orgId: string): Promise<void> {\n const packages = await db.package.findMany({\n where: {\n orgId,\n autoSync: true,\n },\n });\n\n console.log(`🔄 Auto-syncing ${packages.length} packages...`);\n\n for (const pkg of packages) {\n try {\n // Check if package has been updated (compare lastIndexedAt with registry)\n const shouldUpdate = await checkPackageUpdated(pkg);\n\n if (shouldUpdate) {\n console.log(`📦 Re-indexing ${pkg.name}...`);\n\n if (pkg.ecosystem === \"npm\") {\n await syncNpmPackage({\n packageName: pkg.name,\n version: pkg.version,\n projectId: \"\", // Will need project context\n orgId,\n });\n } else if (pkg.ecosystem === \"pypi\") {\n await syncPyPIPackage({\n packageName: pkg.name,\n version: pkg.version,\n projectId: \"\",\n orgId,\n });\n }\n\n await db.package.update({\n where: { id: pkg.id },\n data: { lastIndexedAt: new Date() },\n });\n }\n } catch (error) {\n console.error(`Failed to sync ${pkg.name}:`, error);\n }\n }\n\n console.log(\"✅ Auto-sync complete\");\n}\n\n/**\n * Check if package has been updated since last index\n */\nasync function checkPackageUpdated(pkg: any): Promise<boolean> {\n if (!pkg.lastIndexedAt) return true;\n\n const daysSinceIndex = Math.floor(\n (Date.now() - pkg.lastIndexedAt.getTime()) / (1000 * 60 * 60 * 24)\n );\n\n // Re-index if more than 7 days old\n return daysSinceIndex > 7;\n}\n","import { ingestDocument } from \"../engine/ingest.js\";\n\ninterface NpmConfig {\n packageName: string;\n includeReadme?: boolean;\n includeChangelog?: boolean;\n}\n\nexport async function syncNpmPackage(\n sourceId: string,\n projectId: string,\n config: NpmConfig\n) {\n const { packageName, includeReadme = true } = config;\n let indexed = 0;\n\n // Fetch package metadata from npm registry\n const res = await fetch(`https://registry.npmjs.org/${encodeURIComponent(packageName)}`);\n if (!res.ok) throw new Error(`npm registry error: ${res.status}`);\n\n const pkg = await res.json();\n const latest = pkg[\"dist-tags\"]?.latest;\n const latestVersion = latest ? pkg.versions?.[latest] : null;\n\n // Index package overview\n const overview = [\n `# ${packageName}`,\n pkg.description ? `\\n${pkg.description}` : \"\",\n `\\nLatest version: ${latest || \"unknown\"}`,\n pkg.license ? `License: ${pkg.license}` : \"\",\n pkg.homepage ? `Homepage: ${pkg.homepage}` : \"\",\n pkg.repository?.url ? `Repository: ${pkg.repository.url}` : \"\",\n latestVersion?.keywords?.length ? `\\nKeywords: ${latestVersion.keywords.join(\", \")}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n // Dependencies\n if (latestVersion?.dependencies) {\n const deps = Object.entries(latestVersion.dependencies)\n .map(([name, ver]) => `- ${name}: ${ver}`)\n .join(\"\\n\");\n\n await ingestDocument({\n sourceId,\n projectId,\n externalId: `npm-${packageName}-deps`,\n title: `${packageName} — Dependencies`,\n content: `# ${packageName} Dependencies\\n\\n${deps}`,\n metadata: { source: \"npm\", packageName, section: \"dependencies\" },\n });\n indexed++;\n }\n\n // Main exports / types info\n if (latestVersion?.main || latestVersion?.types || latestVersion?.exports) {\n const entryPoints = [\n latestVersion.main ? `Main: ${latestVersion.main}` : \"\",\n latestVersion.types ? `Types: ${latestVersion.types}` : \"\",\n latestVersion.module ? `Module: ${latestVersion.module}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n await ingestDocument({\n sourceId,\n projectId,\n externalId: `npm-${packageName}-overview`,\n title: `${packageName} — Overview`,\n content: `${overview}\\n\\n## Entry Points\\n${entryPoints}`,\n metadata: { source: \"npm\", packageName, version: latest, section: \"overview\" },\n });\n indexed++;\n }\n\n // README\n if (includeReadme && pkg.readme) {\n await ingestDocument({\n sourceId,\n projectId,\n externalId: `npm-${packageName}-readme`,\n title: `${packageName} — README`,\n content: pkg.readme,\n metadata: { source: \"npm\", packageName, section: \"readme\" },\n });\n indexed++;\n }\n\n return { documentsIndexed: indexed };\n}\n","import { ingestDocument } from \"../engine/ingest.js\";\n\ninterface PyPIConfig {\n packageName: string;\n includeDescription?: boolean;\n}\n\nexport async function syncPyPIPackage(\n sourceId: string,\n projectId: string,\n config: PyPIConfig\n) {\n const { packageName, includeDescription = true } = config;\n let indexed = 0;\n\n const res = await fetch(`https://pypi.org/pypi/${encodeURIComponent(packageName)}/json`);\n if (!res.ok) throw new Error(`PyPI API error: ${res.status}`);\n\n const data = await res.json();\n const info = data.info || {};\n\n // Overview document\n const overview = [\n `# ${info.name || packageName}`,\n info.summary ? `\\n${info.summary}` : \"\",\n `\\nVersion: ${info.version || \"unknown\"}`,\n info.license ? `License: ${info.license}` : \"\",\n info.author ? `Author: ${info.author}` : \"\",\n info.home_page ? `Homepage: ${info.home_page}` : \"\",\n info.project_urls?.Documentation ? `Docs: ${info.project_urls.Documentation}` : \"\",\n info.project_urls?.Repository || info.project_urls?.Source\n ? `Repository: ${info.project_urls.Repository || info.project_urls.Source}`\n : \"\",\n info.requires_python ? `\\nPython: ${info.requires_python}` : \"\",\n info.keywords ? `Keywords: ${info.keywords}` : \"\",\n ].filter(Boolean).join(\"\\n\");\n\n await ingestDocument({\n sourceId,\n projectId,\n externalId: `pypi-${packageName}-overview`,\n title: `${packageName} — Overview`,\n content: overview,\n metadata: { source: \"pypi\", packageName, version: info.version, section: \"overview\" },\n });\n indexed++;\n\n // Dependencies\n if (info.requires_dist?.length) {\n const deps = info.requires_dist\n .filter((d: string) => !d.includes(\"extra ==\"))\n .map((d: string) => `- ${d}`)\n .join(\"\\n\");\n\n if (deps) {\n await ingestDocument({\n sourceId,\n projectId,\n externalId: `pypi-${packageName}-deps`,\n title: `${packageName} — Dependencies`,\n content: `# ${packageName} Dependencies\\n\\n${deps}`,\n metadata: { source: \"pypi\", packageName, section: \"dependencies\" },\n });\n indexed++;\n }\n }\n\n // Full description (usually the README in PyPI)\n if (includeDescription && info.description) {\n await ingestDocument({\n sourceId,\n projectId,\n externalId: `pypi-${packageName}-description`,\n title: `${packageName} — Description`,\n content: info.description,\n metadata: {\n source: \"pypi\",\n packageName,\n section: \"description\",\n contentType: info.description_content_type || \"text/plain\",\n },\n });\n indexed++;\n }\n\n return { documentsIndexed: indexed };\n}\n"],"mappings":"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","names":[]}