kirograph 0.12.2 → 0.13.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 (60) hide show
  1. package/README.md +56 -2
  2. package/dist/architecture/layers/index.js +9 -1
  3. package/dist/architecture/layers/index.js.map +2 -2
  4. package/dist/architecture/layers/ocaml.js +105 -0
  5. package/dist/architecture/layers/ocaml.js.map +7 -0
  6. package/dist/architecture/layers/scala.js +120 -0
  7. package/dist/architecture/layers/scala.js.map +7 -0
  8. package/dist/architecture/layers/solidity.js +105 -0
  9. package/dist/architecture/layers/solidity.js.map +7 -0
  10. package/dist/architecture/layers/vue.js +111 -0
  11. package/dist/architecture/layers/vue.js.map +7 -0
  12. package/dist/architecture/manifest/elm.js +91 -0
  13. package/dist/architecture/manifest/elm.js.map +7 -0
  14. package/dist/architecture/manifest/index.js +13 -2
  15. package/dist/architecture/manifest/index.js.map +2 -2
  16. package/dist/architecture/manifest/ocaml.js +166 -0
  17. package/dist/architecture/manifest/ocaml.js.map +7 -0
  18. package/dist/architecture/manifest/scala.js +117 -0
  19. package/dist/architecture/manifest/scala.js.map +7 -0
  20. package/dist/bin/installer/hooks.js +21 -1
  21. package/dist/bin/installer/hooks.js.map +2 -2
  22. package/dist/bin/kirograph.js +1 -1
  23. package/dist/extraction/extractor.js +65 -2
  24. package/dist/extraction/extractor.js.map +2 -2
  25. package/dist/extraction/grammars.js +22 -0
  26. package/dist/extraction/grammars.js.map +2 -2
  27. package/dist/extraction/languages.js +39 -1
  28. package/dist/extraction/languages.js.map +2 -2
  29. package/dist/extraction/wasm/tree-sitter-hcl.wasm +0 -0
  30. package/dist/extraction/wasm/tree-sitter-scss.wasm +0 -0
  31. package/dist/frameworks/amplify.js +175 -0
  32. package/dist/frameworks/amplify.js.map +7 -0
  33. package/dist/frameworks/angular.js +132 -0
  34. package/dist/frameworks/angular.js.map +7 -0
  35. package/dist/frameworks/ansible.js +151 -0
  36. package/dist/frameworks/ansible.js.map +7 -0
  37. package/dist/frameworks/cloudformation.js +148 -0
  38. package/dist/frameworks/cloudformation.js.map +7 -0
  39. package/dist/frameworks/docker.js +149 -0
  40. package/dist/frameworks/docker.js.map +7 -0
  41. package/dist/frameworks/iac.js +401 -0
  42. package/dist/frameworks/iac.js.map +7 -0
  43. package/dist/frameworks/index.js +81 -3
  44. package/dist/frameworks/index.js.map +3 -3
  45. package/dist/frameworks/kubernetes.js +176 -0
  46. package/dist/frameworks/kubernetes.js.map +7 -0
  47. package/dist/frameworks/pulumi.js +93 -0
  48. package/dist/frameworks/pulumi.js.map +7 -0
  49. package/dist/frameworks/scala.js +124 -0
  50. package/dist/frameworks/scala.js.map +7 -0
  51. package/dist/frameworks/solidity.js +93 -0
  52. package/dist/frameworks/solidity.js.map +7 -0
  53. package/dist/frameworks/terraform.js +278 -0
  54. package/dist/frameworks/terraform.js.map +7 -0
  55. package/dist/frameworks/vue.js +163 -0
  56. package/dist/frameworks/vue.js.map +7 -0
  57. package/dist/graph/queries.js +1 -1
  58. package/dist/graph/queries.js.map +1 -1
  59. package/dist/types.js.map +2 -2
  60. package/package.json +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/frameworks/index.ts"],
4
- "sourcesContent": ["/**\n * Framework Resolver Registry\n *\n * Mirrors CodeGraph src/resolution/frameworks/index.ts\n * Manages framework-specific resolvers and detection.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { logDebug, logWarn } from '../errors';\nimport { updateConfig } from '../config';\nimport type { Node } from '../types';\nimport type { GraphDatabase } from '../db/database';\nimport type { FrameworkResolver, ResolutionContext } from './types';\n\n// Re-export types\nexport type { FrameworkResolver, ResolutionContext, UnresolvedRef, ResolvedRef } from './types';\n\n// Re-export individual resolvers\nexport { reactResolver } from './react';\nexport { svelteResolver } from './svelte';\nexport { expressResolver } from './express';\nexport { djangoResolver, flaskResolver, fastapiResolver } from './python';\nexport { railsResolver } from './ruby';\nexport { springResolver } from './java';\nexport { goResolver } from './go';\nexport { rustResolver } from './rust';\nexport { aspnetResolver } from './csharp';\nexport { swiftUIResolver, uikitResolver, vaporResolver } from './swift';\nexport { laravelResolver, FACADE_MAPPINGS } from './laravel';\nexport { phoenixResolver } from './elixir';\n\n// \u2500\u2500 Registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nimport { reactResolver } from './react';\nimport { svelteResolver } from './svelte';\nimport { expressResolver } from './express';\nimport { djangoResolver, flaskResolver, fastapiResolver } from './python';\nimport { railsResolver } from './ruby';\nimport { springResolver } from './java';\nimport { goResolver } from './go';\nimport { rustResolver } from './rust';\nimport { aspnetResolver } from './csharp';\nimport { swiftUIResolver, uikitResolver, vaporResolver } from './swift';\nimport { laravelResolver } from './laravel';\nimport { phoenixResolver } from './elixir';\n\nconst FRAMEWORK_RESOLVERS: FrameworkResolver[] = [\n // PHP\n laravelResolver,\n // JavaScript / TypeScript\n expressResolver,\n reactResolver,\n svelteResolver,\n // Python\n djangoResolver,\n flaskResolver,\n fastapiResolver,\n // Ruby\n railsResolver,\n // Java\n springResolver,\n // Go\n goResolver,\n // Rust\n rustResolver,\n // C#\n aspnetResolver,\n // Swift\n swiftUIResolver,\n uikitResolver,\n vaporResolver,\n // Elixir\n phoenixResolver,\n];\n\nexport function getAllFrameworkResolvers(): FrameworkResolver[] {\n return FRAMEWORK_RESOLVERS;\n}\n\nexport function getFrameworkResolver(name: string): FrameworkResolver | undefined {\n return FRAMEWORK_RESOLVERS.find(r => r.name === name);\n}\n\nexport function registerFrameworkResolver(resolver: FrameworkResolver): void {\n const index = FRAMEWORK_RESOLVERS.findIndex(r => r.name === resolver.name);\n if (index !== -1) FRAMEWORK_RESOLVERS.splice(index, 1);\n FRAMEWORK_RESOLVERS.push(resolver);\n}\n\n// \u2500\u2500 Context builder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction buildResolutionContext(projectRoot: string, db: GraphDatabase): ResolutionContext {\n const fileCache = new Map<string, string | null>();\n const nodeCache = new Map<string, Node[]>();\n\n return {\n getNodesInFile(filePath: string): Node[] {\n if (!nodeCache.has(filePath)) {\n nodeCache.set(filePath, db.getNodesByFile(filePath));\n }\n return nodeCache.get(filePath)!;\n },\n getNodesByName(name: string): Node[] {\n return db.findNodesByExactName(name);\n },\n getNodesByKind(kind: Node['kind']): Node[] {\n return db.getNodesByKind(kind);\n },\n fileExists(filePath: string): boolean {\n return fs.existsSync(path.join(projectRoot, filePath));\n },\n readFile(filePath: string): string | null {\n if (fileCache.has(filePath)) return fileCache.get(filePath)!;\n try {\n const content = fs.readFileSync(path.join(projectRoot, filePath), 'utf8');\n fileCache.set(filePath, content);\n return content;\n } catch {\n fileCache.set(filePath, null);\n return null;\n }\n },\n getProjectRoot(): string {\n return projectRoot;\n },\n getAllFiles(): string[] {\n return db.getAllFiles().map(f => f.path);\n },\n };\n}\n\n// \u2500\u2500 detectFrameworks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Detect which frameworks are used in a project.\n * Mirrors CodeGraph detectFrameworks() \u2014 uses ResolutionContext for file access.\n * Records detected framework names in config via updateConfig().\n */\nexport async function detectFrameworks(projectRoot: string, db?: GraphDatabase): Promise<FrameworkResolver[]> {\n // If no db provided, fall back to package.json-only detection\n if (!db) {\n return detectFromPackageJson(projectRoot);\n }\n\n const context = buildResolutionContext(projectRoot, db);\n const detected: FrameworkResolver[] = [];\n\n for (const resolver of FRAMEWORK_RESOLVERS) {\n try {\n if (resolver.detect(context)) {\n logDebug(`detectFrameworks: detected ${resolver.name}`);\n detected.push(resolver);\n }\n } catch (err) {\n logWarn(`detectFrameworks: error detecting ${resolver.name}`, { error: String(err) });\n }\n }\n\n if (detected.length > 0) {\n await updateConfig(projectRoot, { frameworkHints: detected.map(f => f.name) });\n }\n\n return detected;\n}\n\n/**\n * Lightweight fallback: detect frameworks from package.json only (no DB needed).\n */\nasync function detectFromPackageJson(projectRoot: string): Promise<FrameworkResolver[]> {\n const pkgPath = path.join(projectRoot, 'package.json');\n if (!fs.existsSync(pkgPath)) return [];\n\n let pkg: Record<string, unknown>;\n try {\n pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) as Record<string, unknown>;\n } catch {\n return [];\n }\n\n const deps: Record<string, string> = {\n ...((pkg.dependencies as Record<string, string>) ?? {}),\n ...((pkg.devDependencies as Record<string, string>) ?? {}),\n };\n\n const PACKAGE_TO_RESOLVER: Record<string, string> = {\n react: 'react', next: 'react', 'react-native': 'react',\n svelte: 'svelte', '@sveltejs/kit': 'svelte',\n express: 'express', fastify: 'express', koa: 'express',\n };\n\n const detectedNames = new Set<string>();\n const detected: FrameworkResolver[] = [];\n\n for (const [pkg, resolverName] of Object.entries(PACKAGE_TO_RESOLVER)) {\n if (Object.prototype.hasOwnProperty.call(deps, pkg) && !detectedNames.has(resolverName)) {\n const resolver = getFrameworkResolver(resolverName);\n if (resolver) {\n detectedNames.add(resolverName);\n detected.push(resolver);\n }\n }\n }\n\n if (detected.length > 0) {\n await updateConfig(projectRoot, { frameworkHints: detected.map(f => f.name) });\n }\n\n return detected;\n}\n"],
5
- "mappings": "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",
6
- "names": ["import_react", "import_svelte", "import_express", "import_python", "import_ruby", "import_java", "import_go", "import_rust", "import_csharp", "import_swift", "import_laravel", "import_elixir", "pkg"]
4
+ "sourcesContent": ["/**\n * Framework Resolver Registry\n *\n * Mirrors CodeGraph src/resolution/frameworks/index.ts\n * Manages framework-specific resolvers and detection.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { logDebug, logWarn } from '../errors';\nimport { updateConfig } from '../config';\nimport type { Node } from '../types';\nimport type { GraphDatabase } from '../db/database';\nimport type { FrameworkResolver, ResolutionContext } from './types';\n\n// Re-export types\nexport type { FrameworkResolver, ResolutionContext, UnresolvedRef, ResolvedRef } from './types';\n\n// Re-export individual resolvers\nexport { reactResolver } from './react';\nexport { svelteResolver } from './svelte';\nexport { expressResolver } from './express';\nexport { djangoResolver, flaskResolver, fastapiResolver } from './python';\nexport { railsResolver } from './ruby';\nexport { springResolver } from './java';\nexport { goResolver } from './go';\nexport { rustResolver } from './rust';\nexport { aspnetResolver } from './csharp';\nexport { swiftUIResolver, uikitResolver, vaporResolver } from './swift';\nexport { laravelResolver, FACADE_MAPPINGS } from './laravel';\nexport { phoenixResolver } from './elixir';\nexport { playResolver } from './scala';\nexport { nuxtResolver, vueResolver } from './vue';\nexport { solidityResolver } from './solidity';\nexport { sstResolver, cdkResolver, serverlessResolver, samResolver } from './iac';\nexport { terraformResolver } from './terraform';\nexport { pulumiResolver } from './pulumi';\nexport { cloudformationResolver } from './cloudformation';\nexport { kubernetesResolver } from './kubernetes';\nexport { dockerComposeResolver } from './docker';\nexport { ansibleResolver } from './ansible';\nexport { angularResolver } from './angular';\nexport { amplifyResolver } from './amplify';\n\n// \u2500\u2500 Registry \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nimport { reactResolver } from './react';\nimport { svelteResolver } from './svelte';\nimport { expressResolver } from './express';\nimport { djangoResolver, flaskResolver, fastapiResolver } from './python';\nimport { railsResolver } from './ruby';\nimport { springResolver } from './java';\nimport { goResolver } from './go';\nimport { rustResolver } from './rust';\nimport { aspnetResolver } from './csharp';\nimport { swiftUIResolver, uikitResolver, vaporResolver } from './swift';\nimport { laravelResolver } from './laravel';\nimport { phoenixResolver } from './elixir';\nimport { playResolver } from './scala';\nimport { nuxtResolver, vueResolver } from './vue';\nimport { solidityResolver } from './solidity';\nimport { sstResolver, cdkResolver, serverlessResolver, samResolver } from './iac';\nimport { terraformResolver } from './terraform';\nimport { pulumiResolver } from './pulumi';\nimport { cloudformationResolver } from './cloudformation';\nimport { kubernetesResolver } from './kubernetes';\nimport { dockerComposeResolver } from './docker';\nimport { ansibleResolver } from './ansible';\nimport { angularResolver } from './angular';\nimport { amplifyResolver } from './amplify';\n\nconst FRAMEWORK_RESOLVERS: FrameworkResolver[] = [\n // PHP\n laravelResolver,\n // JavaScript / TypeScript\n expressResolver,\n reactResolver,\n svelteResolver,\n angularResolver,\n // Vue / Nuxt\n nuxtResolver,\n vueResolver,\n // Python\n djangoResolver,\n flaskResolver,\n fastapiResolver,\n // Ruby\n railsResolver,\n // Java\n springResolver,\n // Go\n goResolver,\n // Rust\n rustResolver,\n // C#\n aspnetResolver,\n // Swift\n swiftUIResolver,\n uikitResolver,\n vaporResolver,\n // Elixir\n phoenixResolver,\n // Scala\n playResolver,\n // Solidity\n solidityResolver,\n // Infrastructure as Code\n sstResolver,\n cdkResolver,\n serverlessResolver,\n samResolver,\n terraformResolver,\n pulumiResolver,\n cloudformationResolver,\n amplifyResolver,\n // Containers & Orchestration\n kubernetesResolver,\n dockerComposeResolver,\n // Configuration Management\n ansibleResolver,\n];\n\nexport function getAllFrameworkResolvers(): FrameworkResolver[] {\n return FRAMEWORK_RESOLVERS;\n}\n\nexport function getFrameworkResolver(name: string): FrameworkResolver | undefined {\n return FRAMEWORK_RESOLVERS.find(r => r.name === name);\n}\n\nexport function registerFrameworkResolver(resolver: FrameworkResolver): void {\n const index = FRAMEWORK_RESOLVERS.findIndex(r => r.name === resolver.name);\n if (index !== -1) FRAMEWORK_RESOLVERS.splice(index, 1);\n FRAMEWORK_RESOLVERS.push(resolver);\n}\n\n// \u2500\u2500 Context builder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nfunction buildResolutionContext(projectRoot: string, db: GraphDatabase): ResolutionContext {\n const fileCache = new Map<string, string | null>();\n const nodeCache = new Map<string, Node[]>();\n\n return {\n getNodesInFile(filePath: string): Node[] {\n if (!nodeCache.has(filePath)) {\n nodeCache.set(filePath, db.getNodesByFile(filePath));\n }\n return nodeCache.get(filePath)!;\n },\n getNodesByName(name: string): Node[] {\n return db.findNodesByExactName(name);\n },\n getNodesByKind(kind: Node['kind']): Node[] {\n return db.getNodesByKind(kind);\n },\n fileExists(filePath: string): boolean {\n return fs.existsSync(path.join(projectRoot, filePath));\n },\n readFile(filePath: string): string | null {\n if (fileCache.has(filePath)) return fileCache.get(filePath)!;\n try {\n const content = fs.readFileSync(path.join(projectRoot, filePath), 'utf8');\n fileCache.set(filePath, content);\n return content;\n } catch {\n fileCache.set(filePath, null);\n return null;\n }\n },\n getProjectRoot(): string {\n return projectRoot;\n },\n getAllFiles(): string[] {\n return db.getAllFiles().map(f => f.path);\n },\n };\n}\n\n// \u2500\u2500 detectFrameworks \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/**\n * Detect which frameworks are used in a project.\n * Mirrors CodeGraph detectFrameworks() \u2014 uses ResolutionContext for file access.\n * Records detected framework names in config via updateConfig().\n */\nexport async function detectFrameworks(projectRoot: string, db?: GraphDatabase): Promise<FrameworkResolver[]> {\n // If no db provided, fall back to package.json-only detection\n if (!db) {\n return detectFromPackageJson(projectRoot);\n }\n\n const context = buildResolutionContext(projectRoot, db);\n const detected: FrameworkResolver[] = [];\n\n for (const resolver of FRAMEWORK_RESOLVERS) {\n try {\n if (resolver.detect(context)) {\n logDebug(`detectFrameworks: detected ${resolver.name}`);\n detected.push(resolver);\n }\n } catch (err) {\n logWarn(`detectFrameworks: error detecting ${resolver.name}`, { error: String(err) });\n }\n }\n\n if (detected.length > 0) {\n await updateConfig(projectRoot, { frameworkHints: detected.map(f => f.name) });\n }\n\n return detected;\n}\n\n/**\n * Lightweight fallback: detect frameworks from package.json only (no DB needed).\n */\nasync function detectFromPackageJson(projectRoot: string): Promise<FrameworkResolver[]> {\n const pkgPath = path.join(projectRoot, 'package.json');\n if (!fs.existsSync(pkgPath)) return [];\n\n let pkg: Record<string, unknown>;\n try {\n pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')) as Record<string, unknown>;\n } catch {\n return [];\n }\n\n const deps: Record<string, string> = {\n ...((pkg.dependencies as Record<string, string>) ?? {}),\n ...((pkg.devDependencies as Record<string, string>) ?? {}),\n };\n\n const PACKAGE_TO_RESOLVER: Record<string, string> = {\n react: 'react', next: 'react', 'react-native': 'react',\n svelte: 'svelte', '@sveltejs/kit': 'svelte',\n express: 'express', fastify: 'express', koa: 'express',\n };\n\n const detectedNames = new Set<string>();\n const detected: FrameworkResolver[] = [];\n\n for (const [pkg, resolverName] of Object.entries(PACKAGE_TO_RESOLVER)) {\n if (Object.prototype.hasOwnProperty.call(deps, pkg) && !detectedNames.has(resolverName)) {\n const resolver = getFrameworkResolver(resolverName);\n if (resolver) {\n detectedNames.add(resolverName);\n detected.push(resolver);\n }\n }\n }\n\n if (detected.length > 0) {\n await updateConfig(projectRoot, { frameworkHints: detected.map(f => f.name) });\n }\n\n return detected;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_react", "import_svelte", "import_express", "import_python", "import_ruby", "import_java", "import_go", "import_rust", "import_csharp", "import_swift", "import_laravel", "import_elixir", "import_scala", "import_vue", "import_solidity", "import_iac", "import_terraform", "import_pulumi", "import_cloudformation", "import_kubernetes", "import_docker", "import_ansible", "import_angular", "import_amplify", "pkg"]
7
7
  }
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var kubernetes_exports = {};
20
+ __export(kubernetes_exports, {
21
+ kubernetesResolver: () => kubernetesResolver
22
+ });
23
+ module.exports = __toCommonJS(kubernetes_exports);
24
+ const kubernetesResolver = {
25
+ name: "kubernetes",
26
+ detect(context) {
27
+ if (context.fileExists("Chart.yaml") || context.fileExists("Chart.yml")) return true;
28
+ if (context.getAllFiles().some(
29
+ (f) => (f.includes("k8s/") || f.includes("kubernetes/") || f.includes("manifests/") || f.includes("deploy/")) && (f.endsWith(".yaml") || f.endsWith(".yml"))
30
+ )) {
31
+ for (const file of context.getAllFiles()) {
32
+ if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
33
+ if (!file.includes("k8s/") && !file.includes("kubernetes/") && !file.includes("manifests/") && !file.includes("deploy/")) continue;
34
+ const content = context.readFile(file);
35
+ if (content && content.includes("apiVersion:") && content.includes("kind:")) return true;
36
+ }
37
+ }
38
+ return false;
39
+ },
40
+ resolve(ref, context) {
41
+ if (/^[a-z][a-z0-9-]*$/.test(ref.referenceName)) {
42
+ const id = resolveK8sResource(ref.referenceName, context);
43
+ if (id) return { original: ref, targetNodeId: id, confidence: 0.75, resolvedBy: "framework" };
44
+ }
45
+ return null;
46
+ },
47
+ extractNodes(filePath, content) {
48
+ const nodes = [];
49
+ const now = Date.now();
50
+ if (!content.includes("apiVersion:") || !content.includes("kind:")) return nodes;
51
+ const documents = content.split(/^---\s*$/m);
52
+ for (const doc of documents) {
53
+ if (!doc.trim()) continue;
54
+ const kindMatch = doc.match(/^kind:\s*(\w+)/m);
55
+ const nameMatch = doc.match(/^\s+name:\s*["']?([^\s"']+)/m);
56
+ const apiVersionMatch = doc.match(/^apiVersion:\s*(\S+)/m);
57
+ if (!kindMatch || !nameMatch) continue;
58
+ const kind = kindMatch[1];
59
+ const name = nameMatch[1];
60
+ const apiVersion = apiVersionMatch ? apiVersionMatch[1] : "";
61
+ const docStart = content.indexOf(doc);
62
+ const line = content.slice(0, docStart).split("\n").length;
63
+ const nodeKind = mapK8sKind(kind);
64
+ if (!nodeKind) continue;
65
+ nodes.push({
66
+ id: `k8s:${filePath}:${kind}:${name}:${line}`,
67
+ kind: nodeKind,
68
+ name: `${kind}/${name}`,
69
+ qualifiedName: `${filePath}::${kind}.${name}`,
70
+ filePath,
71
+ startLine: line,
72
+ endLine: line + doc.split("\n").length - 1,
73
+ startColumn: 0,
74
+ endColumn: 0,
75
+ language: "yaml",
76
+ updatedAt: now,
77
+ signature: `${kind} (${apiVersion})`
78
+ });
79
+ if (kind === "Ingress") {
80
+ const pathPattern = /path:\s*["']?([^\s"']+)["']?/g;
81
+ let pathMatch;
82
+ while ((pathMatch = pathPattern.exec(doc)) !== null) {
83
+ const pathLine = content.slice(0, docStart).split("\n").length + doc.slice(0, pathMatch.index).split("\n").length - 1;
84
+ const routePath = pathMatch[1];
85
+ nodes.push({
86
+ id: `route:${filePath}:INGRESS:${routePath}:${pathLine}`,
87
+ kind: "route",
88
+ name: `INGRESS ${routePath}`,
89
+ qualifiedName: `${filePath}::ingress.${routePath}`,
90
+ filePath,
91
+ startLine: pathLine,
92
+ endLine: pathLine,
93
+ startColumn: 0,
94
+ endColumn: pathMatch[0].length,
95
+ language: "yaml",
96
+ updatedAt: now
97
+ });
98
+ }
99
+ }
100
+ if (kind === "Service") {
101
+ const portPattern = /port:\s*(\d+)/g;
102
+ let portMatch;
103
+ while ((portMatch = portPattern.exec(doc)) !== null) {
104
+ const portLine = content.slice(0, docStart).split("\n").length + doc.slice(0, portMatch.index).split("\n").length - 1;
105
+ const port = portMatch[1];
106
+ nodes.push({
107
+ id: `route:${filePath}:SVC:${name}:${port}:${portLine}`,
108
+ kind: "route",
109
+ name: `${name}:${port}`,
110
+ qualifiedName: `${filePath}::svc.${name}.${port}`,
111
+ filePath,
112
+ startLine: portLine,
113
+ endLine: portLine,
114
+ startColumn: 0,
115
+ endColumn: portMatch[0].length,
116
+ language: "yaml",
117
+ updatedAt: now
118
+ });
119
+ }
120
+ }
121
+ }
122
+ return nodes;
123
+ }
124
+ };
125
+ function mapK8sKind(kind) {
126
+ switch (kind) {
127
+ case "Deployment":
128
+ case "StatefulSet":
129
+ case "DaemonSet":
130
+ case "Job":
131
+ case "CronJob":
132
+ return "component";
133
+ case "Service":
134
+ case "Ingress":
135
+ case "Gateway":
136
+ case "VirtualService":
137
+ return "route";
138
+ case "ConfigMap":
139
+ case "Secret":
140
+ return "variable";
141
+ case "Namespace":
142
+ return "namespace";
143
+ case "ServiceAccount":
144
+ case "Role":
145
+ case "ClusterRole":
146
+ case "RoleBinding":
147
+ case "ClusterRoleBinding":
148
+ return "interface";
149
+ case "PersistentVolumeClaim":
150
+ case "PersistentVolume":
151
+ case "StorageClass":
152
+ return "variable";
153
+ case "HorizontalPodAutoscaler":
154
+ case "NetworkPolicy":
155
+ return "variable";
156
+ case "CustomResourceDefinition":
157
+ return "type_alias";
158
+ default:
159
+ return "class";
160
+ }
161
+ }
162
+ function resolveK8sResource(name, context) {
163
+ for (const file of context.getAllFiles()) {
164
+ if (!file.endsWith(".yaml") && !file.endsWith(".yml")) continue;
165
+ const node = context.getNodesInFile(file).find(
166
+ (n) => n.name.endsWith(`/${name}`) || n.name === name
167
+ );
168
+ if (node) return node.id;
169
+ }
170
+ return null;
171
+ }
172
+ // Annotate the CommonJS export names for ESM import in node:
173
+ 0 && (module.exports = {
174
+ kubernetesResolver
175
+ });
176
+ //# sourceMappingURL=kubernetes.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/frameworks/kubernetes.ts"],
4
+ "sourcesContent": ["/**\n * Kubernetes / Helm Framework Resolver\n *\n * Extracts Deployments, Services, ConfigMaps, Ingress routes from K8s manifests.\n * Detects both raw manifests and Helm charts.\n */\n\nimport type { Node } from '../types';\nimport type { FrameworkResolver, UnresolvedRef, ResolvedRef, ResolutionContext } from './types';\n\nexport const kubernetesResolver: FrameworkResolver = {\n name: 'kubernetes',\n detect(context: ResolutionContext): boolean {\n // Helm chart\n if (context.fileExists('Chart.yaml') || context.fileExists('Chart.yml')) return true;\n // K8s manifests directory\n if (context.getAllFiles().some(f =>\n (f.includes('k8s/') || f.includes('kubernetes/') || f.includes('manifests/') || f.includes('deploy/')) &&\n (f.endsWith('.yaml') || f.endsWith('.yml'))\n )) {\n // Verify at least one file has apiVersion\n for (const file of context.getAllFiles()) {\n if (!file.endsWith('.yaml') && !file.endsWith('.yml')) continue;\n if (!file.includes('k8s/') && !file.includes('kubernetes/') && !file.includes('manifests/') && !file.includes('deploy/')) continue;\n const content = context.readFile(file);\n if (content && content.includes('apiVersion:') && content.includes('kind:')) return true;\n }\n }\n return false;\n },\n resolve(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null {\n // Resolve K8s resource name references (e.g., service names, configmap names)\n if (/^[a-z][a-z0-9-]*$/.test(ref.referenceName)) {\n const id = resolveK8sResource(ref.referenceName, context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.75, resolvedBy: 'framework' };\n }\n return null;\n },\n extractNodes(filePath: string, content: string): Node[] {\n const nodes: Node[] = [];\n const now = Date.now();\n\n if (!content.includes('apiVersion:') || !content.includes('kind:')) return nodes;\n\n // Split multi-document YAML\n const documents = content.split(/^---\\s*$/m);\n\n for (const doc of documents) {\n if (!doc.trim()) continue;\n\n const kindMatch = doc.match(/^kind:\\s*(\\w+)/m);\n const nameMatch = doc.match(/^\\s+name:\\s*[\"']?([^\\s\"']+)/m);\n const apiVersionMatch = doc.match(/^apiVersion:\\s*(\\S+)/m);\n\n if (!kindMatch || !nameMatch) continue;\n\n const kind = kindMatch[1]!;\n const name = nameMatch[1]!;\n const apiVersion = apiVersionMatch ? apiVersionMatch[1]! : '';\n const docStart = content.indexOf(doc);\n const line = content.slice(0, docStart).split('\\n').length;\n\n // Map K8s kinds to graph node kinds\n const nodeKind = mapK8sKind(kind);\n if (!nodeKind) continue;\n\n nodes.push({\n id: `k8s:${filePath}:${kind}:${name}:${line}`,\n kind: nodeKind,\n name: `${kind}/${name}`,\n qualifiedName: `${filePath}::${kind}.${name}`,\n filePath, startLine: line, endLine: line + doc.split('\\n').length - 1,\n startColumn: 0, endColumn: 0,\n language: 'yaml', updatedAt: now,\n signature: `${kind} (${apiVersion})`,\n });\n\n // Extract Ingress routes\n if (kind === 'Ingress') {\n const pathPattern = /path:\\s*[\"']?([^\\s\"']+)[\"']?/g;\n let pathMatch: RegExpExecArray | null;\n while ((pathMatch = pathPattern.exec(doc)) !== null) {\n const pathLine = content.slice(0, docStart).split('\\n').length +\n doc.slice(0, pathMatch.index).split('\\n').length - 1;\n const routePath = pathMatch[1]!;\n nodes.push({\n id: `route:${filePath}:INGRESS:${routePath}:${pathLine}`,\n kind: 'route',\n name: `INGRESS ${routePath}`,\n qualifiedName: `${filePath}::ingress.${routePath}`,\n filePath, startLine: pathLine, endLine: pathLine, startColumn: 0, endColumn: pathMatch[0].length,\n language: 'yaml', updatedAt: now,\n });\n }\n }\n\n // Extract Service ports\n if (kind === 'Service') {\n const portPattern = /port:\\s*(\\d+)/g;\n let portMatch: RegExpExecArray | null;\n while ((portMatch = portPattern.exec(doc)) !== null) {\n const portLine = content.slice(0, docStart).split('\\n').length +\n doc.slice(0, portMatch.index).split('\\n').length - 1;\n const port = portMatch[1]!;\n nodes.push({\n id: `route:${filePath}:SVC:${name}:${port}:${portLine}`,\n kind: 'route',\n name: `${name}:${port}`,\n qualifiedName: `${filePath}::svc.${name}.${port}`,\n filePath, startLine: portLine, endLine: portLine, startColumn: 0, endColumn: portMatch[0].length,\n language: 'yaml', updatedAt: now,\n });\n }\n }\n }\n\n return nodes;\n },\n};\n\nfunction mapK8sKind(kind: string): Node['kind'] | null {\n switch (kind) {\n case 'Deployment':\n case 'StatefulSet':\n case 'DaemonSet':\n case 'Job':\n case 'CronJob':\n return 'component';\n case 'Service':\n case 'Ingress':\n case 'Gateway':\n case 'VirtualService':\n return 'route';\n case 'ConfigMap':\n case 'Secret':\n return 'variable';\n case 'Namespace':\n return 'namespace';\n case 'ServiceAccount':\n case 'Role':\n case 'ClusterRole':\n case 'RoleBinding':\n case 'ClusterRoleBinding':\n return 'interface';\n case 'PersistentVolumeClaim':\n case 'PersistentVolume':\n case 'StorageClass':\n return 'variable';\n case 'HorizontalPodAutoscaler':\n case 'NetworkPolicy':\n return 'variable';\n case 'CustomResourceDefinition':\n return 'type_alias';\n default:\n return 'class';\n }\n}\n\nfunction resolveK8sResource(name: string, context: ResolutionContext): string | null {\n for (const file of context.getAllFiles()) {\n if (!file.endsWith('.yaml') && !file.endsWith('.yml')) continue;\n const node = context.getNodesInFile(file).find(n =>\n n.name.endsWith(`/${name}`) || n.name === name\n );\n if (node) return node.id;\n }\n return null;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var pulumi_exports = {};
20
+ __export(pulumi_exports, {
21
+ pulumiResolver: () => pulumiResolver
22
+ });
23
+ module.exports = __toCommonJS(pulumi_exports);
24
+ const pulumiResolver = {
25
+ name: "pulumi",
26
+ detect(context) {
27
+ if (context.fileExists("Pulumi.yaml") || context.fileExists("Pulumi.yml")) return true;
28
+ const pkg = context.readFile("package.json");
29
+ if (pkg) {
30
+ try {
31
+ const parsed = JSON.parse(pkg);
32
+ const deps = { ...parsed.dependencies, ...parsed.devDependencies };
33
+ if (Object.keys(deps).some((d) => d.startsWith("@pulumi/"))) return true;
34
+ } catch {
35
+ }
36
+ }
37
+ const requirements = context.readFile("requirements.txt");
38
+ if (requirements && requirements.includes("pulumi")) return true;
39
+ return false;
40
+ },
41
+ resolve(ref, context) {
42
+ if (/^[a-z][a-zA-Z0-9]*\.[a-zA-Z]/.test(ref.referenceName)) {
43
+ const varName = ref.referenceName.split(".")[0];
44
+ const id = resolveInDirs(varName, ["index", "src", "infra", "infrastructure", "lib"], context);
45
+ if (id) return { original: ref, targetNodeId: id, confidence: 0.75, resolvedBy: "framework" };
46
+ }
47
+ if (/^[A-Z][a-zA-Z]+$/.test(ref.referenceName)) {
48
+ const id = resolveInDirs(ref.referenceName, ["components", "src", "infra", "lib"], context);
49
+ if (id) return { original: ref, targetNodeId: id, confidence: 0.7, resolvedBy: "framework" };
50
+ }
51
+ return null;
52
+ },
53
+ extractNodes(filePath, content) {
54
+ const nodes = [];
55
+ const now = Date.now();
56
+ const routePattern = /path\s*:\s*["']([^"']+)["'][^}]*method\s*:\s*["'](\w+)["']/g;
57
+ let match;
58
+ while ((match = routePattern.exec(content)) !== null) {
59
+ const line = content.slice(0, match.index).split("\n").length;
60
+ const routePath = match[1];
61
+ const method = match[2].toUpperCase();
62
+ const name = `${method} ${routePath}`;
63
+ nodes.push({
64
+ id: `route:${filePath}:${method}:${routePath}:${line}`,
65
+ kind: "route",
66
+ name,
67
+ qualifiedName: `${filePath}::${name}`,
68
+ filePath,
69
+ startLine: line,
70
+ endLine: line,
71
+ startColumn: 0,
72
+ endColumn: match[0].length,
73
+ language: filePath.endsWith(".py") ? "python" : "typescript",
74
+ updatedAt: now
75
+ });
76
+ }
77
+ return nodes;
78
+ }
79
+ };
80
+ function resolveInDirs(name, dirs, context) {
81
+ for (const file of context.getAllFiles()) {
82
+ if (!(file.endsWith(".ts") || file.endsWith(".js") || file.endsWith(".py") || file.endsWith(".go"))) continue;
83
+ if (!dirs.some((d) => file.includes(`/${d}/`) || file.includes(`/${d}.`))) continue;
84
+ const node = context.getNodesInFile(file).find((n) => n.name === name);
85
+ if (node) return node.id;
86
+ }
87
+ return null;
88
+ }
89
+ // Annotate the CommonJS export names for ESM import in node:
90
+ 0 && (module.exports = {
91
+ pulumiResolver
92
+ });
93
+ //# sourceMappingURL=pulumi.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/frameworks/pulumi.ts"],
4
+ "sourcesContent": ["/**\n * Pulumi Framework Resolver\n *\n * Pulumi is already TypeScript/Python/Go code \u2014 tree-sitter handles parsing.\n * This resolver adds detection, resource reference resolution, and route extraction.\n */\n\nimport type { Node } from '../types';\nimport type { FrameworkResolver, UnresolvedRef, ResolvedRef, ResolutionContext } from './types';\n\nexport const pulumiResolver: FrameworkResolver = {\n name: 'pulumi',\n detect(context: ResolutionContext): boolean {\n if (context.fileExists('Pulumi.yaml') || context.fileExists('Pulumi.yml')) return true;\n const pkg = context.readFile('package.json');\n if (pkg) {\n try {\n const parsed = JSON.parse(pkg);\n const deps = { ...parsed.dependencies, ...parsed.devDependencies };\n if (Object.keys(deps).some(d => d.startsWith('@pulumi/'))) return true;\n } catch { /* ignore */ }\n }\n // Python\n const requirements = context.readFile('requirements.txt');\n if (requirements && requirements.includes('pulumi')) return true;\n return false;\n },\n resolve(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null {\n // Resolve resource property references (e.g., bucket.bucketName)\n if (/^[a-z][a-zA-Z0-9]*\\.[a-zA-Z]/.test(ref.referenceName)) {\n const varName = ref.referenceName.split('.')[0]!;\n const id = resolveInDirs(varName, ['index', 'src', 'infra', 'infrastructure', 'lib'], context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.75, resolvedBy: 'framework' };\n }\n // Resolve component/stack class references\n if (/^[A-Z][a-zA-Z]+$/.test(ref.referenceName)) {\n const id = resolveInDirs(ref.referenceName, ['components', 'src', 'infra', 'lib'], context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.7, resolvedBy: 'framework' };\n }\n return null;\n },\n extractNodes(filePath: string, content: string): Node[] {\n const nodes: Node[] = [];\n const now = Date.now();\n\n // Extract Pulumi API Gateway routes (awsx, apigateway)\n // Pattern: { path: \"/users\", method: \"GET\", ... }\n const routePattern = /path\\s*:\\s*[\"']([^\"']+)[\"'][^}]*method\\s*:\\s*[\"'](\\w+)[\"']/g;\n let match: RegExpExecArray | null;\n while ((match = routePattern.exec(content)) !== null) {\n const line = content.slice(0, match.index).split('\\n').length;\n const routePath = match[1]!;\n const method = match[2]!.toUpperCase();\n const name = `${method} ${routePath}`;\n nodes.push({\n id: `route:${filePath}:${method}:${routePath}:${line}`,\n kind: 'route', name,\n qualifiedName: `${filePath}::${name}`,\n filePath, startLine: line, endLine: line, startColumn: 0, endColumn: match[0].length,\n language: filePath.endsWith('.py') ? 'python' : 'typescript', updatedAt: now,\n });\n }\n\n return nodes;\n },\n};\n\nfunction resolveInDirs(name: string, dirs: string[], context: ResolutionContext): string | null {\n for (const file of context.getAllFiles()) {\n if (!(file.endsWith('.ts') || file.endsWith('.js') || file.endsWith('.py') || file.endsWith('.go'))) continue;\n if (!dirs.some(d => file.includes(`/${d}/`) || file.includes(`/${d}.`))) continue;\n const node = context.getNodesInFile(file).find(n => n.name === name);\n if (node) return node.id;\n }\n return null;\n}\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAUO,MAAM,iBAAoC;AAAA,EAC/C,MAAM;AAAA,EACN,OAAO,SAAqC;AAC1C,QAAI,QAAQ,WAAW,aAAa,KAAK,QAAQ,WAAW,YAAY,EAAG,QAAO;AAClF,UAAM,MAAM,QAAQ,SAAS,cAAc;AAC3C,QAAI,KAAK;AACP,UAAI;AACF,cAAM,SAAS,KAAK,MAAM,GAAG;AAC7B,cAAM,OAAO,EAAE,GAAG,OAAO,cAAc,GAAG,OAAO,gBAAgB;AACjE,YAAI,OAAO,KAAK,IAAI,EAAE,KAAK,OAAK,EAAE,WAAW,UAAU,CAAC,EAAG,QAAO;AAAA,MACpE,QAAQ;AAAA,MAAe;AAAA,IACzB;AAEA,UAAM,eAAe,QAAQ,SAAS,kBAAkB;AACxD,QAAI,gBAAgB,aAAa,SAAS,QAAQ,EAAG,QAAO;AAC5D,WAAO;AAAA,EACT;AAAA,EACA,QAAQ,KAAoB,SAAgD;AAE1E,QAAI,+BAA+B,KAAK,IAAI,aAAa,GAAG;AAC1D,YAAM,UAAU,IAAI,cAAc,MAAM,GAAG,EAAE,CAAC;AAC9C,YAAM,KAAK,cAAc,SAAS,CAAC,SAAS,OAAO,SAAS,kBAAkB,KAAK,GAAG,OAAO;AAC7F,UAAI,GAAI,QAAO,EAAE,UAAU,KAAK,cAAc,IAAI,YAAY,MAAM,YAAY,YAAY;AAAA,IAC9F;AAEA,QAAI,mBAAmB,KAAK,IAAI,aAAa,GAAG;AAC9C,YAAM,KAAK,cAAc,IAAI,eAAe,CAAC,cAAc,OAAO,SAAS,KAAK,GAAG,OAAO;AAC1F,UAAI,GAAI,QAAO,EAAE,UAAU,KAAK,cAAc,IAAI,YAAY,KAAK,YAAY,YAAY;AAAA,IAC7F;AACA,WAAO;AAAA,EACT;AAAA,EACA,aAAa,UAAkB,SAAyB;AACtD,UAAM,QAAgB,CAAC;AACvB,UAAM,MAAM,KAAK,IAAI;AAIrB,UAAM,eAAe;AACrB,QAAI;AACJ,YAAQ,QAAQ,aAAa,KAAK,OAAO,OAAO,MAAM;AACpD,YAAM,OAAO,QAAQ,MAAM,GAAG,MAAM,KAAK,EAAE,MAAM,IAAI,EAAE;AACvD,YAAM,YAAY,MAAM,CAAC;AACzB,YAAM,SAAS,MAAM,CAAC,EAAG,YAAY;AACrC,YAAM,OAAO,GAAG,MAAM,IAAI,SAAS;AACnC,YAAM,KAAK;AAAA,QACT,IAAI,SAAS,QAAQ,IAAI,MAAM,IAAI,SAAS,IAAI,IAAI;AAAA,QACpD,MAAM;AAAA,QAAS;AAAA,QACf,eAAe,GAAG,QAAQ,KAAK,IAAI;AAAA,QACnC;AAAA,QAAU,WAAW;AAAA,QAAM,SAAS;AAAA,QAAM,aAAa;AAAA,QAAG,WAAW,MAAM,CAAC,EAAE;AAAA,QAC9E,UAAU,SAAS,SAAS,KAAK,IAAI,WAAW;AAAA,QAAc,WAAW;AAAA,MAC3E,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT;AACF;AAEA,SAAS,cAAc,MAAc,MAAgB,SAA2C;AAC9F,aAAW,QAAQ,QAAQ,YAAY,GAAG;AACxC,QAAI,EAAE,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,KAAK,GAAI;AACrG,QAAI,CAAC,KAAK,KAAK,OAAK,KAAK,SAAS,IAAI,CAAC,GAAG,KAAK,KAAK,SAAS,IAAI,CAAC,GAAG,CAAC,EAAG;AACzE,UAAM,OAAO,QAAQ,eAAe,IAAI,EAAE,KAAK,OAAK,EAAE,SAAS,IAAI;AACnE,QAAI,KAAM,QAAO,KAAK;AAAA,EACxB;AACA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var scala_exports = {};
20
+ __export(scala_exports, {
21
+ playResolver: () => playResolver
22
+ });
23
+ module.exports = __toCommonJS(scala_exports);
24
+ const playResolver = {
25
+ name: "play",
26
+ detect(context) {
27
+ const buildSbt = context.readFile("build.sbt");
28
+ if (buildSbt && (buildSbt.includes("PlayScala") || buildSbt.includes("play-"))) return true;
29
+ const plugins = context.readFile("project/plugins.sbt");
30
+ if (plugins && plugins.includes("sbt-plugin")) return true;
31
+ return context.getAllFiles().some((f) => f.includes("/controllers/") && f.endsWith(".scala"));
32
+ },
33
+ resolve(ref, context) {
34
+ if (ref.referenceName.endsWith("Controller")) {
35
+ const id = resolveInDirs(ref.referenceName, ["controllers", "app/controllers"], ".scala", "class", context);
36
+ if (id) return { original: ref, targetNodeId: id, confidence: 0.85, resolvedBy: "framework" };
37
+ }
38
+ if (ref.referenceName.endsWith("Service") || ref.referenceName.endsWith("Repository")) {
39
+ const id = resolveInDirs(ref.referenceName, ["services", "repositories", "app/services", "app/repositories"], ".scala", null, context);
40
+ if (id) return { original: ref, targetNodeId: id, confidence: 0.8, resolvedBy: "framework" };
41
+ }
42
+ if (/^[A-Z][a-zA-Z]+$/.test(ref.referenceName)) {
43
+ const id = resolveInDirs(ref.referenceName, ["models", "app/models", "domain"], ".scala", "class", context);
44
+ if (id) return { original: ref, targetNodeId: id, confidence: 0.7, resolvedBy: "framework" };
45
+ }
46
+ return null;
47
+ },
48
+ extractNodes(filePath, content) {
49
+ const nodes = [];
50
+ const now = Date.now();
51
+ if (filePath.endsWith("/routes") || filePath.endsWith("/routes.conf")) {
52
+ const routePattern = /^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\s+(\S+)/gm;
53
+ let match;
54
+ while ((match = routePattern.exec(content)) !== null) {
55
+ const line = content.slice(0, match.index).split("\n").length;
56
+ const [, method, routePath] = match;
57
+ const name = `${method} ${routePath}`;
58
+ nodes.push({
59
+ id: `route:${filePath}:${method}:${routePath}:${line}`,
60
+ kind: "route",
61
+ name,
62
+ qualifiedName: `${filePath}::${name}`,
63
+ filePath,
64
+ startLine: line,
65
+ endLine: line,
66
+ startColumn: 0,
67
+ endColumn: match[0].length,
68
+ language: "scala",
69
+ updatedAt: now
70
+ });
71
+ }
72
+ return nodes;
73
+ }
74
+ const dslPatterns = [
75
+ // Akka HTTP: path("users") { get { ... } }
76
+ /(?:path|pathPrefix)\s*\(\s*"([^"]+)"\s*\)/g,
77
+ // http4s: case GET -> Root / "users"
78
+ /case\s+(GET|POST|PUT|PATCH|DELETE)\s+->\s+Root\s*\/\s*"([^"]+)"/g
79
+ ];
80
+ for (const pattern of dslPatterns) {
81
+ let match;
82
+ while ((match = pattern.exec(content)) !== null) {
83
+ const line = content.slice(0, match.index).split("\n").length;
84
+ const isHttp4s = pattern.source.includes("case");
85
+ const method = isHttp4s ? match[1] : "ANY";
86
+ const routePath = isHttp4s ? `/${match[2]}` : `/${match[1]}`;
87
+ const name = `${method} ${routePath}`;
88
+ const id = `route:${filePath}:${method}:${routePath}:${line}`;
89
+ if (!nodes.some((n) => n.id === id)) {
90
+ nodes.push({
91
+ id,
92
+ kind: "route",
93
+ name,
94
+ qualifiedName: `${filePath}::${name}`,
95
+ filePath,
96
+ startLine: line,
97
+ endLine: line,
98
+ startColumn: 0,
99
+ endColumn: match[0].length,
100
+ language: "scala",
101
+ updatedAt: now
102
+ });
103
+ }
104
+ }
105
+ }
106
+ return nodes;
107
+ }
108
+ };
109
+ function resolveInDirs(name, dirs, ext, kind, context) {
110
+ for (const file of context.getAllFiles()) {
111
+ if (file.endsWith(ext) && dirs.some((d) => file.includes(`/${d}/`) || file.includes(`/${d}`))) {
112
+ const node = context.getNodesInFile(file).find(
113
+ (n) => n.name === name && (kind === null || n.kind === kind)
114
+ );
115
+ if (node) return node.id;
116
+ }
117
+ }
118
+ return null;
119
+ }
120
+ // Annotate the CommonJS export names for ESM import in node:
121
+ 0 && (module.exports = {
122
+ playResolver
123
+ });
124
+ //# sourceMappingURL=scala.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/frameworks/scala.ts"],
4
+ "sourcesContent": ["/**\n * Scala Framework Resolver (Play, Akka HTTP, http4s)\n */\n\nimport type { Node } from '../types';\nimport type { FrameworkResolver, UnresolvedRef, ResolvedRef, ResolutionContext } from './types';\n\nexport const playResolver: FrameworkResolver = {\n name: 'play',\n detect(context: ResolutionContext): boolean {\n // Check build.sbt or plugins.sbt for Play plugin\n const buildSbt = context.readFile('build.sbt');\n if (buildSbt && (buildSbt.includes('PlayScala') || buildSbt.includes('play-'))) return true;\n const plugins = context.readFile('project/plugins.sbt');\n if (plugins && plugins.includes('sbt-plugin')) return true;\n return context.getAllFiles().some(f => f.includes('/controllers/') && f.endsWith('.scala'));\n },\n resolve(ref: UnresolvedRef, context: ResolutionContext): ResolvedRef | null {\n // Resolve controller references\n if (ref.referenceName.endsWith('Controller')) {\n const id = resolveInDirs(ref.referenceName, ['controllers', 'app/controllers'], '.scala', 'class', context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.85, resolvedBy: 'framework' };\n }\n // Resolve service references\n if (ref.referenceName.endsWith('Service') || ref.referenceName.endsWith('Repository')) {\n const id = resolveInDirs(ref.referenceName, ['services', 'repositories', 'app/services', 'app/repositories'], '.scala', null, context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.8, resolvedBy: 'framework' };\n }\n // Resolve model references\n if (/^[A-Z][a-zA-Z]+$/.test(ref.referenceName)) {\n const id = resolveInDirs(ref.referenceName, ['models', 'app/models', 'domain'], '.scala', 'class', context);\n if (id) return { original: ref, targetNodeId: id, confidence: 0.7, resolvedBy: 'framework' };\n }\n return null;\n },\n extractNodes(filePath: string, content: string): Node[] {\n const nodes: Node[] = [];\n const now = Date.now();\n\n // Play routes file (conf/routes)\n if (filePath.endsWith('/routes') || filePath.endsWith('/routes.conf')) {\n const routePattern = /^(GET|POST|PUT|PATCH|DELETE|HEAD|OPTIONS)\\s+(\\S+)/gm;\n let match: RegExpExecArray | null;\n while ((match = routePattern.exec(content)) !== null) {\n const line = content.slice(0, match.index).split('\\n').length;\n const [, method, routePath] = match;\n const name = `${method} ${routePath}`;\n nodes.push({\n id: `route:${filePath}:${method}:${routePath}:${line}`,\n kind: 'route', name,\n qualifiedName: `${filePath}::${name}`,\n filePath, startLine: line, endLine: line, startColumn: 0, endColumn: match[0].length,\n language: 'scala', updatedAt: now,\n });\n }\n return nodes;\n }\n\n // Akka HTTP / http4s route DSL\n const dslPatterns = [\n // Akka HTTP: path(\"users\") { get { ... } }\n /(?:path|pathPrefix)\\s*\\(\\s*\"([^\"]+)\"\\s*\\)/g,\n // http4s: case GET -> Root / \"users\"\n /case\\s+(GET|POST|PUT|PATCH|DELETE)\\s+->\\s+Root\\s*\\/\\s*\"([^\"]+)\"/g,\n ];\n for (const pattern of dslPatterns) {\n let match: RegExpExecArray | null;\n while ((match = pattern.exec(content)) !== null) {\n const line = content.slice(0, match.index).split('\\n').length;\n const isHttp4s = pattern.source.includes('case');\n const method = isHttp4s ? match[1]! : 'ANY';\n const routePath = isHttp4s ? `/${match[2]}` : `/${match[1]}`;\n const name = `${method} ${routePath}`;\n const id = `route:${filePath}:${method}:${routePath}:${line}`;\n if (!nodes.some(n => n.id === id)) {\n nodes.push({\n id, kind: 'route', name,\n qualifiedName: `${filePath}::${name}`,\n filePath, startLine: line, endLine: line, startColumn: 0, endColumn: match[0].length,\n language: 'scala', updatedAt: now,\n });\n }\n }\n }\n\n return nodes;\n },\n};\n\nfunction resolveInDirs(name: string, dirs: string[], ext: string, kind: string | null, context: ResolutionContext): string | null {\n for (const file of context.getAllFiles()) {\n if (file.endsWith(ext) && dirs.some(d => file.includes(`/${d}/`) || file.includes(`/${d}`))) {\n const node = context.getNodesInFile(file).find(\n n => n.name === name && (kind === null || n.kind === kind)\n );\n if (node) return node.id;\n }\n }\n return null;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var solidity_exports = {};
20
+ __export(solidity_exports, {
21
+ solidityResolver: () => solidityResolver
22
+ });
23
+ module.exports = __toCommonJS(solidity_exports);
24
+ const solidityResolver = {
25
+ name: "solidity",
26
+ detect(context) {
27
+ if (context.fileExists("hardhat.config.ts") || context.fileExists("hardhat.config.js")) return true;
28
+ if (context.fileExists("foundry.toml")) return true;
29
+ if (context.fileExists("truffle-config.js")) return true;
30
+ return context.getAllFiles().some((f) => f.endsWith(".sol"));
31
+ },
32
+ resolve(ref, context) {
33
+ if (ref.referenceName.startsWith("I") && /^I[A-Z]/.test(ref.referenceName)) {
34
+ const id = resolveInterface(ref.referenceName, context);
35
+ if (id) return { original: ref, targetNodeId: id, confidence: 0.85, resolvedBy: "framework" };
36
+ }
37
+ if (/^[A-Z][a-zA-Z0-9]+$/.test(ref.referenceName)) {
38
+ const id = resolveContract(ref.referenceName, context);
39
+ if (id) return { original: ref, targetNodeId: id, confidence: 0.8, resolvedBy: "framework" };
40
+ }
41
+ if (ref.referenceKind === "function") {
42
+ const id = resolveLibraryFunction(ref.referenceName, context);
43
+ if (id) return { original: ref, targetNodeId: id, confidence: 0.75, resolvedBy: "framework" };
44
+ }
45
+ return null;
46
+ },
47
+ extractNodes(filePath, content) {
48
+ return [];
49
+ }
50
+ };
51
+ function resolveInterface(name, context) {
52
+ const dirs = ["interfaces", "contracts/interfaces", "src/interfaces"];
53
+ for (const file of context.getAllFiles()) {
54
+ if (!file.endsWith(".sol")) continue;
55
+ if (dirs.some((d) => file.includes(`/${d}/`))) {
56
+ const node = context.getNodesInFile(file).find((n) => n.name === name && n.kind === "interface");
57
+ if (node) return node.id;
58
+ }
59
+ }
60
+ for (const file of context.getAllFiles()) {
61
+ if (!file.endsWith(".sol")) continue;
62
+ const node = context.getNodesInFile(file).find((n) => n.name === name && n.kind === "interface");
63
+ if (node) return node.id;
64
+ }
65
+ return null;
66
+ }
67
+ function resolveContract(name, context) {
68
+ const dirs = ["contracts", "src", "lib"];
69
+ for (const file of context.getAllFiles()) {
70
+ if (!file.endsWith(".sol")) continue;
71
+ if (dirs.some((d) => file.includes(`/${d}/`))) {
72
+ const node = context.getNodesInFile(file).find((n) => n.name === name && n.kind === "class");
73
+ if (node) return node.id;
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+ function resolveLibraryFunction(name, context) {
79
+ const dirs = ["libraries", "contracts/libraries", "lib"];
80
+ for (const file of context.getAllFiles()) {
81
+ if (!file.endsWith(".sol")) continue;
82
+ if (dirs.some((d) => file.includes(`/${d}/`))) {
83
+ const node = context.getNodesInFile(file).find((n) => n.name === name && n.kind === "function");
84
+ if (node) return node.id;
85
+ }
86
+ }
87
+ return null;
88
+ }
89
+ // Annotate the CommonJS export names for ESM import in node:
90
+ 0 && (module.exports = {
91
+ solidityResolver
92
+ });
93
+ //# sourceMappingURL=solidity.js.map