codebase-digest-ai 0.1.1__py3-none-any.whl

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.
@@ -0,0 +1,81 @@
1
+ """Core data models for codebase analysis."""
2
+
3
+ from dataclasses import dataclass, field
4
+ from typing import Dict, List, Optional, Set
5
+ from pathlib import Path
6
+
7
+
8
+ @dataclass
9
+ class Symbol:
10
+ """Represents a code symbol (function, class, method, etc.)."""
11
+ name: str
12
+ type: str # 'function', 'class', 'method', 'variable'
13
+ file_path: Path
14
+ line_number: int
15
+ docstring: Optional[str] = None
16
+ parameters: List[str] = field(default_factory=list)
17
+ return_type: Optional[str] = None
18
+ decorators: List[str] = field(default_factory=list)
19
+
20
+
21
+ @dataclass
22
+ class Import:
23
+ """Represents an import statement."""
24
+ module: str
25
+ names: List[str]
26
+ alias: Optional[str] = None
27
+ file_path: Optional[Path] = None
28
+ line_number: Optional[int] = None
29
+
30
+
31
+ @dataclass
32
+ class CallRelation:
33
+ """Represents a function/method call relationship."""
34
+ caller_symbol: Symbol
35
+ callee_name: str
36
+ line_number: Optional[int] = None
37
+ callee_file: Optional[Path] = None # For cross-file calls
38
+
39
+
40
+ @dataclass
41
+ class DomainEntity:
42
+ """Represents a domain entity (business object)."""
43
+ name: str
44
+ type: str # 'class', 'dataclass', 'pydantic_model', etc.
45
+ file_path: Path
46
+ fields: List[str] = field(default_factory=list)
47
+ methods: List[str] = field(default_factory=list)
48
+ creation_points: List[str] = field(default_factory=list)
49
+ modification_points: List[str] = field(default_factory=list)
50
+ validation_points: List[str] = field(default_factory=list)
51
+
52
+
53
+ @dataclass
54
+ class ExecutionFlow:
55
+ """Represents an execution flow through the system."""
56
+ name: str
57
+ entry_point: str
58
+ steps: List[str] = field(default_factory=list)
59
+ files_involved: Set[Path] = field(default_factory=set)
60
+ description: Optional[str] = None
61
+
62
+
63
+ @dataclass
64
+ class CodebaseAnalysis:
65
+ """Complete analysis results for a codebase."""
66
+ root_path: Path
67
+ symbols: List[Symbol] = field(default_factory=list)
68
+ imports: List[Import] = field(default_factory=list)
69
+ call_relations: List[CallRelation] = field(default_factory=list)
70
+ domain_entities: List[DomainEntity] = field(default_factory=list)
71
+ execution_flows: List[ExecutionFlow] = field(default_factory=list)
72
+ entry_points: List[Path] = field(default_factory=list)
73
+
74
+ # Metrics
75
+ total_files: int = 0
76
+ total_lines: int = 0
77
+ languages: Set[str] = field(default_factory=set)
78
+ complexity_score: float = 0.0
79
+
80
+ # Directory structure
81
+ directory_tree: Dict = field(default_factory=dict)
@@ -0,0 +1,7 @@
1
+ """Parser modules for different programming languages."""
2
+
3
+ from .base import BaseParser
4
+ from .python_parser import PythonParser
5
+ from .javascript_parser import JavaScriptParser
6
+
7
+ __all__ = ["BaseParser", "PythonParser", "JavaScriptParser"]
@@ -0,0 +1,41 @@
1
+ """Base parser interface."""
2
+
3
+ from abc import ABC, abstractmethod
4
+ from pathlib import Path
5
+ from typing import List
6
+
7
+ from ..models import Symbol, Import, CallRelation, DomainEntity
8
+
9
+
10
+ class BaseParser(ABC):
11
+ """Abstract base class for language-specific parsers."""
12
+
13
+ def __init__(self, file_path: Path):
14
+ self.file_path = file_path
15
+ self.content = file_path.read_text(encoding='utf-8')
16
+
17
+ @abstractmethod
18
+ def parse_symbols(self) -> List[Symbol]:
19
+ """Extract symbols (functions, classes, methods) from the file."""
20
+ pass
21
+
22
+ @abstractmethod
23
+ def parse_imports(self) -> List[Import]:
24
+ """Extract import statements from the file."""
25
+ pass
26
+
27
+ @abstractmethod
28
+ def parse_calls(self) -> List[CallRelation]:
29
+ """Extract function/method calls from the file."""
30
+ pass
31
+
32
+ @abstractmethod
33
+ def parse_domain_entities(self) -> List[DomainEntity]:
34
+ """Extract domain entities (business objects) from the file."""
35
+ pass
36
+
37
+ @property
38
+ @abstractmethod
39
+ def supported_extensions(self) -> List[str]:
40
+ """Return list of file extensions this parser supports."""
41
+ pass
@@ -0,0 +1,36 @@
1
+ """JavaScript/TypeScript parser using tree-sitter."""
2
+
3
+ from pathlib import Path
4
+ from typing import List
5
+
6
+ from .base import BaseParser
7
+ from ..models import Symbol, Import, CallRelation, DomainEntity
8
+
9
+
10
+ class JavaScriptParser(BaseParser):
11
+ """Parser for JavaScript/TypeScript files using tree-sitter."""
12
+
13
+ @property
14
+ def supported_extensions(self) -> List[str]:
15
+ return ['.js', '.jsx', '.ts', '.tsx']
16
+
17
+ def parse_symbols(self) -> List[Symbol]:
18
+ """Extract JavaScript/TypeScript symbols."""
19
+ # TODO: Implement tree-sitter parsing
20
+ # For now, return empty list as placeholder
21
+ return []
22
+
23
+ def parse_imports(self) -> List[Import]:
24
+ """Extract import statements."""
25
+ # TODO: Implement tree-sitter parsing
26
+ return []
27
+
28
+ def parse_calls(self) -> List[CallRelation]:
29
+ """Extract function calls."""
30
+ # TODO: Implement tree-sitter parsing
31
+ return []
32
+
33
+ def parse_domain_entities(self) -> List[DomainEntity]:
34
+ """Extract domain entities."""
35
+ # TODO: Implement tree-sitter parsing
36
+ return []
@@ -0,0 +1,270 @@
1
+ """Python AST-based parser."""
2
+
3
+ import ast
4
+ from pathlib import Path
5
+ from typing import List, Optional
6
+
7
+ from .base import BaseParser
8
+ from ..models import Symbol, Import, CallRelation, DomainEntity
9
+
10
+
11
+ class PythonParser(BaseParser):
12
+ """Parser for Python files using AST."""
13
+
14
+ @property
15
+ def supported_extensions(self) -> List[str]:
16
+ return ['.py']
17
+
18
+ def parse_symbols(self) -> List[Symbol]:
19
+ """Extract Python symbols using AST."""
20
+ symbols = []
21
+ try:
22
+ tree = ast.parse(self.content)
23
+
24
+ for node in ast.walk(tree):
25
+ if isinstance(node, ast.FunctionDef):
26
+ symbols.append(self._create_function_symbol(node))
27
+ elif isinstance(node, ast.ClassDef):
28
+ symbols.append(self._create_class_symbol(node))
29
+ # Add methods
30
+ for item in node.body:
31
+ if isinstance(item, ast.FunctionDef):
32
+ symbols.append(self._create_method_symbol(item, node.name))
33
+
34
+ except SyntaxError:
35
+ # Skip files with syntax errors
36
+ pass
37
+
38
+ return symbols
39
+
40
+ def parse_imports(self) -> List[Import]:
41
+ """Extract import statements."""
42
+ imports = []
43
+ try:
44
+ tree = ast.parse(self.content)
45
+
46
+ for node in ast.walk(tree):
47
+ if isinstance(node, ast.Import):
48
+ for alias in node.names:
49
+ imports.append(Import(
50
+ module=alias.name,
51
+ names=[alias.name],
52
+ alias=alias.asname,
53
+ file_path=self.file_path,
54
+ line_number=node.lineno
55
+ ))
56
+ elif isinstance(node, ast.ImportFrom):
57
+ if node.module:
58
+ names = [alias.name for alias in node.names]
59
+ imports.append(Import(
60
+ module=node.module,
61
+ names=names,
62
+ file_path=self.file_path,
63
+ line_number=node.lineno
64
+ ))
65
+
66
+ except SyntaxError:
67
+ pass
68
+
69
+ return imports
70
+
71
+ def parse_calls(self) -> List[CallRelation]:
72
+ """Extract function calls with symbol context."""
73
+ calls = []
74
+ try:
75
+ tree = ast.parse(self.content)
76
+
77
+ # First pass: collect all symbols for context
78
+ symbols_by_name = {}
79
+ for node in ast.walk(tree):
80
+ if isinstance(node, ast.FunctionDef):
81
+ symbol = self._create_function_symbol(node)
82
+ symbols_by_name[node.name] = symbol
83
+ elif isinstance(node, ast.ClassDef):
84
+ class_symbol = self._create_class_symbol(node)
85
+ symbols_by_name[node.name] = class_symbol
86
+ # Add methods
87
+ for item in node.body:
88
+ if isinstance(item, ast.FunctionDef):
89
+ method_symbol = self._create_method_symbol(item, node.name)
90
+ symbols_by_name[f"{node.name}.{item.name}"] = method_symbol
91
+
92
+ # Second pass: extract calls with symbol context
93
+ for node in ast.walk(tree):
94
+ if isinstance(node, ast.FunctionDef):
95
+ caller_symbol = symbols_by_name.get(node.name)
96
+ if caller_symbol:
97
+ # Find calls within this function
98
+ for child in ast.walk(node):
99
+ if isinstance(child, ast.Call):
100
+ callee_name = self._extract_call_name(child)
101
+ if callee_name:
102
+ calls.append(CallRelation(
103
+ caller_symbol=caller_symbol,
104
+ callee_name=callee_name,
105
+ line_number=child.lineno
106
+ ))
107
+
108
+ elif isinstance(node, ast.ClassDef):
109
+ # Handle method calls
110
+ for item in node.body:
111
+ if isinstance(item, ast.FunctionDef):
112
+ method_key = f"{node.name}.{item.name}"
113
+ caller_symbol = symbols_by_name.get(method_key)
114
+ if caller_symbol:
115
+ # Find calls within this method
116
+ for child in ast.walk(item):
117
+ if isinstance(child, ast.Call):
118
+ callee_name = self._extract_call_name(child)
119
+ if callee_name:
120
+ calls.append(CallRelation(
121
+ caller_symbol=caller_symbol,
122
+ callee_name=callee_name,
123
+ line_number=child.lineno
124
+ ))
125
+
126
+ except SyntaxError:
127
+ pass
128
+
129
+ return calls
130
+
131
+ def _extract_call_name(self, call_node: ast.Call) -> Optional[str]:
132
+ """Extract the called function/method name from a Call node."""
133
+ if isinstance(call_node.func, ast.Name):
134
+ call_name = call_node.func.id
135
+ # Filter out builtin functions
136
+ if call_name in {'print', 'len', 'str', 'int', 'float', 'bool', 'list', 'dict', 'set', 'tuple', 'range', 'enumerate', 'zip', 'map', 'filter', 'sorted', 'reversed', 'sum', 'min', 'max', 'abs', 'round', 'type', 'isinstance', 'hasattr', 'getattr', 'setattr', 'delattr'}:
137
+ return None
138
+ return call_name
139
+ elif isinstance(call_node.func, ast.Attribute):
140
+ attr_name = self._get_attribute_name_from_node(call_node.func)
141
+ # Filter out common builtin method patterns
142
+ if attr_name and any(pattern in attr_name.lower() for pattern in ['append', 'extend', 'pop', 'remove', 'insert', 'sort', 'reverse', 'datetime.now', 'time.time']):
143
+ return None
144
+ return attr_name
145
+ return None
146
+
147
+ def parse_domain_entities(self) -> List[DomainEntity]:
148
+ """Extract domain entities (classes that represent business objects)."""
149
+ entities = []
150
+ try:
151
+ tree = ast.parse(self.content)
152
+
153
+ for node in ast.walk(tree):
154
+ if isinstance(node, ast.ClassDef):
155
+ # Look for common domain entity patterns
156
+ if self._is_domain_entity(node):
157
+ entity = DomainEntity(
158
+ name=node.name,
159
+ type='class',
160
+ file_path=self.file_path,
161
+ fields=self._extract_class_fields(node),
162
+ methods=self._extract_class_methods(node)
163
+ )
164
+ entities.append(entity)
165
+
166
+ except SyntaxError:
167
+ pass
168
+
169
+ return entities
170
+
171
+ def _create_function_symbol(self, node: ast.FunctionDef) -> Symbol:
172
+ """Create a Symbol from a function AST node."""
173
+ return Symbol(
174
+ name=node.name,
175
+ type='function',
176
+ file_path=self.file_path,
177
+ line_number=node.lineno,
178
+ docstring=ast.get_docstring(node),
179
+ parameters=[arg.arg for arg in node.args.args],
180
+ decorators=[self._get_decorator_name(dec) for dec in node.decorator_list]
181
+ )
182
+
183
+ def _create_class_symbol(self, node: ast.ClassDef) -> Symbol:
184
+ """Create a Symbol from a class AST node."""
185
+ return Symbol(
186
+ name=node.name,
187
+ type='class',
188
+ file_path=self.file_path,
189
+ line_number=node.lineno,
190
+ docstring=ast.get_docstring(node),
191
+ decorators=[self._get_decorator_name(dec) for dec in node.decorator_list]
192
+ )
193
+
194
+ def _create_method_symbol(self, node: ast.FunctionDef, class_name: str) -> Symbol:
195
+ """Create a Symbol from a method AST node."""
196
+ return Symbol(
197
+ name=f"{class_name}.{node.name}",
198
+ type='method',
199
+ file_path=self.file_path,
200
+ line_number=node.lineno,
201
+ docstring=ast.get_docstring(node),
202
+ parameters=[arg.arg for arg in node.args.args],
203
+ decorators=[self._get_decorator_name(dec) for dec in node.decorator_list]
204
+ )
205
+
206
+ def _get_decorator_name(self, decorator) -> str:
207
+ """Extract decorator name from AST node."""
208
+ if isinstance(decorator, ast.Name):
209
+ return decorator.id
210
+ elif isinstance(decorator, ast.Attribute):
211
+ return self._get_attribute_name_from_node(decorator) or ""
212
+ return ""
213
+
214
+ def _get_attribute_name_from_node(self, node: ast.Attribute) -> Optional[str]:
215
+ """Get full attribute name (e.g., 'obj.method') from AST node."""
216
+ if isinstance(node.value, ast.Name):
217
+ return f"{node.value.id}.{node.attr}"
218
+ elif isinstance(node.value, ast.Attribute):
219
+ base = self._get_attribute_name_from_node(node.value)
220
+ return f"{base}.{node.attr}" if base else None
221
+ return None
222
+
223
+ def _is_domain_entity(self, node: ast.ClassDef) -> bool:
224
+ """Determine if a class represents a domain entity."""
225
+ # Simple heuristics for domain entities
226
+ class_name = node.name.lower()
227
+
228
+ # Common domain entity names
229
+ domain_keywords = [
230
+ 'user', 'account', 'profile', 'customer', 'client',
231
+ 'order', 'payment', 'transaction', 'invoice', 'billing',
232
+ 'product', 'item', 'catalog', 'inventory',
233
+ 'wallet', 'balance', 'credit', 'debit',
234
+ 'session', 'token', 'auth', 'permission',
235
+ 'notification', 'message', 'email', 'sms',
236
+ 'address', 'location', 'contact', 'phone'
237
+ ]
238
+
239
+ # Check if class name contains domain keywords
240
+ for keyword in domain_keywords:
241
+ if keyword in class_name:
242
+ return True
243
+
244
+ # Check for dataclass or pydantic model decorators
245
+ for decorator in node.decorator_list:
246
+ if isinstance(decorator, ast.Name):
247
+ if decorator.id in ['dataclass', 'BaseModel']:
248
+ return True
249
+
250
+ return False
251
+
252
+ def _extract_class_fields(self, node: ast.ClassDef) -> List[str]:
253
+ """Extract field names from a class."""
254
+ fields = []
255
+ for item in node.body:
256
+ if isinstance(item, ast.AnnAssign) and isinstance(item.target, ast.Name):
257
+ fields.append(item.target.id)
258
+ elif isinstance(item, ast.Assign):
259
+ for target in item.targets:
260
+ if isinstance(target, ast.Name):
261
+ fields.append(target.id)
262
+ return fields
263
+
264
+ def _extract_class_methods(self, node: ast.ClassDef) -> List[str]:
265
+ """Extract method names from a class."""
266
+ methods = []
267
+ for item in node.body:
268
+ if isinstance(item, ast.FunctionDef):
269
+ methods.append(item.name)
270
+ return methods
@@ -0,0 +1,233 @@
1
+ Metadata-Version: 2.4
2
+ Name: codebase-digest-ai
3
+ Version: 0.1.1
4
+ Summary: AI-native code intelligence engine for semantic codebase analysis
5
+ Author: Harsh Bothara
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/codebase-digest/codebase-digest
8
+ Project-URL: Documentation, https://github.com/codebase-digest/codebase-digest#readme
9
+ Project-URL: Repository, https://github.com/codebase-digest/codebase-digest
10
+ Project-URL: Issues, https://github.com/codebase-digest/codebase-digest/issues
11
+ Keywords: code-analysis,ast,static-analysis,documentation,ai,developer-tools
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Documentation
20
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
+ Classifier: Topic :: Software Development :: Quality Assurance
22
+ Requires-Python: >=3.10
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: typer>=0.9.0
26
+ Requires-Dist: networkx>=3.0
27
+ Requires-Dist: rich>=13.0.0
28
+ Requires-Dist: jinja2>=3.1.0
29
+ Requires-Dist: pathspec>=0.11.0
30
+ Requires-Dist: pyvis>=0.3.2
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7.0.0; extra == "dev"
33
+ Requires-Dist: black>=23.0.0; extra == "dev"
34
+ Requires-Dist: isort>=5.12.0; extra == "dev"
35
+ Requires-Dist: mypy>=1.0.0; extra == "dev"
36
+ Requires-Dist: build>=0.10.0; extra == "dev"
37
+ Requires-Dist: twine>=4.0.0; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # codebase-digest
41
+
42
+ πŸš€ **AI-Native Code Intelligence Engine**
43
+
44
+ Transform any codebase into semantic architectural understanding, execution flows, and human-readable engineering reports.
45
+
46
+ ## 🧱 What It Does
47
+
48
+ This is NOT a repo summarizer. This is a code intelligence engine that explains:
49
+ - **What this system does** - Infers project purpose from domain entities
50
+ - **How data flows** - Maps execution paths and call relationships
51
+ - **Where logic lives** - Identifies core components and their responsibilities
52
+ - **What domains exist** - Detects business entities (User, Payment, Wallet, etc.)
53
+ - **What files matter** - Highlights entry points and key modules
54
+
55
+ ## ✨ Features
56
+
57
+ - **πŸ” Semantic Analysis**: Extract functions, classes, methods, and imports with full context
58
+ - **πŸ“Š Interactive Call Graphs**: Visualize function relationships and execution flows
59
+ - **πŸ—οΈ Domain Entity Detection**: Automatically identify core business objects
60
+ - **πŸ”„ Execution Flow Mapping**: Trace request paths through the system
61
+ - **πŸ“‹ Project README Generation**: Auto-generate documentation for new developers
62
+ - **πŸ“ˆ Multi-format Output**: HTML dashboards + Markdown reports + JSON data + Interactive graphs
63
+
64
+ ## πŸš€ Quick Start
65
+
66
+ ```bash
67
+ # Install
68
+ pip install codebase-digest
69
+
70
+ # Analyze current directory
71
+ codebase-digest build
72
+
73
+ # Analyze specific directory
74
+ codebase-digest build /path/to/project
75
+
76
+ # Generate with interactive call graph
77
+ codebase-digest build --graph
78
+
79
+ # Quick stats
80
+ codebase-digest stats
81
+
82
+ # Search for patterns
83
+ codebase-digest query "wallet"
84
+ ```
85
+
86
+ ## πŸ“ Output Structure
87
+
88
+ Generates `.digest/` directory with comprehensive analysis:
89
+ ```
90
+ .digest/
91
+ β”œβ”€β”€ README.md # Project documentation for developers
92
+ β”œβ”€β”€ callgraph.html # Interactive call graph visualization
93
+ β”œβ”€β”€ report.html # Comprehensive HTML dashboard
94
+ β”œβ”€β”€ architecture.md # Technical architecture breakdown
95
+ β”œβ”€β”€ flows.md # Execution flow documentation
96
+ β”œβ”€β”€ ai-context.md # AI-optimized context file
97
+ └── entities.json # Structured analysis data
98
+ ```
99
+
100
+ ## πŸ“Š Example Output
101
+
102
+ For a Python financial services project:
103
+
104
+ ```
105
+ πŸ“Š Codebase Statistics
106
+ ┏━━━━━━━━━━━━━━━━━━┳━━━━━━━━┓
107
+ ┃ Total Files ┃ 4 ┃
108
+ ┃ Lines of Code ┃ 189 ┃
109
+ ┃ Languages ┃ Python ┃
110
+ ┃ Functions ┃ 24 ┃
111
+ ┃ Classes ┃ 8 ┃
112
+ ┃ Domain Entities ┃ 7 ┃
113
+ ┃ Execution Flows ┃ 4 ┃
114
+ ┃ Complexity Score ┃ 1.8 ┃
115
+ ┗━━━━━━━━━━━━━━━━━━┻━━━━━━━━┛
116
+
117
+ Graph Stats: 29 nodes, 27 edges, 7 components
118
+ ```
119
+
120
+ **Generated README.md excerpt:**
121
+ ```markdown
122
+ # Project Overview
123
+
124
+ This is a financial services application that provides user management,
125
+ payment processing, and digital wallet functionality. The system is built
126
+ with a service-oriented architecture using Python dataclasses for domain
127
+ modeling and separate service layers for business logic.
128
+
129
+ ## Architecture
130
+
131
+ The application follows a layered architecture with clear separation of concerns:
132
+ - **Domain Layer**: Contains core business entities (User, Payment, Wallet)
133
+ - **Service Layer**: Implements business logic (UserService, PaymentService)
134
+ - **Application Layer**: Handles bootstrapping and orchestration
135
+ ```
136
+
137
+ ## πŸ’‘ Commands
138
+
139
+ ```bash
140
+ # Full analysis with all outputs
141
+ codebase-digest build [PATH]
142
+
143
+ # Specific formats
144
+ codebase-digest build --format html # HTML dashboard only
145
+ codebase-digest build --format markdown # Markdown reports only
146
+ codebase-digest build --format json # JSON data only
147
+
148
+ # Interactive call graph with depth filtering
149
+ codebase-digest build --graph --graph-depth 3
150
+
151
+ # Quick metrics and search
152
+ codebase-digest stats [PATH] # Project statistics
153
+ codebase-digest query "search term" [PATH] # Search patterns
154
+ ```
155
+
156
+ ## 🎯 Key Features
157
+
158
+ ### πŸ•ΈοΈ Interactive Call Graph
159
+ - **Probabilistic entrypoint detection** - Finds real execution starting points
160
+ - **Noise filtering** - Removes builtin calls and isolated nodes
161
+ - **Depth filtering** - Focus on core execution spine
162
+ - **Professional UI** - GitHub/Linear/Notion inspired design
163
+
164
+ ### πŸ“ Smart README Generation
165
+ - **Project type inference** - Detects financial, e-commerce, CMS patterns
166
+ - **Architecture analysis** - Service-oriented vs modular detection
167
+ - **Run instructions** - Inferred from entry points
168
+ - **Future improvements** - Realistic enhancement suggestions
169
+
170
+ ### πŸ” Semantic Understanding
171
+ - **Symbol-aware analysis** - True function-level relationships
172
+ - **Domain entity detection** - Business object identification
173
+ - **Execution flow mapping** - Startup and runtime sequences
174
+ - **Cross-file analysis** - Import and dependency tracking
175
+
176
+ ## πŸ› οΈ Tech Stack
177
+
178
+ - **Python 3.10+** - Core language
179
+ - **AST parsing** - Deep Python code analysis
180
+ - **NetworkX** - Call graph analysis and visualization
181
+ - **vis.js** - Interactive graph rendering
182
+ - **Typer** - CLI interface
183
+ - **Rich** - Beautiful terminal output
184
+
185
+ ## πŸ“‹ Supported Languages
186
+
187
+ - βœ… **Python** - Full AST analysis with call graphs
188
+ - 🚧 **JavaScript/TypeScript** - Parser implemented, integration in progress
189
+ - 🚧 **Java** - Planned
190
+ - 🚧 **Go** - Planned
191
+
192
+ ## 🎯 Use Cases
193
+
194
+ - **New Developer Onboarding** - Understand unfamiliar codebases quickly
195
+ - **Code Reviews** - Architectural overview and impact analysis
196
+ - **Documentation Generation** - Auto-generate project documentation
197
+ - **Refactoring Planning** - Identify core components and dependencies
198
+ - **AI-Assisted Development** - Provide context for LLM code assistance
199
+
200
+ ## πŸ”§ Development
201
+
202
+ ```bash
203
+ # Install development dependencies
204
+ pip install -e ".[dev]"
205
+
206
+ # Run tests
207
+ pytest
208
+
209
+ # Format code
210
+ black .
211
+ isort .
212
+
213
+ # Type checking
214
+ mypy codebase_digest/
215
+ ```
216
+
217
+ ## 🀝 Contributing
218
+
219
+ 1. Fork the repository
220
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
221
+ 3. Make your changes
222
+ 4. Add tests if applicable
223
+ 5. Submit a pull request
224
+
225
+ ## πŸ“„ License
226
+
227
+ MIT License - see LICENSE file for details.
228
+
229
+ ## πŸ™ Acknowledgments
230
+
231
+ - Built with modern Python tooling and best practices
232
+ - Inspired by professional developer tools (JetBrains, Sourcegraph)
233
+ - Designed for AI-native development workflows