code2llm 0.5.46__tar.gz → 0.5.48__tar.gz
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.
- {code2llm-0.5.46 → code2llm-0.5.48}/PKG-INFO +6 -6
- {code2llm-0.5.46 → code2llm-0.5.48}/README.md +5 -5
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/__init__.py +1 -1
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/cli_exports/formats.py +1 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/context_exporter.py +24 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/html_dashboard.py +177 -24
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/readme_exporter.py +1 -1
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/toon/renderer.py +29 -1
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/toon_view.py +38 -6
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/nlp/__init__.py +1 -1
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm.egg-info/PKG-INFO +6 -6
- {code2llm-0.5.46 → code2llm-0.5.48}/pyproject.toml +1 -1
- {code2llm-0.5.46 → code2llm-0.5.48}/LICENSE +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/__main__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/analysis/__init__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/analysis/call_graph.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/analysis/cfg.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/analysis/coupling.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/analysis/data_analysis.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/analysis/dfg.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/analysis/pipeline_detector.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/analysis/side_effects.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/analysis/smells.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/analysis/type_inference.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/api.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/cli.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/cli_analysis.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/cli_exports/__init__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/cli_exports/code2logic.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/cli_exports/orchestrator.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/cli_exports/prompt.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/__init__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/analyzer.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/config.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/core/__init__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/core/file_analyzer.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/core/file_cache.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/core/file_filter.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/core/refactoring.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/large_repo.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/models.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/streaming/__init__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/streaming/cache.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/streaming/incremental.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/streaming/prioritizer.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/streaming/scanner.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/streaming/strategies.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/streaming_analyzer.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/core/toon_size_manager.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/__init__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/article_view.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/base.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/context_view.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/evolution_exporter.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/flow_constants.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/flow_exporter.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/flow_renderer.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/json_exporter.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/llm_exporter.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/map_exporter.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/mermaid_exporter.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/project_yaml_exporter.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/report_generators.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/toon/__init__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/toon/helpers.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/toon/metrics.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/toon/module_detail.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/toon.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/validate_project.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/exporters/yaml_exporter.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/generators/__init__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/generators/llm_flow.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/generators/llm_task.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/generators/mermaid.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/nlp/config.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/nlp/entity_resolution.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/nlp/intent_matching.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/nlp/normalization.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/nlp/pipeline.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/patterns/__init__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/patterns/detector.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/refactor/__init__.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm/refactor/prompt_engine.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm.egg-info/SOURCES.txt +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm.egg-info/dependency_links.txt +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm.egg-info/entry_points.txt +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm.egg-info/requires.txt +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/code2llm.egg-info/top_level.txt +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/setup.cfg +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/setup.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_advanced_analysis.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_analyzer.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_deep_analysis.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_edge_cases.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_flow_exporter.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_format_quality.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_multilanguage_e2e.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_nlp_pipeline.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_pipeline_detector.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_prompt_engine.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_prompt_txt.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_refactoring_engine.py +0 -0
- {code2llm-0.5.46 → code2llm-0.5.48}/tests/test_toon_v2.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code2llm
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.48
|
|
4
4
|
Summary: High-performance Python code flow analysis with optimized TOON format - CFG, DFG, call graphs, and intelligent code queries
|
|
5
5
|
Home-page: https://github.com/wronai/stts
|
|
6
6
|
Author: STTS Project
|
|
@@ -50,7 +50,7 @@ Dynamic: requires-python
|
|
|
50
50
|
|
|
51
51
|
# code2llm - Generated Analysis Files
|
|
52
52
|
|
|
53
|
-
This directory contains the complete analysis of your
|
|
53
|
+
This directory contains the complete analysis of your project generated by `code2llm`. Each file serves a specific purpose for understanding, refactoring, and documenting your codebase.
|
|
54
54
|
|
|
55
55
|
## 📁 Generated Files Overview
|
|
56
56
|
|
|
@@ -60,7 +60,7 @@ When you run `code2llm ./ -f all`, the following files are created:
|
|
|
60
60
|
|
|
61
61
|
| File | Format | Purpose | Key Insights |
|
|
62
62
|
|------|--------|---------|--------------|
|
|
63
|
-
| `analysis.toon` | **TOON** | **🔥 Health diagnostics** - Complexity, god modules, coupling |
|
|
63
|
+
| `analysis.toon` | **TOON** | **🔥 Health diagnostics** - Complexity, god modules, coupling | 59 critical functions, 0 god modules |
|
|
64
64
|
| `project.toon` | **TOON** | **🧠 Project logic** - Compact module view from code2logic | Generated via code2logic integration |
|
|
65
65
|
|
|
66
66
|
### 🤖 LLM-Ready Documentation
|
|
@@ -374,10 +374,10 @@ code2llm ./ -f yaml --separate-orphans
|
|
|
374
374
|
---
|
|
375
375
|
|
|
376
376
|
**Generated by**: `code2llm ./ -f all --readme`
|
|
377
|
-
**Analysis Date**: 2026-03-
|
|
378
|
-
**Total Functions**:
|
|
377
|
+
**Analysis Date**: 2026-03-09
|
|
378
|
+
**Total Functions**: 850
|
|
379
379
|
**Total Classes**: 104
|
|
380
|
-
**Modules**:
|
|
380
|
+
**Modules**: 105
|
|
381
381
|
|
|
382
382
|
For more information about code2llm, visit: https://github.com/tom-sapletta/code2llm
|
|
383
383
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# code2llm - Generated Analysis Files
|
|
2
2
|
|
|
3
|
-
This directory contains the complete analysis of your
|
|
3
|
+
This directory contains the complete analysis of your project generated by `code2llm`. Each file serves a specific purpose for understanding, refactoring, and documenting your codebase.
|
|
4
4
|
|
|
5
5
|
## 📁 Generated Files Overview
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ When you run `code2llm ./ -f all`, the following files are created:
|
|
|
10
10
|
|
|
11
11
|
| File | Format | Purpose | Key Insights |
|
|
12
12
|
|------|--------|---------|--------------|
|
|
13
|
-
| `analysis.toon` | **TOON** | **🔥 Health diagnostics** - Complexity, god modules, coupling |
|
|
13
|
+
| `analysis.toon` | **TOON** | **🔥 Health diagnostics** - Complexity, god modules, coupling | 59 critical functions, 0 god modules |
|
|
14
14
|
| `project.toon` | **TOON** | **🧠 Project logic** - Compact module view from code2logic | Generated via code2logic integration |
|
|
15
15
|
|
|
16
16
|
### 🤖 LLM-Ready Documentation
|
|
@@ -324,10 +324,10 @@ code2llm ./ -f yaml --separate-orphans
|
|
|
324
324
|
---
|
|
325
325
|
|
|
326
326
|
**Generated by**: `code2llm ./ -f all --readme`
|
|
327
|
-
**Analysis Date**: 2026-03-
|
|
328
|
-
**Total Functions**:
|
|
327
|
+
**Analysis Date**: 2026-03-09
|
|
328
|
+
**Total Functions**: 850
|
|
329
329
|
**Total Classes**: 104
|
|
330
|
-
**Modules**:
|
|
330
|
+
**Modules**: 105
|
|
331
331
|
|
|
332
332
|
For more information about code2llm, visit: https://github.com/tom-sapletta/code2llm
|
|
333
333
|
|
|
@@ -8,7 +8,7 @@ Includes NLP Processing Pipeline for query normalization, intent matching,
|
|
|
8
8
|
and entity resolution with multilingual support.
|
|
9
9
|
"""
|
|
10
10
|
|
|
11
|
-
__version__ = "0.5.
|
|
11
|
+
__version__ = "0.5.48"
|
|
12
12
|
__author__ = "STTS Project"
|
|
13
13
|
|
|
14
14
|
# Core analysis components (lightweight, always needed)
|
|
@@ -121,6 +121,7 @@ def _export_simple_formats(args, result, output_dir: Path, formats):
|
|
|
121
121
|
data = load_project_yaml(str(yaml_path))
|
|
122
122
|
view_map = {
|
|
123
123
|
'project.toon': ToonViewGenerator(),
|
|
124
|
+
'context.md': ContextViewGenerator(),
|
|
124
125
|
'dashboard.html': HTMLDashboardGenerator(),
|
|
125
126
|
}
|
|
126
127
|
for filename, generator in view_map.items():
|
|
@@ -4,10 +4,12 @@ Rename from llm_exporter.py → context_exporter.py (Sprint 4, v0.3.3).
|
|
|
4
4
|
Produces LLM-ready architecture summary with flows, patterns, and API surface.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
from collections import defaultdict
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
from typing import Any, Dict, List, Tuple
|
|
9
10
|
from .base import Exporter
|
|
10
11
|
from ..core.models import AnalysisResult, FunctionInfo
|
|
12
|
+
from ..core.config import LANGUAGE_EXTENSIONS
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
class ContextExporter(Exporter):
|
|
@@ -54,10 +56,15 @@ class ContextExporter(Exporter):
|
|
|
54
56
|
f.write('\n'.join(lines))
|
|
55
57
|
|
|
56
58
|
def _get_overview(self, result: AnalysisResult) -> List[str]:
|
|
59
|
+
lang_info = self._detect_languages(result)
|
|
60
|
+
primary = lang_info[0][0] if lang_info else 'unknown'
|
|
61
|
+
lang_summary = ', '.join(f'{l}: {c}' for l, c in lang_info[:5])
|
|
57
62
|
return [
|
|
58
63
|
"## Overview",
|
|
59
64
|
"",
|
|
60
65
|
f"- **Project**: {result.project_path}",
|
|
66
|
+
f"- **Primary Language**: {primary}",
|
|
67
|
+
f"- **Languages**: {lang_summary}",
|
|
61
68
|
f"- **Analysis Mode**: {result.analysis_mode}",
|
|
62
69
|
f"- **Total Functions**: {len(result.functions)}",
|
|
63
70
|
f"- **Total Classes**: {len(result.classes)}",
|
|
@@ -66,6 +73,23 @@ class ContextExporter(Exporter):
|
|
|
66
73
|
"",
|
|
67
74
|
]
|
|
68
75
|
|
|
76
|
+
@staticmethod
|
|
77
|
+
def _detect_languages(result: AnalysisResult) -> List[tuple]:
|
|
78
|
+
"""Detect languages from module file extensions."""
|
|
79
|
+
lang_counts: Dict[str, int] = defaultdict(int)
|
|
80
|
+
for mi in result.modules.values():
|
|
81
|
+
detected = False
|
|
82
|
+
for lang, extensions in LANGUAGE_EXTENSIONS.items():
|
|
83
|
+
if any(mi.file.endswith(ext) for ext in extensions):
|
|
84
|
+
lang_counts[lang] += 1
|
|
85
|
+
detected = True
|
|
86
|
+
break
|
|
87
|
+
if not detected:
|
|
88
|
+
ext = Path(mi.file).suffix.lower()
|
|
89
|
+
if ext:
|
|
90
|
+
lang_counts[ext.lstrip('.')] += 1
|
|
91
|
+
return sorted(lang_counts.items(), key=lambda x: -x[1])
|
|
92
|
+
|
|
69
93
|
def _get_architecture_by_module(self, result: AnalysisResult) -> List[str]:
|
|
70
94
|
lines = ["## Architecture by Module", ""]
|
|
71
95
|
module_stats = []
|
|
@@ -1,14 +1,38 @@
|
|
|
1
1
|
"""HTML Dashboard Generator — web visualization with trend charts.
|
|
2
2
|
|
|
3
3
|
Generates dashboard.html from project.yaml data.
|
|
4
|
-
Includes: metric cards,
|
|
5
|
-
|
|
4
|
+
Includes: metric cards, language breakdown, evolution chart,
|
|
5
|
+
module size/function charts, alerts, hotspots, refactoring priorities.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from collections import defaultdict
|
|
8
9
|
from datetime import datetime
|
|
9
10
|
from pathlib import Path
|
|
10
11
|
from typing import Any, Dict, List
|
|
11
12
|
|
|
13
|
+
# Language detection from file extensions
|
|
14
|
+
_LANG_EXT_MAP = {
|
|
15
|
+
'.py': 'Python', '.ts': 'TypeScript', '.tsx': 'TypeScript',
|
|
16
|
+
'.js': 'JavaScript', '.jsx': 'JavaScript', '.mjs': 'JavaScript', '.cjs': 'JavaScript',
|
|
17
|
+
'.go': 'Go', '.rs': 'Rust', '.java': 'Java',
|
|
18
|
+
'.cpp': 'C++', '.cc': 'C++', '.cxx': 'C++', '.hpp': 'C++', '.h': 'C/C++',
|
|
19
|
+
'.c': 'C', '.cs': 'C#', '.rb': 'Ruby', '.php': 'PHP',
|
|
20
|
+
'.swift': 'Swift', '.kt': 'Kotlin', '.kts': 'Kotlin',
|
|
21
|
+
'.scala': 'Scala', '.sh': 'Shell', '.bash': 'Shell', '.zsh': 'Shell',
|
|
22
|
+
'.dart': 'Dart', '.ex': 'Elixir', '.exs': 'Elixir',
|
|
23
|
+
'.hs': 'Haskell', '.lua': 'Lua', '.pl': 'Perl', '.r': 'R', '.R': 'R',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
_LANG_COLORS = {
|
|
27
|
+
'TypeScript': '#3178c6', 'JavaScript': '#f7df1e', 'Python': '#3572A5',
|
|
28
|
+
'Go': '#00ADD8', 'Rust': '#dea584', 'Java': '#b07219',
|
|
29
|
+
'C++': '#f34b7d', 'C': '#555555', 'C/C++': '#555555', 'C#': '#178600',
|
|
30
|
+
'Ruby': '#701516', 'PHP': '#4F5D95', 'Swift': '#F05138',
|
|
31
|
+
'Kotlin': '#A97BFF', 'Scala': '#c22d40', 'Shell': '#89e051',
|
|
32
|
+
'Dart': '#00B4AB', 'Elixir': '#6e4a7e', 'Haskell': '#5e5086',
|
|
33
|
+
'Lua': '#000080', 'Perl': '#0298c3', 'R': '#198CE7',
|
|
34
|
+
}
|
|
35
|
+
|
|
12
36
|
|
|
13
37
|
class HTMLDashboardGenerator:
|
|
14
38
|
"""Generate dashboard.html from project.yaml data."""
|
|
@@ -30,20 +54,25 @@ class HTMLDashboardGenerator:
|
|
|
30
54
|
|
|
31
55
|
health_color, health_label = self._health_verdict(health)
|
|
32
56
|
evo_chart = self._build_evolution_section(evolution)
|
|
33
|
-
|
|
57
|
+
lang_data = self._build_language_breakdown(modules)
|
|
58
|
+
mod_lines_chart = self._build_module_lines_chart(modules)
|
|
59
|
+
mod_funcs_chart = self._build_module_funcs_chart(modules)
|
|
34
60
|
alerts_html = self._build_alerts_html(health)
|
|
35
61
|
hotspots_html = self._build_hotspots_html(hotspots)
|
|
36
62
|
refactor_html = self._build_refactoring_html(refactoring)
|
|
63
|
+
top_modules_html = self._build_top_modules_html(modules)
|
|
37
64
|
|
|
38
65
|
cc_avg = health.get("cc_avg", 0)
|
|
39
66
|
|
|
40
67
|
return self._assemble_html(
|
|
41
68
|
proj=proj, stats=stats, health=health,
|
|
42
69
|
cc_avg=cc_avg, health_color=health_color, health_label=health_label,
|
|
43
|
-
evo_chart=evo_chart,
|
|
70
|
+
evo_chart=evo_chart, lang_data=lang_data,
|
|
71
|
+
mod_lines_chart=mod_lines_chart, mod_funcs_chart=mod_funcs_chart,
|
|
44
72
|
alerts_html=alerts_html, hotspots_html=hotspots_html,
|
|
45
73
|
hotspots=hotspots, refactor_html=refactor_html,
|
|
46
|
-
refactoring=refactoring,
|
|
74
|
+
refactoring=refactoring, top_modules_html=top_modules_html,
|
|
75
|
+
modules=modules,
|
|
47
76
|
)
|
|
48
77
|
|
|
49
78
|
# ------------------------------------------------------------------
|
|
@@ -71,13 +100,66 @@ class HTMLDashboardGenerator:
|
|
|
71
100
|
}
|
|
72
101
|
|
|
73
102
|
@staticmethod
|
|
74
|
-
def
|
|
75
|
-
|
|
103
|
+
def _build_language_breakdown(modules: List[Dict]) -> Dict[str, Any]:
|
|
104
|
+
"""Detect languages from module paths and build pie chart data."""
|
|
105
|
+
lang_files: Dict[str, int] = defaultdict(int)
|
|
106
|
+
lang_lines: Dict[str, int] = defaultdict(int)
|
|
107
|
+
for m in modules:
|
|
108
|
+
ext = Path(m.get("path", "")).suffix.lower()
|
|
109
|
+
lang = _LANG_EXT_MAP.get(ext, ext.lstrip('.').capitalize() if ext else "Other")
|
|
110
|
+
lang_files[lang] += 1
|
|
111
|
+
lang_lines[lang] += m.get("lines", 0)
|
|
112
|
+
|
|
113
|
+
sorted_langs = sorted(lang_files.items(), key=lambda x: -x[1])
|
|
114
|
+
names = [l[0] for l in sorted_langs]
|
|
115
|
+
files = [l[1] for l in sorted_langs]
|
|
116
|
+
lines = [lang_lines[l[0]] for l in sorted_langs]
|
|
117
|
+
colors = [_LANG_COLORS.get(n, '#6b7280') for n in names]
|
|
118
|
+
return {"names": names, "files": files, "lines": lines, "colors": colors}
|
|
119
|
+
|
|
120
|
+
@staticmethod
|
|
121
|
+
def _build_module_lines_chart(modules: List[Dict]) -> Dict[str, Any]:
|
|
122
|
+
"""Top 15 modules by line count."""
|
|
123
|
+
top = sorted(modules, key=lambda m: m.get("lines", 0), reverse=True)[:15]
|
|
124
|
+
return {
|
|
125
|
+
"names": [Path(m.get("path", "")).name for m in top],
|
|
126
|
+
"lines": [m.get("lines", 0) for m in top],
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
@staticmethod
|
|
130
|
+
def _build_module_funcs_chart(modules: List[Dict]) -> Dict[str, Any]:
|
|
131
|
+
"""Top 15 modules by function/method count."""
|
|
132
|
+
top = sorted(modules, key=lambda m: m.get("methods", 0), reverse=True)[:15]
|
|
76
133
|
return {
|
|
77
134
|
"names": [Path(m.get("path", "")).name for m in top],
|
|
78
|
-
"
|
|
135
|
+
"funcs": [m.get("methods", 0) for m in top],
|
|
79
136
|
}
|
|
80
137
|
|
|
138
|
+
@staticmethod
|
|
139
|
+
def _build_top_modules_html(modules: List[Dict]) -> str:
|
|
140
|
+
"""Build top modules table sorted by lines."""
|
|
141
|
+
top = sorted(modules, key=lambda m: m.get("lines", 0), reverse=True)[:20]
|
|
142
|
+
html = ""
|
|
143
|
+
for m in top:
|
|
144
|
+
path = m.get("path", "?")
|
|
145
|
+
lines = m.get("lines", 0)
|
|
146
|
+
methods = m.get("methods", 0)
|
|
147
|
+
classes = m.get("classes", 0)
|
|
148
|
+
cc_max = m.get("cc_max", 0)
|
|
149
|
+
ext = Path(path).suffix.lower()
|
|
150
|
+
lang = _LANG_EXT_MAP.get(ext, ext.lstrip('.'))
|
|
151
|
+
color = _LANG_COLORS.get(lang, '#6b7280')
|
|
152
|
+
html += f"""
|
|
153
|
+
<tr>
|
|
154
|
+
<td><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:{color};margin-right:6px"></span>{Path(path).name}</td>
|
|
155
|
+
<td style="color:var(--muted);font-size:.75rem">{'/'.join(Path(path).parts[:-1]) or '.'}</td>
|
|
156
|
+
<td style="text-align:right">{lines:,}</td>
|
|
157
|
+
<td style="text-align:right">{methods}</td>
|
|
158
|
+
<td style="text-align:right">{classes}</td>
|
|
159
|
+
<td style="text-align:right">{cc_max}</td>
|
|
160
|
+
</tr>"""
|
|
161
|
+
return html
|
|
162
|
+
|
|
81
163
|
@staticmethod
|
|
82
164
|
def _build_alerts_html(health: Dict) -> str:
|
|
83
165
|
html = ""
|
|
@@ -109,7 +191,7 @@ class HTMLDashboardGenerator:
|
|
|
109
191
|
@staticmethod
|
|
110
192
|
def _build_refactoring_html(refactoring: Dict) -> str:
|
|
111
193
|
html = ""
|
|
112
|
-
for i, p in enumerate(refactoring.get("priorities", [])[:
|
|
194
|
+
for i, p in enumerate(refactoring.get("priorities", [])[:15], 1):
|
|
113
195
|
impact_class = p.get("impact", "low")
|
|
114
196
|
html += f"""
|
|
115
197
|
<tr>
|
|
@@ -131,15 +213,20 @@ class HTMLDashboardGenerator:
|
|
|
131
213
|
health_color = ctx["health_color"]
|
|
132
214
|
health_label = ctx["health_label"]
|
|
133
215
|
evo = ctx["evo_chart"]
|
|
134
|
-
|
|
216
|
+
lang = ctx["lang_data"]
|
|
217
|
+
mod_lines = ctx["mod_lines_chart"]
|
|
218
|
+
mod_funcs = ctx["mod_funcs_chart"]
|
|
135
219
|
alerts_html = ctx["alerts_html"]
|
|
136
220
|
hotspots_html = ctx["hotspots_html"]
|
|
137
221
|
hotspots = ctx["hotspots"]
|
|
138
222
|
refactor_html = ctx["refactor_html"]
|
|
139
223
|
refactoring = ctx["refactoring"]
|
|
224
|
+
top_modules_html = ctx["top_modules_html"]
|
|
225
|
+
modules = ctx["modules"]
|
|
140
226
|
|
|
141
227
|
evo_section = self._render_evolution_section(evo)
|
|
142
228
|
evo_script = self._render_evolution_script(evo)
|
|
229
|
+
lang_summary = ', '.join(f'{n}: {c}' for n, c in zip(lang['names'], lang['files']))
|
|
143
230
|
|
|
144
231
|
return f"""<!DOCTYPE html>
|
|
145
232
|
<html lang="en">
|
|
@@ -165,7 +252,7 @@ class HTMLDashboardGenerator:
|
|
|
165
252
|
body {{ font-family: 'Segoe UI',system-ui,sans-serif; background:var(--bg); color:var(--text); padding:2rem; }}
|
|
166
253
|
h1 {{ font-size:1.5rem; margin-bottom:.5rem; }}
|
|
167
254
|
h2 {{ font-size:1.1rem; color:var(--muted); margin:1.5rem 0 .75rem; border-bottom:1px solid var(--border); padding-bottom:.25rem; }}
|
|
168
|
-
.grid {{ display:grid; grid-template-columns:repeat(auto-fit,minmax(
|
|
255
|
+
.grid {{ display:grid; grid-template-columns:repeat(auto-fit,minmax(160px,1fr)); gap:1rem; margin:1rem 0; }}
|
|
169
256
|
.card {{ background:var(--surface); border:1px solid var(--border); border-radius:.5rem; padding:1rem; }}
|
|
170
257
|
.card .value {{ font-size:1.8rem; font-weight:700; }}
|
|
171
258
|
.card .label {{ color:var(--muted); font-size:.8rem; text-transform:uppercase; }}
|
|
@@ -186,10 +273,12 @@ class HTMLDashboardGenerator:
|
|
|
186
273
|
tr.warning td {{ background:rgba(234,179,8,.05); }}
|
|
187
274
|
.health-indicator {{ display:inline-block; width:12px; height:12px; border-radius:50%; margin-right:.5rem; }}
|
|
188
275
|
.two-col {{ display:grid; grid-template-columns:1fr 1fr; gap:1rem; }}
|
|
276
|
+
.three-col {{ display:grid; grid-template-columns:1fr 1fr 1fr; gap:1rem; }}
|
|
189
277
|
.evo-cards {{ display:grid; grid-template-columns:repeat(auto-fit,minmax(120px,1fr)); gap:.75rem; }}
|
|
190
278
|
.evo-cards .card {{ text-align:center; }}
|
|
191
279
|
.trend {{ font-size:.75rem; color:var(--muted); }}
|
|
192
|
-
|
|
280
|
+
.lang-tag {{ display:inline-block; padding:.1rem .4rem; border-radius:.2rem; font-size:.7rem; font-weight:600; margin-right:.25rem; color:#fff; }}
|
|
281
|
+
@media (max-width:768px) {{ .two-col,.three-col {{ grid-template-columns:1fr; }} }}
|
|
193
282
|
footer {{ margin-top:2rem; color:var(--muted); font-size:.75rem; text-align:center; }}
|
|
194
283
|
</style>
|
|
195
284
|
</head>
|
|
@@ -200,24 +289,47 @@ class HTMLDashboardGenerator:
|
|
|
200
289
|
</h1>
|
|
201
290
|
<p style="color:var(--muted);font-size:.85rem;">
|
|
202
291
|
Analyzed {proj.get('analyzed_at', '?')[:10]} by code2llm
|
|
292
|
+
· Primary language: <strong>{proj.get('language', 'unknown')}</strong>
|
|
293
|
+
· {lang_summary}
|
|
203
294
|
</p>
|
|
204
295
|
|
|
205
296
|
<div class="grid">
|
|
297
|
+
<div class="card"><div class="value">{stats.get('functions', 0):,}</div><div class="label">Functions</div></div>
|
|
298
|
+
<div class="card"><div class="value">{stats.get('classes', 0):,}</div><div class="label">Classes</div></div>
|
|
299
|
+
<div class="card"><div class="value">{stats.get('files', 0):,}</div><div class="label">Files</div></div>
|
|
300
|
+
<div class="card"><div class="value">{stats.get('lines', 0):,}</div><div class="label">Lines</div></div>
|
|
301
|
+
<div class="card"><div class="value">{len(lang['names'])}</div><div class="label">Languages</div></div>
|
|
206
302
|
<div class="card"><div class="value">{cc_avg}</div><div class="label">Avg CC</div></div>
|
|
207
303
|
<div class="card"><div class="value">{health.get('critical_count', 0)}</div><div class="label">Critical (CC≥{health.get('critical_limit', 10)})</div></div>
|
|
208
|
-
<div class="card"><div class="value">{stats.get('functions', 0)}</div><div class="label">Functions</div></div>
|
|
209
|
-
<div class="card"><div class="value">{stats.get('classes', 0)}</div><div class="label">Classes</div></div>
|
|
210
|
-
<div class="card"><div class="value">{stats.get('files', 0)}</div><div class="label">Files</div></div>
|
|
211
|
-
<div class="card"><div class="value">{stats.get('lines', 0)}</div><div class="label">Lines</div></div>
|
|
212
304
|
<div class="card"><div class="value">{health.get('duplicates', 0)}</div><div class="label">Duplicates</div></div>
|
|
213
305
|
<div class="card"><div class="value">{health.get('cycles', 0)}</div><div class="label">Cycles</div></div>
|
|
214
306
|
</div>
|
|
215
307
|
|
|
308
|
+
<div class="three-col">
|
|
309
|
+
<div class="chart-container">
|
|
310
|
+
<h2 style="border:none;margin:0 0 .5rem;">Language Distribution</h2>
|
|
311
|
+
<canvas id="langChart" height="200"></canvas>
|
|
312
|
+
</div>
|
|
313
|
+
<div class="chart-container">
|
|
314
|
+
<h2 style="border:none;margin:0 0 .5rem;">Largest Modules (lines)</h2>
|
|
315
|
+
<canvas id="modLinesChart" height="200"></canvas>
|
|
316
|
+
</div>
|
|
317
|
+
<div class="chart-container">
|
|
318
|
+
<h2 style="border:none;margin:0 0 .5rem;">Most Complex Modules (functions)</h2>
|
|
319
|
+
<canvas id="modFuncsChart" height="200"></canvas>
|
|
320
|
+
</div>
|
|
321
|
+
</div>
|
|
322
|
+
|
|
216
323
|
<div class="two-col">
|
|
217
324
|
{evo_section}
|
|
218
|
-
<div
|
|
219
|
-
<h2
|
|
220
|
-
<
|
|
325
|
+
<div>
|
|
326
|
+
<h2>Top Modules ({len(modules)})</h2>
|
|
327
|
+
<div class="card"><div class="table-wrap">
|
|
328
|
+
<table>
|
|
329
|
+
<thead><tr><th>Module</th><th>Path</th><th style="text-align:right">Lines</th><th style="text-align:right">Funcs</th><th style="text-align:right">Classes</th><th style="text-align:right">CC max</th></tr></thead>
|
|
330
|
+
<tbody>{top_modules_html if top_modules_html else '<tr><td colspan="6" style="color:var(--muted)">No modules</td></tr>'}</tbody>
|
|
331
|
+
</table>
|
|
332
|
+
</div></div>
|
|
221
333
|
</div>
|
|
222
334
|
</div>
|
|
223
335
|
|
|
@@ -256,13 +368,54 @@ class HTMLDashboardGenerator:
|
|
|
256
368
|
<script>
|
|
257
369
|
{evo_script}
|
|
258
370
|
|
|
259
|
-
|
|
260
|
-
|
|
371
|
+
// Language distribution pie chart
|
|
372
|
+
const langCtx = document.getElementById('langChart').getContext('2d');
|
|
373
|
+
new Chart(langCtx, {{
|
|
374
|
+
type: 'doughnut',
|
|
375
|
+
data: {{
|
|
376
|
+
labels: {lang['names']},
|
|
377
|
+
datasets: [{{
|
|
378
|
+
data: {lang['files']},
|
|
379
|
+
backgroundColor: {lang['colors']},
|
|
380
|
+
borderColor: 'var(--border)', borderWidth: 1
|
|
381
|
+
}}]
|
|
382
|
+
}},
|
|
383
|
+
options: {{
|
|
384
|
+
responsive: true,
|
|
385
|
+
plugins: {{
|
|
386
|
+
legend: {{ position: 'right', labels: {{ color: '#e2e8f0', font: {{size: 11}} }} }}
|
|
387
|
+
}}
|
|
388
|
+
}}
|
|
389
|
+
}});
|
|
390
|
+
|
|
391
|
+
// Module lines bar chart
|
|
392
|
+
const modLinesCtx = document.getElementById('modLinesChart').getContext('2d');
|
|
393
|
+
new Chart(modLinesCtx, {{
|
|
394
|
+
type: 'bar',
|
|
395
|
+
data: {{
|
|
396
|
+
labels: {mod_lines['names']},
|
|
397
|
+
datasets: [{{ label: 'Lines', data: {mod_lines['lines']},
|
|
398
|
+
backgroundColor: '#3b82f6'
|
|
399
|
+
}}]
|
|
400
|
+
}},
|
|
401
|
+
options: {{
|
|
402
|
+
responsive: true, indexAxis: 'y',
|
|
403
|
+
scales: {{
|
|
404
|
+
x: {{ grid:{{color:'#334155'}}, ticks:{{color:'#94a3b8'}} }},
|
|
405
|
+
y: {{ grid:{{color:'#334155'}}, ticks:{{color:'#94a3b8',font:{{size:10}}}} }}
|
|
406
|
+
}},
|
|
407
|
+
plugins: {{ legend: {{ display:false }} }}
|
|
408
|
+
}}
|
|
409
|
+
}});
|
|
410
|
+
|
|
411
|
+
// Module functions bar chart
|
|
412
|
+
const modFuncsCtx = document.getElementById('modFuncsChart').getContext('2d');
|
|
413
|
+
new Chart(modFuncsCtx, {{
|
|
261
414
|
type: 'bar',
|
|
262
415
|
data: {{
|
|
263
|
-
labels: {
|
|
264
|
-
datasets: [{{ label: '
|
|
265
|
-
backgroundColor:
|
|
416
|
+
labels: {mod_funcs['names']},
|
|
417
|
+
datasets: [{{ label: 'Functions', data: {mod_funcs['funcs']},
|
|
418
|
+
backgroundColor: '#22c55e'
|
|
266
419
|
}}]
|
|
267
420
|
}},
|
|
268
421
|
options: {{
|
|
@@ -101,7 +101,7 @@ class READMEExporter(BaseExporter):
|
|
|
101
101
|
|
|
102
102
|
content = f"""# code2llm - Generated Analysis Files
|
|
103
103
|
|
|
104
|
-
This directory contains the complete analysis of your
|
|
104
|
+
This directory contains the complete analysis of your project generated by `code2llm`. Each file serves a specific purpose for understanding, refactoring, and documenting your codebase.
|
|
105
105
|
|
|
106
106
|
## 📁 Generated Files Overview
|
|
107
107
|
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
"""Rendering functions for TOON exporter."""
|
|
2
2
|
|
|
3
|
+
from collections import defaultdict
|
|
4
|
+
from pathlib import Path
|
|
3
5
|
from typing import Any, Dict, List
|
|
4
6
|
|
|
5
7
|
from ...core.models import AnalysisResult, FunctionInfo
|
|
8
|
+
from ...core.config import LANGUAGE_EXTENSIONS
|
|
6
9
|
|
|
7
10
|
from .helpers import _dup_file_set, _package_of
|
|
8
11
|
|
|
@@ -32,12 +35,37 @@ class ToonRenderer:
|
|
|
32
35
|
ndups = len(ctx["duplicates"])
|
|
33
36
|
ncycles = len(ctx["cycles"])
|
|
34
37
|
|
|
38
|
+
lang_label = self._detect_language_label(result)
|
|
39
|
+
|
|
35
40
|
lines = [
|
|
36
|
-
f"# code2llm | {nfiles}f {total_lines}L |
|
|
41
|
+
f"# code2llm | {nfiles}f {total_lines}L | {lang_label} | {ctx['timestamp']}",
|
|
37
42
|
f"# CC̄={avg_cc} | critical:{critical}/{nfuncs} | dups:{ndups} | cycles:{ncycles}",
|
|
38
43
|
]
|
|
39
44
|
return lines
|
|
40
45
|
|
|
46
|
+
@staticmethod
|
|
47
|
+
def _detect_language_label(result: AnalysisResult) -> str:
|
|
48
|
+
"""Build language breakdown label like 'typescript:463,javascript:10,rust:1'."""
|
|
49
|
+
from .helpers import _is_excluded
|
|
50
|
+
langs: Dict[str, int] = defaultdict(int)
|
|
51
|
+
for mi in result.modules.values():
|
|
52
|
+
if _is_excluded(mi.file):
|
|
53
|
+
continue
|
|
54
|
+
detected = False
|
|
55
|
+
for lang, extensions in LANGUAGE_EXTENSIONS.items():
|
|
56
|
+
if any(mi.file.endswith(ext) for ext in extensions):
|
|
57
|
+
langs[lang] += 1
|
|
58
|
+
detected = True
|
|
59
|
+
break
|
|
60
|
+
if not detected:
|
|
61
|
+
ext = Path(mi.file).suffix.lower()
|
|
62
|
+
if ext:
|
|
63
|
+
langs[ext.lstrip('.')] += 1
|
|
64
|
+
if not langs:
|
|
65
|
+
return "unknown"
|
|
66
|
+
sorted_langs = sorted(langs.items(), key=lambda x: -x[1])
|
|
67
|
+
return ",".join(f"{lang}:{count}" for lang, count in sorted_langs)
|
|
68
|
+
|
|
41
69
|
def render_health(self, ctx: Dict[str, Any]) -> List[str]:
|
|
42
70
|
"""Render health section."""
|
|
43
71
|
issues = ctx["health"]
|
|
@@ -3,9 +3,23 @@
|
|
|
3
3
|
Generates project.toon from project.yaml data.
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
+
from collections import defaultdict
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
from typing import Any, Dict, List
|
|
8
9
|
|
|
10
|
+
# Language detection from file extensions
|
|
11
|
+
_LANG_EXT_MAP = {
|
|
12
|
+
'.py': 'python', '.ts': 'typescript', '.tsx': 'typescript',
|
|
13
|
+
'.js': 'javascript', '.jsx': 'javascript', '.mjs': 'javascript', '.cjs': 'javascript',
|
|
14
|
+
'.go': 'go', '.rs': 'rust', '.java': 'java',
|
|
15
|
+
'.cpp': 'cpp', '.cc': 'cpp', '.cxx': 'cpp', '.hpp': 'cpp', '.h': 'c',
|
|
16
|
+
'.c': 'c', '.cs': 'csharp', '.rb': 'ruby', '.php': 'php',
|
|
17
|
+
'.swift': 'swift', '.kt': 'kotlin', '.kts': 'kotlin',
|
|
18
|
+
'.scala': 'scala', '.sh': 'shell', '.bash': 'shell', '.zsh': 'shell',
|
|
19
|
+
'.dart': 'dart', '.ex': 'elixir', '.exs': 'elixir',
|
|
20
|
+
'.hs': 'haskell', '.lua': 'lua', '.pl': 'perl', '.r': 'r', '.R': 'r',
|
|
21
|
+
}
|
|
22
|
+
|
|
9
23
|
|
|
10
24
|
class ToonViewGenerator:
|
|
11
25
|
"""Generate project.toon from project.yaml data."""
|
|
@@ -37,11 +51,13 @@ class ToonViewGenerator:
|
|
|
37
51
|
@staticmethod
|
|
38
52
|
def _render_header(proj: Dict) -> List[str]:
|
|
39
53
|
stats = proj.get("stats", {})
|
|
54
|
+
lang = proj.get('language', 'unknown')
|
|
40
55
|
return [
|
|
41
56
|
f"# {proj.get('name', '?')} | "
|
|
42
57
|
f"{stats.get('functions', 0)} func | "
|
|
43
58
|
f"{stats.get('files', 0)}f | "
|
|
44
59
|
f"{stats.get('lines', 0)}L | "
|
|
60
|
+
f"{lang} | "
|
|
45
61
|
f"{proj.get('analyzed_at', '?')[:10]}",
|
|
46
62
|
"",
|
|
47
63
|
]
|
|
@@ -73,17 +89,33 @@ class ToonViewGenerator:
|
|
|
73
89
|
|
|
74
90
|
@staticmethod
|
|
75
91
|
def _render_modules(modules: List[Dict]) -> List[str]:
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
92
|
+
# Show top modules by size (lines) - works for all languages
|
|
93
|
+
top_by_lines = sorted(modules, key=lambda m: m.get("lines", 0), reverse=True)[:15]
|
|
94
|
+
lines = ["", f"MODULES[{len(modules)}] (top by size):"]
|
|
95
|
+
for m in top_by_lines:
|
|
96
|
+
path = m.get('path', '?')
|
|
97
|
+
ext = Path(path).suffix.lower()
|
|
98
|
+
lang = _LANG_EXT_MAP.get(ext, ext.lstrip('.'))
|
|
79
99
|
lines.append(
|
|
80
|
-
f" M[{
|
|
100
|
+
f" M[{path}] "
|
|
81
101
|
f"{m.get('lines', 0)}L "
|
|
82
102
|
f"C:{m.get('classes', 0)} "
|
|
83
|
-
f"
|
|
103
|
+
f"F:{m.get('methods', 0)} "
|
|
84
104
|
f"CC↑{m.get('cc_max', 0)} "
|
|
85
|
-
f"D:{m.get('inbound_deps', 0)}"
|
|
105
|
+
f"D:{m.get('inbound_deps', 0)} "
|
|
106
|
+
f"({lang})"
|
|
86
107
|
)
|
|
108
|
+
|
|
109
|
+
# Language breakdown
|
|
110
|
+
lang_counts: Dict[str, int] = defaultdict(int)
|
|
111
|
+
for m in modules:
|
|
112
|
+
ext = Path(m.get('path', '')).suffix.lower()
|
|
113
|
+
lang = _LANG_EXT_MAP.get(ext, ext.lstrip('.') if ext else 'other')
|
|
114
|
+
lang_counts[lang] += 1
|
|
115
|
+
if lang_counts:
|
|
116
|
+
sorted_langs = sorted(lang_counts.items(), key=lambda x: -x[1])
|
|
117
|
+
lang_str = '/'.join(f"{l}:{c}" for l, c in sorted_langs)
|
|
118
|
+
lines.append(f" LANGS: {lang_str}")
|
|
87
119
|
return lines
|
|
88
120
|
|
|
89
121
|
@staticmethod
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code2llm
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.48
|
|
4
4
|
Summary: High-performance Python code flow analysis with optimized TOON format - CFG, DFG, call graphs, and intelligent code queries
|
|
5
5
|
Home-page: https://github.com/wronai/stts
|
|
6
6
|
Author: STTS Project
|
|
@@ -50,7 +50,7 @@ Dynamic: requires-python
|
|
|
50
50
|
|
|
51
51
|
# code2llm - Generated Analysis Files
|
|
52
52
|
|
|
53
|
-
This directory contains the complete analysis of your
|
|
53
|
+
This directory contains the complete analysis of your project generated by `code2llm`. Each file serves a specific purpose for understanding, refactoring, and documenting your codebase.
|
|
54
54
|
|
|
55
55
|
## 📁 Generated Files Overview
|
|
56
56
|
|
|
@@ -60,7 +60,7 @@ When you run `code2llm ./ -f all`, the following files are created:
|
|
|
60
60
|
|
|
61
61
|
| File | Format | Purpose | Key Insights |
|
|
62
62
|
|------|--------|---------|--------------|
|
|
63
|
-
| `analysis.toon` | **TOON** | **🔥 Health diagnostics** - Complexity, god modules, coupling |
|
|
63
|
+
| `analysis.toon` | **TOON** | **🔥 Health diagnostics** - Complexity, god modules, coupling | 59 critical functions, 0 god modules |
|
|
64
64
|
| `project.toon` | **TOON** | **🧠 Project logic** - Compact module view from code2logic | Generated via code2logic integration |
|
|
65
65
|
|
|
66
66
|
### 🤖 LLM-Ready Documentation
|
|
@@ -374,10 +374,10 @@ code2llm ./ -f yaml --separate-orphans
|
|
|
374
374
|
---
|
|
375
375
|
|
|
376
376
|
**Generated by**: `code2llm ./ -f all --readme`
|
|
377
|
-
**Analysis Date**: 2026-03-
|
|
378
|
-
**Total Functions**:
|
|
377
|
+
**Analysis Date**: 2026-03-09
|
|
378
|
+
**Total Functions**: 850
|
|
379
379
|
**Total Classes**: 104
|
|
380
|
-
**Modules**:
|
|
380
|
+
**Modules**: 105
|
|
381
381
|
|
|
382
382
|
For more information about code2llm, visit: https://github.com/tom-sapletta/code2llm
|
|
383
383
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "code2llm"
|
|
7
|
-
version = "0.5.
|
|
7
|
+
version = "0.5.48"
|
|
8
8
|
description = "High-performance Python code flow analysis with optimized TOON format - CFG, DFG, call graphs, and intelligent code queries"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.8"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|