code2llm 0.5.151__tar.gz → 0.5.153__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.151/code2llm.egg-info → code2llm-0.5.153}/PKG-INFO +13 -6
- {code2llm-0.5.151 → code2llm-0.5.153}/README.md +12 -5
- code2llm-0.5.153/VERSION +1 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/__init__.py +12 -5
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/__main__.py +1 -1
- code2llm-0.5.153/code2llm/analysis/__init__.py +38 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/analysis/call_graph.py +52 -43
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/analysis/cfg.py +70 -63
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/analysis/coupling.py +30 -29
- code2llm-0.5.153/code2llm/analysis/data_analysis.py +565 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/analysis/dfg.py +95 -73
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/analysis/pipeline_classifier.py +45 -13
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/analysis/pipeline_detector.py +31 -33
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/analysis/pipeline_resolver.py +2 -1
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/analysis/side_effects.py +139 -48
- code2llm-0.5.153/code2llm/analysis/smells.py +224 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/analysis/type_inference.py +24 -16
- code2llm-0.5.153/code2llm/analysis/utils/__init__.py +17 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/analysis/utils/ast_helpers.py +4 -3
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/cli.py +8 -12
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/cli_analysis.py +82 -62
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/cli_commands.py +91 -59
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/cli_exports/code2logic.py +32 -17
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/cli_exports/formats.py +98 -68
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/cli_exports/orchestrator.py +113 -57
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/cli_exports/orchestrator_chunked.py +23 -16
- code2llm-0.5.153/code2llm/cli_exports/orchestrator_constants.py +55 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/cli_exports/orchestrator_handlers.py +51 -40
- code2llm-0.5.153/code2llm/cli_exports/prompt.py +598 -0
- code2llm-0.5.153/code2llm/cli_parser.py +357 -0
- code2llm-0.5.153/code2llm/core/__init__.py +68 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/analyzer.py +183 -112
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/config.py +154 -108
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/export_pipeline.py +1 -1
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/file_analyzer.py +241 -141
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/file_cache.py +14 -14
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/file_filter.py +97 -38
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/gitignore.py +45 -36
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/lang/__init__.py +31 -32
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/lang/base.py +301 -143
- code2llm-0.5.153/code2llm/core/lang/cpp.py +41 -0
- code2llm-0.5.153/code2llm/core/lang/csharp.py +57 -0
- code2llm-0.5.153/code2llm/core/lang/generic.py +88 -0
- code2llm-0.5.153/code2llm/core/lang/go_lang.py +126 -0
- code2llm-0.5.153/code2llm/core/lang/java.py +58 -0
- code2llm-0.5.153/code2llm/core/lang/php.py +118 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/lang/ruby.py +57 -53
- code2llm-0.5.153/code2llm/core/lang/rust.py +116 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/lang/ts_extractors.py +90 -61
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/lang/ts_parser.py +24 -21
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/lang/typescript.py +38 -20
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/large_repo.py +247 -192
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/models.py +30 -16
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/persistent_cache.py +17 -12
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/refactoring.py +54 -32
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/repo_files.py +75 -34
- code2llm-0.5.153/code2llm/core/source_classifier.py +254 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/streaming/cache.py +8 -8
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/streaming/incremental.py +17 -15
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/streaming/prioritizer.py +29 -28
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/streaming/scanner.py +72 -65
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/streaming/strategies.py +5 -4
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/streaming_analyzer.py +76 -79
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/toon_size_manager.py +85 -72
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/__init__.py +30 -26
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/article_view.py +17 -7
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/base.py +8 -10
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/context_exporter.py +157 -72
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/context_view.py +15 -5
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/dashboard_data.py +78 -33
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/dashboard_renderer.py +45 -32
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/evolution/__init__.py +21 -21
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/evolution/computation.py +59 -36
- code2llm-0.5.153/code2llm/exporters/evolution/constants.py +41 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/evolution/exclusion.py +2 -2
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/evolution/render.py +45 -45
- code2llm-0.5.153/code2llm/exporters/evolution/yaml_export.py +126 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/evolution_exporter.py +12 -5
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/flow_constants.py +26 -7
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/flow_exporter.py +55 -39
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/flow_renderer.py +20 -25
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/html_dashboard.py +18 -8
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/index_generator/__init__.py +9 -9
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/index_generator/renderer.py +2 -2
- code2llm-0.5.153/code2llm/exporters/index_generator/scanner.py +133 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/index_generator.py +8 -8
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/json_exporter.py +2 -2
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/map/__init__.py +11 -11
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/map/alerts.py +3 -3
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/map/details.py +2 -5
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/map/header.py +27 -16
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/map/module_list.py +1 -1
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/map/utils.py +8 -6
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/map/yaml_export.py +23 -11
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/map_exporter.py +6 -3
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/mermaid/__init__.py +15 -15
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/mermaid/calls.py +9 -2
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/mermaid/classic.py +17 -4
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/mermaid/compact.py +6 -3
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/mermaid/flow_compact.py +25 -15
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/mermaid/flow_detailed.py +21 -5
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/mermaid/flow_full.py +21 -5
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/mermaid/utils.py +20 -18
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/mermaid_exporter.py +0 -4
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/mermaid_flow_helpers.py +26 -16
- code2llm-0.5.153/code2llm/exporters/planfile_tickets.py +361 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/project_yaml/core.py +32 -21
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/project_yaml/health.py +27 -15
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/project_yaml/hotspots.py +42 -30
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/project_yaml/modules.py +21 -14
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/readme/__init__.py +6 -6
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/readme/content.py +5 -5
- code2llm-0.5.153/code2llm/exporters/readme/files.py +26 -0
- code2llm-0.5.153/code2llm/exporters/readme/insights.py +54 -0
- code2llm-0.5.153/code2llm/exporters/readme/sections.py +93 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/readme_exporter.py +21 -7
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/report_generators.py +8 -5
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/toon/__init__.py +52 -11
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/toon/helpers.py +37 -10
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/toon/metrics.py +15 -11
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/toon/metrics_core.py +58 -38
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/toon/metrics_duplicates.py +24 -6
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/toon/metrics_health.py +54 -30
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/toon/module_detail.py +24 -14
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/toon/renderer.py +66 -38
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/toon.py +0 -1
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/toon_view.py +50 -17
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/validate_project.py +4 -1
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/yaml_exporter.py +205 -103
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/__init__.py +3 -3
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/llm_flow/__init__.py +26 -26
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/llm_flow/analysis.py +20 -10
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/llm_flow/cli.py +2 -2
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/llm_flow/generator.py +5 -3
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/llm_flow/nodes.py +15 -11
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/llm_flow/parsing.py +2 -2
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/llm_flow/utils.py +13 -10
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/llm_flow.py +27 -26
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/llm_task.py +49 -15
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/mermaid/__init__.py +21 -21
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/mermaid/fix.py +44 -41
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/mermaid/png.py +110 -48
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/mermaid/validation.py +41 -30
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/mermaid.py +29 -30
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/nlp/__init__.py +2 -2
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/nlp/config.py +44 -33
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/nlp/entity_resolution.py +81 -79
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/nlp/intent_matching.py +117 -90
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/nlp/normalization.py +29 -28
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/nlp/pipeline.py +110 -100
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/parsers/toon_parser.py +55 -55
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/patterns/detector.py +100 -81
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/refactor/prompt_engine.py +65 -36
- {code2llm-0.5.151 → code2llm-0.5.153/code2llm.egg-info}/PKG-INFO +13 -6
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm.egg-info/SOURCES.txt +4 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/pyproject.toml +1 -1
- code2llm-0.5.153/setup.py +76 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_advanced_analysis.py +47 -26
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_analyzer.py +38 -41
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_cache_invalidation_e2e.py +7 -3
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_calls_toon_export.py +33 -34
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_declarative_collection.py +86 -7
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_deep_analysis.py +19 -16
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_edge_cases.py +99 -93
- code2llm-0.5.153/tests/test_export_cache_flags.py +27 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_flow_exporter.py +96 -47
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_format_quality.py +50 -19
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_multilanguage_e2e.py +77 -50
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_nlp_pipeline.py +71 -72
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_nonpython_cc_calls.py +125 -60
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_orchestrator_cache_mtime.py +3 -2
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_persistent_cache.py +22 -8
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_pipeline_detector.py +164 -66
- code2llm-0.5.153/tests/test_planfile_tickets_exporter.py +146 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_project_toon_export.py +24 -11
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_prompt_engine.py +16 -14
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_prompt_txt.py +158 -108
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_refactoring_engine.py +34 -21
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_toon_v2.py +58 -51
- code2llm-0.5.151/VERSION +0 -1
- code2llm-0.5.151/code2llm/analysis/__init__.py +0 -37
- code2llm-0.5.151/code2llm/analysis/data_analysis.py +0 -375
- code2llm-0.5.151/code2llm/analysis/smells.py +0 -196
- code2llm-0.5.151/code2llm/analysis/utils/__init__.py +0 -5
- code2llm-0.5.151/code2llm/cli_exports/orchestrator_constants.py +0 -52
- code2llm-0.5.151/code2llm/cli_exports/prompt.py +0 -479
- code2llm-0.5.151/code2llm/cli_parser.py +0 -333
- code2llm-0.5.151/code2llm/core/__init__.py +0 -53
- code2llm-0.5.151/code2llm/core/lang/cpp.py +0 -35
- code2llm-0.5.151/code2llm/core/lang/csharp.py +0 -42
- code2llm-0.5.151/code2llm/core/lang/generic.py +0 -71
- code2llm-0.5.151/code2llm/core/lang/go_lang.py +0 -102
- code2llm-0.5.151/code2llm/core/lang/java.py +0 -43
- code2llm-0.5.151/code2llm/core/lang/php.py +0 -66
- code2llm-0.5.151/code2llm/core/lang/rust.py +0 -94
- code2llm-0.5.151/code2llm/exporters/evolution/constants.py +0 -25
- code2llm-0.5.151/code2llm/exporters/evolution/yaml_export.py +0 -102
- code2llm-0.5.151/code2llm/exporters/index_generator/scanner.py +0 -116
- code2llm-0.5.151/code2llm/exporters/readme/files.py +0 -26
- code2llm-0.5.151/code2llm/exporters/readme/insights.py +0 -52
- code2llm-0.5.151/code2llm/exporters/readme/sections.py +0 -67
- code2llm-0.5.151/setup.py +0 -72
- {code2llm-0.5.151 → code2llm-0.5.153}/LICENSE +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/MANIFEST.in +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/api.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/cli_exports/__init__.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/ast_registry.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/incremental.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/core/streaming/__init__.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/llm_exporter.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/project_yaml/__init__.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/project_yaml/constants.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/project_yaml/evolution.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/exporters/project_yaml_exporter.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/generators/_utils.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/patterns/__init__.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm/refactor/__init__.py +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm.egg-info/dependency_links.txt +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm.egg-info/entry_points.txt +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm.egg-info/requires.txt +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/code2llm.egg-info/top_level.txt +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/setup.cfg +0 -0
- {code2llm-0.5.151 → code2llm-0.5.153}/tests/test_file_analyzer_tagging.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.153
|
|
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
|
|
@@ -66,13 +66,13 @@ Dynamic: requires-python
|
|
|
66
66
|
|
|
67
67
|
## AI Cost Tracking
|
|
68
68
|
|
|
69
|
-
     
|
|
70
|
+
  
|
|
71
71
|
|
|
72
|
-
- 🤖 **LLM usage:** $7.5000 (
|
|
73
|
-
- 👤 **Human dev:** ~$
|
|
72
|
+
- 🤖 **LLM usage:** $7.5000 (206 commits)
|
|
73
|
+
- 👤 **Human dev:** ~$7734 (77.3h @ $100/h, 30min dedup)
|
|
74
74
|
|
|
75
|
-
Generated on 2026-05-
|
|
75
|
+
Generated on 2026-05-24 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
76
76
|
|
|
77
77
|
---
|
|
78
78
|
|
|
@@ -88,6 +88,7 @@ When you run `code2llm ./ -f all`, the following files are created:
|
|
|
88
88
|
|
|
89
89
|
| File | Format | Purpose | Key Insights |
|
|
90
90
|
|------|--------|---------|--------------|
|
|
91
|
+
| `planfile-tickets.yaml` | **YAML** | **🎫 Koru-ready ticket feed** - Actionable planfile suggestions from code2llm findings | Import or apply tickets for autonomous execution |
|
|
91
92
|
| `evolution.toon.yaml` | **YAML** | **📋 Refactoring queue** - Prioritized improvements | 0 refactoring actions needed |
|
|
92
93
|
| `map.toon.yaml` | **YAML** | **🗺️ Structural map + project header** - Modules, imports, exports, signatures, stats, alerts, hotspots, trend | Project architecture overview |
|
|
93
94
|
|
|
@@ -113,6 +114,12 @@ code2llm ./ -f toon
|
|
|
113
114
|
# Generate all formats (what created these files)
|
|
114
115
|
code2llm ./ -f all
|
|
115
116
|
|
|
117
|
+
# Generate planfile suggestions and create executable tickets for Koru
|
|
118
|
+
code2llm ./ -f all -o ./project --no-chunk --planfile-apply
|
|
119
|
+
|
|
120
|
+
# Or import the generated manifest later
|
|
121
|
+
planfile ticket import --from ./project/planfile-tickets.yaml --source code2llm
|
|
122
|
+
|
|
116
123
|
# LLM-ready context only
|
|
117
124
|
code2llm ./ -f context
|
|
118
125
|
```
|
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## AI Cost Tracking
|
|
4
4
|
|
|
5
|
-
     
|
|
6
|
+
  
|
|
7
7
|
|
|
8
|
-
- 🤖 **LLM usage:** $7.5000 (
|
|
9
|
-
- 👤 **Human dev:** ~$
|
|
8
|
+
- 🤖 **LLM usage:** $7.5000 (206 commits)
|
|
9
|
+
- 👤 **Human dev:** ~$7734 (77.3h @ $100/h, 30min dedup)
|
|
10
10
|
|
|
11
|
-
Generated on 2026-05-
|
|
11
|
+
Generated on 2026-05-24 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -24,6 +24,7 @@ When you run `code2llm ./ -f all`, the following files are created:
|
|
|
24
24
|
|
|
25
25
|
| File | Format | Purpose | Key Insights |
|
|
26
26
|
|------|--------|---------|--------------|
|
|
27
|
+
| `planfile-tickets.yaml` | **YAML** | **🎫 Koru-ready ticket feed** - Actionable planfile suggestions from code2llm findings | Import or apply tickets for autonomous execution |
|
|
27
28
|
| `evolution.toon.yaml` | **YAML** | **📋 Refactoring queue** - Prioritized improvements | 0 refactoring actions needed |
|
|
28
29
|
| `map.toon.yaml` | **YAML** | **🗺️ Structural map + project header** - Modules, imports, exports, signatures, stats, alerts, hotspots, trend | Project architecture overview |
|
|
29
30
|
|
|
@@ -49,6 +50,12 @@ code2llm ./ -f toon
|
|
|
49
50
|
# Generate all formats (what created these files)
|
|
50
51
|
code2llm ./ -f all
|
|
51
52
|
|
|
53
|
+
# Generate planfile suggestions and create executable tickets for Koru
|
|
54
|
+
code2llm ./ -f all -o ./project --no-chunk --planfile-apply
|
|
55
|
+
|
|
56
|
+
# Or import the generated manifest later
|
|
57
|
+
planfile ticket import --from ./project/planfile-tickets.yaml --source code2llm
|
|
58
|
+
|
|
52
59
|
# LLM-ready context only
|
|
53
60
|
code2llm ./ -f context
|
|
54
61
|
```
|
code2llm-0.5.153/VERSION
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.5.153
|
|
@@ -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.153"
|
|
12
12
|
__author__ = "STTS Project"
|
|
13
13
|
|
|
14
14
|
# Core analysis components (lightweight, always needed)
|
|
@@ -39,14 +39,21 @@ def __getattr__(name):
|
|
|
39
39
|
"""Lazy import heavy modules on first access."""
|
|
40
40
|
if name == "ProjectAnalyzer":
|
|
41
41
|
from .core.analyzer import ProjectAnalyzer
|
|
42
|
+
|
|
42
43
|
return ProjectAnalyzer
|
|
43
|
-
|
|
44
|
+
|
|
44
45
|
_nlp_names = {
|
|
45
|
-
"NLPPipeline",
|
|
46
|
-
"
|
|
46
|
+
"NLPPipeline",
|
|
47
|
+
"QueryNormalizer",
|
|
48
|
+
"IntentMatcher",
|
|
49
|
+
"EntityResolver",
|
|
50
|
+
"NLPConfig",
|
|
51
|
+
"FAST_NLP_CONFIG",
|
|
52
|
+
"PRECISE_NLP_CONFIG",
|
|
47
53
|
}
|
|
48
54
|
if name in _nlp_names:
|
|
49
55
|
from . import nlp
|
|
56
|
+
|
|
50
57
|
return getattr(nlp, name)
|
|
51
|
-
|
|
58
|
+
|
|
52
59
|
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Analysis package for code2llm."""
|
|
2
|
+
|
|
3
|
+
__all__ = [
|
|
4
|
+
"CFGExtractor",
|
|
5
|
+
"DFGExtractor",
|
|
6
|
+
"CallGraphExtractor",
|
|
7
|
+
"CouplingAnalyzer",
|
|
8
|
+
"SmellDetector",
|
|
9
|
+
"DataAnalyzer",
|
|
10
|
+
"TypeInferenceEngine",
|
|
11
|
+
"SideEffectDetector",
|
|
12
|
+
"PipelineDetector",
|
|
13
|
+
"PipelineResolver",
|
|
14
|
+
"PipelineClassifier",
|
|
15
|
+
]
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def __getattr__(name):
|
|
19
|
+
"""Lazy import analysis modules on first access."""
|
|
20
|
+
_imports = {
|
|
21
|
+
"CFGExtractor": ".cfg",
|
|
22
|
+
"DFGExtractor": ".dfg",
|
|
23
|
+
"CallGraphExtractor": ".call_graph",
|
|
24
|
+
"CouplingAnalyzer": ".coupling",
|
|
25
|
+
"SmellDetector": ".smells",
|
|
26
|
+
"DataAnalyzer": ".data_analysis",
|
|
27
|
+
"TypeInferenceEngine": ".type_inference",
|
|
28
|
+
"SideEffectDetector": ".side_effects",
|
|
29
|
+
"PipelineDetector": ".pipeline_detector",
|
|
30
|
+
"PipelineResolver": ".pipeline_resolver",
|
|
31
|
+
"PipelineClassifier": ".pipeline_classifier",
|
|
32
|
+
}
|
|
33
|
+
if name in _imports:
|
|
34
|
+
import importlib
|
|
35
|
+
|
|
36
|
+
module = importlib.import_module(_imports[name], __package__)
|
|
37
|
+
return getattr(module, name)
|
|
38
|
+
raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
|
|
@@ -10,20 +10,22 @@ from code2llm.analysis.utils import ast_unparse, qualified_name
|
|
|
10
10
|
|
|
11
11
|
class CallGraphExtractor(ast.NodeVisitor):
|
|
12
12
|
"""Extract call graph from AST."""
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
def __init__(self, config: Config):
|
|
15
15
|
self.config = config
|
|
16
16
|
self.result = AnalysisResult()
|
|
17
17
|
self.module_name = ""
|
|
18
18
|
self.file_path = ""
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
# Context
|
|
21
21
|
self.function_stack = []
|
|
22
22
|
self.class_stack = []
|
|
23
23
|
self.imports = {}
|
|
24
24
|
self.astroid_tree = None
|
|
25
|
-
|
|
26
|
-
def extract(
|
|
25
|
+
|
|
26
|
+
def extract(
|
|
27
|
+
self, tree: ast.AST, module_name: str, file_path: str
|
|
28
|
+
) -> AnalysisResult:
|
|
27
29
|
"""Extract call graph from AST."""
|
|
28
30
|
self.result = AnalysisResult()
|
|
29
31
|
self.module_name = module_name
|
|
@@ -31,14 +33,15 @@ class CallGraphExtractor(ast.NodeVisitor):
|
|
|
31
33
|
self.function_stack = []
|
|
32
34
|
self.class_stack = []
|
|
33
35
|
self.imports = {}
|
|
34
|
-
|
|
36
|
+
|
|
35
37
|
# Try to get astroid tree for better resolution (lazy import - heavy module)
|
|
36
38
|
try:
|
|
37
39
|
import astroid as _astroid
|
|
40
|
+
|
|
38
41
|
self.astroid_tree = _astroid.MANAGER.ast_from_file(file_path)
|
|
39
42
|
except Exception:
|
|
40
43
|
self.astroid_tree = None
|
|
41
|
-
|
|
44
|
+
|
|
42
45
|
self.visit(tree)
|
|
43
46
|
self._calculate_metrics()
|
|
44
47
|
return self.result
|
|
@@ -55,20 +58,22 @@ class CallGraphExtractor(ast.NodeVisitor):
|
|
|
55
58
|
for func_name, func_info in self.result.functions.items():
|
|
56
59
|
fan_out = len(set(func_info.calls))
|
|
57
60
|
fan_in = len(set(func_info.called_by))
|
|
58
|
-
|
|
61
|
+
|
|
59
62
|
self.result.metrics[func_name] = {
|
|
60
63
|
"fan_in": fan_in,
|
|
61
64
|
"fan_out": fan_out,
|
|
62
|
-
"complexity": getattr(
|
|
65
|
+
"complexity": getattr(
|
|
66
|
+
func_info, "complexity", 1
|
|
67
|
+
), # Placeholder for now
|
|
63
68
|
}
|
|
64
|
-
|
|
69
|
+
|
|
65
70
|
def visit_Import(self, node: ast.Import):
|
|
66
71
|
"""Track imports."""
|
|
67
72
|
for alias in node.names:
|
|
68
73
|
name = alias.asname if alias.asname else alias.name
|
|
69
74
|
self.imports[name] = alias.name
|
|
70
75
|
self.result.imports[name] = alias.name
|
|
71
|
-
|
|
76
|
+
|
|
72
77
|
def visit_ImportFrom(self, node: ast.ImportFrom):
|
|
73
78
|
"""Track from imports."""
|
|
74
79
|
module = node.module or ""
|
|
@@ -77,68 +82,68 @@ class CallGraphExtractor(ast.NodeVisitor):
|
|
|
77
82
|
full_name = f"{module}.{alias.name}" if module else alias.name
|
|
78
83
|
self.imports[name] = full_name
|
|
79
84
|
self.result.imports[name] = full_name
|
|
80
|
-
|
|
85
|
+
|
|
81
86
|
def visit_ClassDef(self, node: ast.ClassDef):
|
|
82
87
|
"""Visit class definition."""
|
|
83
88
|
self.class_stack.append(node.name)
|
|
84
|
-
|
|
89
|
+
|
|
85
90
|
# Store class info
|
|
86
91
|
self.result.classes[node.name] = {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
"file": self.file_path,
|
|
93
|
+
"line": node.lineno,
|
|
94
|
+
"methods": [m.name for m in node.body if isinstance(m, ast.FunctionDef)],
|
|
95
|
+
"bases": [self._expr_to_str(b) for b in node.bases],
|
|
91
96
|
}
|
|
92
|
-
|
|
97
|
+
|
|
93
98
|
for stmt in node.body:
|
|
94
99
|
self.visit(stmt)
|
|
95
|
-
|
|
100
|
+
|
|
96
101
|
self.class_stack.pop()
|
|
97
|
-
|
|
102
|
+
|
|
98
103
|
def visit_FunctionDef(self, node: ast.FunctionDef):
|
|
99
104
|
"""Visit function definition and track calls within it."""
|
|
100
105
|
func_name = qualified_name(self.module_name, self.class_stack, node.name)
|
|
101
106
|
self.function_stack.append(func_name)
|
|
102
|
-
|
|
107
|
+
|
|
103
108
|
# Visit body to find calls
|
|
104
109
|
for stmt in node.body:
|
|
105
110
|
self.visit(stmt)
|
|
106
|
-
|
|
111
|
+
|
|
107
112
|
self.function_stack.pop()
|
|
108
|
-
|
|
113
|
+
|
|
109
114
|
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef):
|
|
110
115
|
"""Visit async function."""
|
|
111
116
|
self.visit_FunctionDef(node)
|
|
112
|
-
|
|
117
|
+
|
|
113
118
|
def visit_Call(self, node: ast.Call):
|
|
114
119
|
"""Track function calls."""
|
|
115
120
|
if not self.function_stack:
|
|
116
121
|
self.generic_visit(node)
|
|
117
122
|
return
|
|
118
|
-
|
|
123
|
+
|
|
119
124
|
caller = self.function_stack[-1]
|
|
120
125
|
callee = self._resolve_call(node.func)
|
|
121
|
-
|
|
126
|
+
|
|
122
127
|
# If ast-based resolution failed or returned None.sth, try astroid
|
|
123
|
-
if (not callee or
|
|
128
|
+
if (not callee or "None." in callee) and self.astroid_tree:
|
|
124
129
|
astroid_callee = self._resolve_with_astroid(node)
|
|
125
130
|
if astroid_callee:
|
|
126
131
|
callee = astroid_callee
|
|
127
|
-
|
|
132
|
+
|
|
128
133
|
if callee and caller in self.result.functions:
|
|
129
134
|
self.result.functions[caller].calls.append(callee)
|
|
130
|
-
|
|
135
|
+
|
|
131
136
|
# Create call edge
|
|
132
137
|
edge = FlowEdge(
|
|
133
138
|
source=-1, # Will be resolved
|
|
134
139
|
target=-1,
|
|
135
140
|
edge_type="call",
|
|
136
|
-
metadata={
|
|
141
|
+
metadata={"caller": caller, "callee": callee},
|
|
137
142
|
)
|
|
138
143
|
self.result.call_edges.append(edge)
|
|
139
|
-
|
|
144
|
+
|
|
140
145
|
self.generic_visit(node)
|
|
141
|
-
|
|
146
|
+
|
|
142
147
|
def _resolve_call(self, node: ast.AST) -> Optional[str]:
|
|
143
148
|
"""Resolve a call to its full name."""
|
|
144
149
|
if isinstance(node, ast.Name):
|
|
@@ -146,53 +151,57 @@ class CallGraphExtractor(ast.NodeVisitor):
|
|
|
146
151
|
if node.id in self.imports:
|
|
147
152
|
return self.imports[node.id]
|
|
148
153
|
return f"{self.module_name}.{node.id}"
|
|
149
|
-
|
|
154
|
+
|
|
150
155
|
elif isinstance(node, ast.Attribute):
|
|
151
156
|
# Method or module.function call
|
|
152
157
|
parts = []
|
|
153
158
|
current = node
|
|
154
|
-
|
|
159
|
+
|
|
155
160
|
while isinstance(current, ast.Attribute):
|
|
156
161
|
parts.append(current.attr)
|
|
157
162
|
current = current.value
|
|
158
|
-
|
|
163
|
+
|
|
159
164
|
if isinstance(current, ast.Name):
|
|
160
165
|
parts.append(current.id)
|
|
161
166
|
parts.reverse()
|
|
162
|
-
|
|
167
|
+
|
|
163
168
|
# Check if root is an import
|
|
164
169
|
root = parts[0]
|
|
165
170
|
if root in self.imports:
|
|
166
171
|
return f"{self.imports[root]}.{'.'.join(parts[1:])}"
|
|
167
|
-
|
|
172
|
+
|
|
168
173
|
# Check for self/cls
|
|
169
|
-
if root in (
|
|
174
|
+
if root in ("self", "cls") and self.class_stack:
|
|
170
175
|
return f"{self.module_name}.{self.class_stack[-1]}.{'.'.join(parts[1:])}"
|
|
171
|
-
|
|
176
|
+
|
|
172
177
|
return f"{self.module_name}.{'.'.join(parts)}"
|
|
173
|
-
|
|
178
|
+
|
|
174
179
|
return None
|
|
175
180
|
|
|
176
181
|
def _resolve_with_astroid(self, node: ast.Call) -> Optional[str]:
|
|
177
182
|
"""Use astroid to infer the call target."""
|
|
178
183
|
if not self.astroid_tree:
|
|
179
184
|
return None
|
|
180
|
-
|
|
185
|
+
|
|
181
186
|
try:
|
|
182
187
|
# Find the corresponding astroid node by line/col
|
|
183
188
|
# This is a bit slow but robust
|
|
184
189
|
import astroid as _astroid
|
|
190
|
+
|
|
185
191
|
for astroid_node in self.astroid_tree.nodes_of_class(_astroid.Call):
|
|
186
|
-
if
|
|
192
|
+
if (
|
|
193
|
+
astroid_node.lineno == node.lineno
|
|
194
|
+
and astroid_node.col_offset == node.col_offset
|
|
195
|
+
):
|
|
187
196
|
# Infer the targets
|
|
188
197
|
inferred = astroid_node.func.infer()
|
|
189
198
|
for target in inferred:
|
|
190
|
-
if hasattr(target,
|
|
199
|
+
if hasattr(target, "qname"):
|
|
191
200
|
return target.qname()
|
|
192
201
|
break
|
|
193
202
|
except Exception:
|
|
194
203
|
pass
|
|
195
204
|
return None
|
|
196
|
-
|
|
205
|
+
|
|
197
206
|
def _expr_to_str(self, node: ast.AST) -> str:
|
|
198
207
|
return ast_unparse(node, default_none="")
|