How Language and Framework Registries Provide Context for Code Analysis in Egonex-AI

The LanguageRegistry and FrameworkRegistry classes in Egonex-AI map file paths to language configurations and detect project frameworks by scanning manifest files, enabling the analyzer pipeline to select the correct parser and apply framework-specific rules.

Accurate code analysis in the Egonex-AI/Understand-Anything repository depends on identifying both the programming language of each file and the frameworks used by the project. The language and framework registries provide this contextual foundation by maintaining lookup maps that connect file metadata to appropriate analysis configurations. These registries enable the system to route files to specialized parsers and enrich the knowledge graph with framework-specific insights.

LanguageRegistry: Mapping File Paths to Language Configurations

The LanguageRegistry class in understand-anything-plugin/packages/core/src/languages/language-registry.ts serves as the primary source for determining which language parser should handle a specific file. It maintains three internal lookup maps: byId, byExtension, and byFilename.

Registration and Schema Validation

When register is called, the system validates the LanguageConfig object against LanguageConfigSchema before indexing. The configuration is stored in all three maps: by its unique identifier, by each associated file extension (normalized to include a leading dot), and by any special filenames such as Dockerfile or Makefile.

File Resolution Logic

The getForFile(filePath) method implements a priority-based lookup strategy. It first checks the byFilename map for exact filename matches, then falls back to the byExtension map based on the file extension. This ensures that files like Dockerfile match correctly even without an extension, while standard source files resolve based on their suffix.

Default Language Configurations

The static createDefault() method pre-populates the registry with all built-in language configurations stored in builtinLanguageConfigs. This ensures that common languages like TypeScript, Python, and Java are immediately available without manual registration.

FrameworkRegistry: Detecting Project Frameworks from Manifests

While the language registry identifies file types, the FrameworkRegistry in understand-anything-plugin/packages/core/src/languages/framework-registry.ts identifies the broader context of the project itself. It maintains byId and byLanguage maps linking framework configurations to the languages they support.

Framework Registration and Indexing

The register method validates each FrameworkConfig against FrameworkConfigSchema and prevents duplicate framework IDs. It indexes each framework under every language ID it supports, creating a relationship matrix that connects frameworks to their native languages.

Manifest Scanning and Keyword Detection

The detectFrameworks(manifests) method receives a map of manifest filenames to their content, such as package.json or requirements.txt. It iterates through registered framework configurations, checking if any manifest filename matches the framework's expected files. When found, it scans the content for detectionKeywords—specific strings that confirm framework presence, such as "react" inside a package.json dependencies block.

Connecting Registries to the Analyzer Pipeline

The PluginRegistry in understand-anything-plugin/packages/core/src/plugins/registry.ts bridges the language registry to the actual analysis logic. When processing a file, the plugin registry calls languageRegistry.getForFile(filePath) to determine the language ID, then routes the file to the appropriate analyzer plugin. This integration ensures that TypeScript files receive TypeScript-specific parsing, while Python files receive Python-specific analysis.

Framework detection feeds into higher-level agents such as the architecture analyzer, which uses framework identities to enrich the knowledge graph with framework-specific nodes and apply framework-aware validation rules.

Working Example: Using Registries in Practice

The following example demonstrates how to initialize the registries and use them to analyze a project:

import { LanguageRegistry } from "./languages/language-registry.js";
import { FrameworkRegistry } from "./languages/framework-registry.js";
import { PluginRegistry } from "./plugins/registry.js";

// 1️⃣ Build registries with default configurations
const langReg = LanguageRegistry.createDefault();
const fwReg   = FrameworkRegistry.createDefault();

// 2️⃣ Resolve language for a specific source file
const file = "src/app.tsx";
const langConfig = langReg.getForFile(file);
console.log(langConfig?.id); // → "typescript"

// 3️⃣ Select the appropriate analyzer plugin
const pluginReg = new PluginRegistry(langReg);
const plugin = pluginReg.getPluginForFile(file);
plugin?.analyzeFile(file, sourceCode);

// 4️⃣ Detect frameworks from project manifest files
const manifests = {
  "package.json": `{ "dependencies": { "react": "^18.0.0" } }`,
  "requirements.txt": "django==4.2\n"
};
const frameworks = fwReg.detectFrameworks(manifests);
console.log(frameworks.map(f => f.id)); // → ["react", "django"]

Summary

  • The LanguageRegistry uses three lookup maps (byId, byExtension, byFilename) to resolve file paths to language configurations, validating entries against LanguageConfigSchema.
  • The FrameworkRegistry detects project frameworks by scanning manifest files for detectionKeywords, maintaining relationships between frameworks and their supported languages.
  • The PluginRegistry consumes the LanguageRegistry to route files to the correct analyzer plugins, ensuring language-specific parsing.
  • Both registries provide createDefault() methods that preload built-in configurations for immediate use.

Frequently Asked Questions

How does LanguageRegistry determine the language for a file without an extension?

The getForFile(filePath) method first checks the byFilename map for exact matches against special filenames like Dockerfile or Makefile. If no filename match exists, it falls back to checking the file extension against the byExtension map. This dual-lookup strategy ensures accurate identification of both standard source files and configuration files lacking extensions.

What is the difference between LanguageRegistry and FrameworkRegistry?

The LanguageRegistry operates at the file level, mapping individual file paths to language configurations to determine which parser to use. The FrameworkRegistry operates at the project level, analyzing manifest files like package.json or requirements.txt to identify which frameworks the project uses, enabling higher-level architectural analysis and framework-specific rule application.

Can custom languages or frameworks be added to the registries?

Yes, both registries expose a register method that accepts configuration objects. For languages, pass a LanguageConfig validated against LanguageConfigSchema. For frameworks, pass a FrameworkConfig validated against FrameworkConfigSchema. The registries will index these custom entries alongside the built-in configurations loaded via createDefault().

How does the PluginRegistry use the LanguageRegistry?

The PluginRegistry receives a LanguageRegistry instance during initialization. When getPluginForFile(filePath) is called, it internally invokes languageRegistry.getForFile(filePath) to retrieve the language ID, then returns the appropriate analyzer plugin capable of parsing that specific language. This decouples file routing from language detection logic.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →