Skip to content

Commit d9513b6

Browse files
refactor(docs): code analysis engine
changes: - file: formats.py area: cli modified: [_export_simple_formats, _export_evolution] - file: prompt.py area: cli modified: [_build_prompt_footer, _analyze_generated_files, _build_dynamic_focus_areas, _build_subprojects_section, _build_dynamic_tasks] - file: cli_parser.py area: analyzer modified: [create_parser] - file: evolution_exporter.py area: core added: [export_to_yaml] modified: [EvolutionExporter] - file: map_exporter.py area: core added: [export_to_yaml] modified: [MapExporter] - file: readme_exporter.py area: docs modified: [_get_existing_files, _build_core_files_section, _extract_insights, _generate_readme_content, READMEExporter] stats: lines: "+1328/-416 (net +912)" files: 24 complexity: "Large structural change (normalized)"
1 parent 2f9f1e1 commit d9513b6

29 files changed

Lines changed: 1351 additions & 420 deletions

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,24 @@
11
## [Unreleased]
22

3+
## [0.5.68] - 2026-03-25
4+
5+
### Docs
6+
- Update project/README.md
7+
- Update project/context.md
8+
9+
### Other
10+
- Update code2llm/cli_exports/formats.py
11+
- Update code2llm/cli_exports/prompt.py
12+
- Update code2llm/cli_parser.py
13+
- Update code2llm/exporters/__init__.py
14+
- Update code2llm/exporters/evolution_exporter.py
15+
- Update code2llm/exporters/flow_exporter.py
16+
- Update code2llm/exporters/map_exporter.py
17+
- Update code2llm/exporters/readme_exporter.py
18+
- Update code2llm/exporters/toon/metrics.py
19+
- Update code2llm/exporters/toon/module_detail.py
20+
- ... and 12 more files
21+
322
## [0.5.67] - 2026-03-25
423

524
### Other

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.5.67
1+
0.5.68

code2llm/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
and entity resolution with multilingual support.
99
"""
1010

11-
__version__ = "0.5.67"
11+
__version__ = "0.5.68"
1212
__author__ = "STTS Project"
1313

1414
# Core analysis components (lightweight, always needed)

code2llm/cli_exports/formats.py

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from pathlib import Path
66
from typing import Optional
77

8-
from ..exporters import (
8+
from code2llm.exporters import (
99
YAMLExporter, JSONExporter, MermaidExporter,
1010
ContextExporter, ToonExporter, MapExporter, FlowExporter,
1111
EvolutionExporter, READMEExporter, ProjectYAMLExporter,
@@ -16,14 +16,14 @@
1616

1717

1818
def _export_evolution(args, result, output_dir: Path):
19-
"""Export evolution.toon format."""
19+
"""Export evolution.toon.yaml format."""
2020
if 'evolution' not in [f.strip() for f in args.format.split(',')] and 'all' not in [f.strip() for f in args.format.split(',')]:
2121
return
2222
exporter = EvolutionExporter()
23-
filepath = output_dir / 'evolution.toon'
24-
exporter.export(result, str(filepath))
23+
filepath = output_dir / 'evolution.toon.yaml'
24+
exporter.export_to_yaml(result, str(filepath))
2525
if args.verbose:
26-
print(f" - EVOLUTION (refactoring queue): {filepath}")
26+
print(f" - EVOLUTION-YAML (refactoring queue): {filepath}")
2727

2828

2929
def _export_data_structures(args, result, output_dir: Path):
@@ -101,16 +101,16 @@ def _export_simple_formats(args, result, output_dir: Path, formats):
101101
"""Export toon, map, flow, context, yaml, json, project-yaml formats."""
102102
format_map = {
103103
'toon': (ToonExporter, 'analysis.toon.yaml', 'TOON-YAML (diagnostics)'),
104-
'map': (MapExporter, 'map.toon', 'MAP (structure + header)'),
104+
'map': (MapExporter, 'map.toon.yaml', 'MAP-YAML (structure)'),
105105
'flow': (FlowExporter, 'flow.toon', 'FLOW (data-flow)'),
106106
'context': (ContextExporter, 'context.md', 'CONTEXT (LLM narrative)'),
107107
}
108108

109109
for fmt, (exporter_cls, filename, label) in format_map.items():
110110
if fmt in formats:
111111
exporter = exporter_cls()
112-
# For toon format, export as YAML (analysis.toon.yaml)
113-
if fmt == 'toon':
112+
# For toon and map formats, export as YAML
113+
if fmt in ('toon', 'map'):
114114
filepath = output_dir / filename
115115
exporter.export_to_yaml(result, str(filepath))
116116
if args.verbose:

code2llm/cli_exports/prompt.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ def _get_prompt_paths(source_path: Optional[Path], output_dir: Path) -> Tuple[st
7878

7979
_MAIN_FILES = [
8080
('analysis.toon', 'Health diagnostics - complexity metrics, god modules, coupling issues, refactoring priorities'),
81-
('map.toon', 'Structural map - files, sizes, imports, exports, signatures, project header'),
81+
('map.toon.yaml', 'Structural map - files, sizes, imports, exports, signatures, project header'),
8282
('context.md', 'LLM narrative - architecture summary, key entry points, process flows, public API surface'),
83-
('evolution.toon', 'Refactoring queue - ranked actions by impact/effort, risks, metrics targets, history'),
83+
('evolution.toon.yaml', 'Refactoring queue - ranked actions by impact/effort, risks, metrics targets, history'),
8484
('README.md', 'Documentation - complete guide to all generated files, usage examples, interpretation'),
8585
]
8686

@@ -139,7 +139,7 @@ def _build_subprojects_section(subprojects: list, output_dir: Path, output_rel_p
139139
level_name = {0: 'root', 1: 'L1', 2: 'L2', 3: 'chunk'}.get(sp.level, f'L{sp.level}')
140140
sp_files = []
141141
total_size = 0
142-
for f in ['analysis.toon', 'context.md', 'evolution.toon']:
142+
for f in ['analysis.toon', 'context.md', 'evolution.toon.yaml']:
143143
f_path = sp_dir / f
144144
if f_path.exists():
145145
size = f_path.stat().st_size
@@ -169,9 +169,9 @@ def _analyze_generated_files(output_dir: Path, subprojects: list = None) -> dict
169169
"""Analyze which files were generated and determine appropriate focus areas."""
170170
analysis = {
171171
'has_analysis_toon': (output_dir / 'analysis.toon').exists(),
172-
'has_map_toon': (output_dir / 'map.toon').exists(),
172+
'has_map_toon': (output_dir / 'map.toon.yaml').exists(),
173173
'has_context_md': (output_dir / 'context.md').exists(),
174-
'has_evolution_toon': (output_dir / 'evolution.toon').exists(),
174+
'has_evolution_toon': (output_dir / 'evolution.toon.yaml').exists(),
175175
'has_readme': (output_dir / 'README.md').exists(),
176176
'has_yaml': (output_dir / 'analysis.yaml').exists(),
177177
'has_json': (output_dir / 'analysis.json').exists(),
@@ -196,10 +196,10 @@ def _build_dynamic_focus_areas(file_analysis: dict) -> List[str]:
196196
focus_areas.append("1. **Code Health Analysis** - Review complexity metrics, god modules, coupling issues from analysis.toon")
197197

198198
if file_analysis['has_map_toon']:
199-
focus_areas.append("2. **Structural Map** - Use map.toon to inspect imports, exports, signatures, and the project header")
199+
focus_areas.append("2. **Structural Map** - Use map.toon.yaml to inspect imports, exports, signatures, and the project header")
200200

201201
if file_analysis['has_evolution_toon']:
202-
focus_areas.append("3. **Refactoring Priorities** - Examine ranked refactoring actions and risk assessment from evolution.toon")
202+
focus_areas.append("3. **Refactoring Priorities** - Examine ranked refactoring actions and risk assessment from evolution.toon.yaml")
203203

204204
if file_analysis['has_context_md']:
205205
focus_areas.append("4. **Architecture Overview** - Understand main flows, entry points, and public API from context.md")
@@ -231,10 +231,10 @@ def _build_dynamic_tasks(file_analysis: dict) -> List[str]:
231231
tasks.append("- Highlight critical functions (CC ≥ 10) and top problem areas from analysis.toon.")
232232

233233
if file_analysis['has_map_toon']:
234-
tasks.append("- Cross-check imports, exports, and signatures against map.toon before proposing splits.")
234+
tasks.append("- Cross-check imports, exports, and signatures against map.toon.yaml before proposing splits.")
235235

236236
if file_analysis['has_evolution_toon']:
237-
tasks.append("- Prioritize refactoring actions by impact/effort ratio from evolution.toon.")
237+
tasks.append("- Prioritize refactoring actions by impact/effort ratio from evolution.toon.yaml.")
238238

239239
if file_analysis['has_context_md']:
240240
tasks.append("- Validate entry points and public API surface match the architecture described.")
@@ -271,9 +271,9 @@ def _build_prompt_footer(chunked: bool = False, file_analysis: dict = None) -> L
271271
lines.append("")
272272
lines.append("Analysis Strategy:")
273273
if file_analysis['has_analysis_toon'] and file_analysis['has_map_toon']:
274-
lines.append("- Start with analysis.toon for health metrics, then map.toon for structure and signatures")
274+
lines.append("- Start with analysis.toon for health metrics, then map.toon.yaml for structure and signatures")
275275
if file_analysis['has_evolution_toon']:
276-
lines.append("- Finish with evolution.toon for action priorities and next steps")
276+
lines.append("- Finish with evolution.toon.yaml for action priorities and next steps")
277277
elif file_analysis['has_context_md']:
278278
lines.append("- Use context.md as the primary reference for architectural understanding")
279279

code2llm/cli_parser.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,16 @@ def create_parser() -> argparse.ArgumentParser:
3434
3535
Format Options (-f):
3636
toon — Health diagnostics (analysis.toon) [default]
37-
map — Structural map (map.toon) — modules, imports, exports, signatures, project header
38-
evolution — Refactoring queue (evolution.toon)
37+
map — Structural map (map.toon.yaml) — modules, imports, exports, signatures, project header
38+
evolution — Refactoring queue (evolution.toon.yaml)
3939
context — LLM narrative (context.md) — architecture summary
4040
yaml — Standard YAML format
4141
json — Machine-readable JSON
4242
mermaid — Flowchart diagrams (flow.mmd, calls.mmd, compact_flow.mmd)
4343
flow — Data-flow analysis (flow.toon) — legacy, explicit opt-in
4444
code2logic — Generate project logic (legacy project.toon) via external code2logic
4545
project-yaml — Unified project.yaml (single source of truth) + generated views
46-
all — Generate core formats (analysis.toon, map.toon, evolution.toon, context, yaml, json, mermaid)
46+
all — Generate core formats (analysis.toon, map.toon.yaml, evolution.toon.yaml, context, yaml, json, mermaid)
4747
4848
Strategy Options (--strategy):
4949
quick — Fast overview, fewer files analyzed

code2llm/exporters/__init__.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
"""Exporters package for code2llm.
22
33
Available exporters:
4-
- ToonExporter → analysis.toon (health diagnostics)
5-
- MapExporter → map.toon (structural map + project header)
6-
- FlowExporter → flow.toon (data-flow: pipelines, contracts, types)
7-
- EvolutionExporter → evolution.toon (ranked refactoring queue)
8-
- ContextExporter → context.md (LLM narrative)
9-
- READMEExporter → README.md (documentation of all files)
4+
- ToonExporter → analysis.toon (health diagnostics)
5+
- MapExporter → map.toon.yaml (structural map + project header)
6+
- FlowExporter → flow.toon (data-flow: pipelines, contracts, types)
7+
- EvolutionExporter → evolution.toon.yaml (ranked refactoring queue)
8+
- ContextExporter → context.md (LLM narrative)
9+
- READMEExporter → README.md (documentation of all files)
1010
- YAMLExporter → analysis.yaml
1111
- JSONExporter → analysis.json
1212
- MermaidExporter → *.mmd

code2llm/exporters/evolution_exporter.py

Lines changed: 92 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
"""Evolution Exporter — prioritized refactoring queue for iterative improvement.
22
3-
Generates evolution.toon with:
3+
Generates evolution.toon.yaml with:
44
NEXT[N] — ranked refactoring actions (impact × effort)
55
RISKS[N] — breaking changes and compatibility notes
66
METRICS-TARGET — measurable goals vs current baseline
7-
HISTORY — comparison with previous evolution.toon
7+
HISTORY — comparison with previous evolution.toon.yaml
88
"""
99

10+
import yaml
1011
from collections import defaultdict
1112
from datetime import datetime
1213
from pathlib import Path
@@ -24,7 +25,7 @@
2425

2526

2627
class EvolutionExporter(Exporter):
27-
"""Export evolution.toon — prioritized refactoring queue."""
28+
"""Export evolution.toon.yaml — prioritized refactoring queue."""
2829

2930
# Exclude patterns (mirrors ToonExporter)
3031
EXCLUDE_PATTERNS = {
@@ -65,6 +66,94 @@ def export(self, result: AnalysisResult, output_path: str, **kwargs) -> None:
6566
with open(output_path, "w", encoding="utf-8") as f:
6667
f.write("\n".join(sections) + "\n")
6768

69+
def export_to_yaml(self, result: AnalysisResult, output_path: str, **kwargs) -> None:
70+
"""Generate evolution.toon.yaml (structured YAML)."""
71+
ctx = self._build_context(result)
72+
73+
# Build refactoring actions
74+
actions = []
75+
for gm in ctx["god_modules"][:3]:
76+
actions.append({
77+
"priority": "high",
78+
"action": "SPLIT",
79+
"target": gm["file"],
80+
"reason": f"{gm['lines']}L, {gm['classes']} classes, max CC={gm['max_cc']}",
81+
"effort": "~4h",
82+
})
83+
84+
for f in ctx["funcs"][:20]:
85+
if f["cc"] >= CC_SPLIT_THRESHOLD:
86+
actions.append({
87+
"priority": "critical" if f["cc"] >= 25 else "high",
88+
"action": "SPLIT-FUNC",
89+
"target": f"{f['class_name']}.{f['name']}" if f["class_name"] else f["name"],
90+
"cc": f["cc"],
91+
"fan_out": f["fan_out"],
92+
"reason": f"CC={f['cc']} exceeds {CC_SPLIT_THRESHOLD}",
93+
"effort": "~1h",
94+
})
95+
96+
for ht in ctx["hub_types"][:3]:
97+
if ht["consumers"] >= 20:
98+
actions.append({
99+
"priority": "medium",
100+
"action": "INTERFACE-SPLIT",
101+
"target": ht["type"],
102+
"consumers": ht["consumers"],
103+
"reason": f"Hub type with {ht['consumers']} consumers",
104+
"effort": "~6h",
105+
})
106+
107+
actions.sort(key=lambda x: x.get("priority", "") == "critical", reverse=True)
108+
109+
# Build risks
110+
risks = []
111+
for gm in ctx["god_modules"][:3]:
112+
risks.append({
113+
"type": "breaking_imports",
114+
"target": gm["file"],
115+
"impact": f"may break {gm['funcs']} import paths",
116+
})
117+
for ht in ctx["hub_types"][:2]:
118+
if ht["consumers"] >= 20:
119+
risks.append({
120+
"type": "api_change",
121+
"target": ht["type"],
122+
"impact": f"changes API for {ht['consumers']} consumers",
123+
})
124+
125+
data = {
126+
"format": "evolution-toon-yaml",
127+
"timestamp": ctx["timestamp"],
128+
"stats": {
129+
"total_funcs": ctx["total_funcs"],
130+
"total_files": ctx["total_files"],
131+
"avg_cc": ctx["avg_cc"],
132+
"max_cc": ctx["max_cc"],
133+
"high_cc_count": ctx["high_cc_count"],
134+
"critical_count": ctx["critical_count"],
135+
},
136+
"refactoring": {
137+
"action_count": len(actions),
138+
"actions": actions[:10],
139+
},
140+
"risks": {
141+
"count": len(risks),
142+
"items": risks,
143+
},
144+
"metrics_target": {
145+
"avg_cc": {"current": ctx["avg_cc"], "target": round(min(ctx["avg_cc"] * 0.7, 5.0), 1)},
146+
"max_cc": {"current": ctx["max_cc"], "target": min(ctx["max_cc"] // 2, 20)},
147+
"god_modules": {"current": len(ctx["god_modules"]), "target": 0},
148+
"high_cc": {"current": ctx["high_cc_count"], "target": max(ctx["high_cc_count"] // 2, 0)},
149+
"hub_types": {"current": len(ctx["hub_types"]), "target": max(len(ctx["hub_types"]) - 2, 0)},
150+
},
151+
}
152+
153+
Path(output_path).parent.mkdir(parents=True, exist_ok=True)
154+
with open(output_path, "w", encoding="utf-8") as f:
155+
yaml.dump(data, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
156+
68157
# ------------------------------------------------------------------
69158
# context builder
70159
# ------------------------------------------------------------------

code2llm/exporters/flow_exporter.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@
1919
from .base import Exporter
2020
from .flow_constants import CC_HIGH, FAN_OUT_THRESHOLD, EXCLUDE_PATTERNS, HUB_SPLIT_RECOMMENDATIONS, HUB_TYPE_THRESHOLD
2121
from .flow_renderer import FlowRenderer
22-
from ..core.models import (
22+
from code2llm.core.models import (
2323
AnalysisResult, FunctionInfo, ClassInfo, ModuleInfo, FlowNode
2424
)
25-
from ..analysis.type_inference import TypeInferenceEngine
26-
from ..analysis.side_effects import SideEffectDetector, SideEffectInfo
27-
from ..analysis.pipeline_detector import PipelineDetector, Pipeline
25+
from code2llm.analysis.type_inference import TypeInferenceEngine
26+
from code2llm.analysis.side_effects import SideEffectDetector, SideEffectInfo
27+
from code2llm.analysis.pipeline_detector import PipelineDetector, Pipeline
2828

2929
# Thresholds - already imported from flow_constants
3030

0 commit comments

Comments
 (0)