code2llm 0.5.169__tar.gz → 0.5.172__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.
Files changed (209) hide show
  1. {code2llm-0.5.169/code2llm.egg-info → code2llm-0.5.172}/PKG-INFO +9 -6
  2. {code2llm-0.5.169 → code2llm-0.5.172}/README.md +5 -3
  3. code2llm-0.5.172/VERSION +1 -0
  4. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/__init__.py +1 -1
  5. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/smells.py +26 -8
  6. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/file_filter.py +0 -5
  7. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/nlp/__init__.py +1 -1
  8. {code2llm-0.5.169 → code2llm-0.5.172/code2llm.egg-info}/PKG-INFO +9 -6
  9. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm.egg-info/SOURCES.txt +1 -0
  10. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm.egg-info/requires.txt +1 -0
  11. {code2llm-0.5.169 → code2llm-0.5.172}/pyproject.toml +4 -5
  12. {code2llm-0.5.169 → code2llm-0.5.172}/setup.py +2 -2
  13. code2llm-0.5.172/tests/test_smells_shotgun_surgery.py +97 -0
  14. code2llm-0.5.169/VERSION +0 -1
  15. {code2llm-0.5.169 → code2llm-0.5.172}/LICENSE +0 -0
  16. {code2llm-0.5.169 → code2llm-0.5.172}/MANIFEST.in +0 -0
  17. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/__main__.py +0 -0
  18. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/__init__.py +0 -0
  19. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/_data_impl.py +0 -0
  20. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/call_graph.py +0 -0
  21. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/cfg.py +0 -0
  22. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/coupling.py +0 -0
  23. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/data_analysis.py +0 -0
  24. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/dfg.py +0 -0
  25. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/pipeline_classifier.py +0 -0
  26. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/pipeline_detector.py +0 -0
  27. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/pipeline_resolver.py +0 -0
  28. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/side_effects.py +0 -0
  29. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/type_inference.py +0 -0
  30. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/utils/__init__.py +0 -0
  31. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/analysis/utils/ast_helpers.py +0 -0
  32. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/api.py +0 -0
  33. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli.py +0 -0
  34. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_analysis.py +0 -0
  35. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_commands.py +0 -0
  36. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_exports/__init__.py +0 -0
  37. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_exports/code2logic.py +0 -0
  38. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_exports/formats.py +0 -0
  39. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_exports/orchestrator.py +0 -0
  40. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_exports/orchestrator_chunked.py +0 -0
  41. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_exports/orchestrator_constants.py +0 -0
  42. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_exports/orchestrator_handlers.py +0 -0
  43. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_exports/prompt.py +0 -0
  44. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/cli_parser.py +0 -0
  45. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/__init__.py +0 -0
  46. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/analyzer.py +0 -0
  47. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/ast_registry.py +0 -0
  48. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/config.py +0 -0
  49. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/export_pipeline.py +0 -0
  50. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/file_analyzer.py +0 -0
  51. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/file_cache.py +0 -0
  52. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/gitignore.py +0 -0
  53. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/incremental.py +0 -0
  54. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/__init__.py +0 -0
  55. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/_c_parser.py +0 -0
  56. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/_calls.py +0 -0
  57. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/_complexity.py +0 -0
  58. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/base.py +0 -0
  59. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/cpp.py +0 -0
  60. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/csharp.py +0 -0
  61. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/generic.py +0 -0
  62. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/go_lang.py +0 -0
  63. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/java.py +0 -0
  64. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/php.py +0 -0
  65. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/ruby.py +0 -0
  66. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/rust.py +0 -0
  67. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/ts_extractors.py +0 -0
  68. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/ts_parser.py +0 -0
  69. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/lang/typescript.py +0 -0
  70. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/large_repo.py +0 -0
  71. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/models.py +0 -0
  72. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/persistent_cache.py +0 -0
  73. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/refactoring.py +0 -0
  74. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/repo_files.py +0 -0
  75. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/source_classifier.py +0 -0
  76. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/streaming/__init__.py +0 -0
  77. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/streaming/cache.py +0 -0
  78. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/streaming/incremental.py +0 -0
  79. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/streaming/prioritizer.py +0 -0
  80. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/streaming/scanner.py +0 -0
  81. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/streaming/strategies.py +0 -0
  82. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/streaming_analyzer.py +0 -0
  83. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/core/toon_size_manager.py +0 -0
  84. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/__init__.py +0 -0
  85. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/article_view.py +0 -0
  86. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/base.py +0 -0
  87. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/context_exporter.py +0 -0
  88. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/context_view.py +0 -0
  89. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/dashboard_data.py +0 -0
  90. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/dashboard_renderer.py +0 -0
  91. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/evolution/__init__.py +0 -0
  92. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/evolution/computation.py +0 -0
  93. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/evolution/constants.py +0 -0
  94. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/evolution/exclusion.py +0 -0
  95. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/evolution/render.py +0 -0
  96. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/evolution/yaml_export.py +0 -0
  97. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/evolution_exporter.py +0 -0
  98. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/flow_constants.py +0 -0
  99. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/flow_exporter.py +0 -0
  100. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/flow_renderer.py +0 -0
  101. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/html_dashboard.py +0 -0
  102. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/index_generator/__init__.py +0 -0
  103. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/index_generator/renderer.py +0 -0
  104. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/index_generator/scanner.py +0 -0
  105. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/index_generator.py +0 -0
  106. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/json_exporter.py +0 -0
  107. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/llm_exporter.py +0 -0
  108. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/map/__init__.py +0 -0
  109. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/map/alerts.py +0 -0
  110. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/map/details.py +0 -0
  111. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/map/header.py +0 -0
  112. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/map/module_list.py +0 -0
  113. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/map/utils.py +0 -0
  114. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/map/yaml_export.py +0 -0
  115. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/map_exporter.py +0 -0
  116. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/mermaid/__init__.py +0 -0
  117. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/mermaid/calls.py +0 -0
  118. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/mermaid/classic.py +0 -0
  119. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/mermaid/compact.py +0 -0
  120. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/mermaid/flow_compact.py +0 -0
  121. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/mermaid/flow_detailed.py +0 -0
  122. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/mermaid/flow_full.py +0 -0
  123. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/mermaid/utils.py +0 -0
  124. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/mermaid_exporter.py +0 -0
  125. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/mermaid_flow_helpers.py +0 -0
  126. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/planfile_tickets.py +0 -0
  127. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/project_yaml/__init__.py +0 -0
  128. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/project_yaml/constants.py +0 -0
  129. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/project_yaml/core.py +0 -0
  130. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/project_yaml/evolution.py +0 -0
  131. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/project_yaml/health.py +0 -0
  132. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/project_yaml/hotspots.py +0 -0
  133. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/project_yaml/modules.py +0 -0
  134. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/project_yaml_exporter.py +0 -0
  135. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/readme/__init__.py +0 -0
  136. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/readme/content.py +0 -0
  137. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/readme/files.py +0 -0
  138. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/readme/insights.py +0 -0
  139. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/readme/sections.py +0 -0
  140. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/readme_exporter.py +0 -0
  141. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/report_generators.py +0 -0
  142. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/__init__.py +0 -0
  143. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/_render_coupling_helpers.py +0 -0
  144. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/_render_section_helpers.py +0 -0
  145. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/constants.py +0 -0
  146. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/helpers.py +0 -0
  147. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/metrics.py +0 -0
  148. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/metrics_core.py +0 -0
  149. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/metrics_duplicates.py +0 -0
  150. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/metrics_health.py +0 -0
  151. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/module_detail.py +0 -0
  152. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon/renderer.py +0 -0
  153. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon.py +0 -0
  154. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/toon_view.py +0 -0
  155. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/validate_project.py +0 -0
  156. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/exporters/yaml_exporter.py +0 -0
  157. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/__init__.py +0 -0
  158. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/_utils.py +0 -0
  159. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/llm_flow/__init__.py +0 -0
  160. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/llm_flow/analysis.py +0 -0
  161. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/llm_flow/cli.py +0 -0
  162. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/llm_flow/generator.py +0 -0
  163. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/llm_flow/nodes.py +0 -0
  164. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/llm_flow/parsing.py +0 -0
  165. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/llm_flow/utils.py +0 -0
  166. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/llm_flow.py +0 -0
  167. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/llm_task.py +0 -0
  168. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/mermaid/__init__.py +0 -0
  169. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/mermaid/fix.py +0 -0
  170. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/mermaid/png.py +0 -0
  171. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/mermaid/validation.py +0 -0
  172. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/generators/mermaid.py +0 -0
  173. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/nlp/config.py +0 -0
  174. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/nlp/entity_resolution.py +0 -0
  175. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/nlp/intent_matching.py +0 -0
  176. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/nlp/normalization.py +0 -0
  177. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/nlp/pipeline.py +0 -0
  178. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/parsers/toon_parser.py +0 -0
  179. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/patterns/__init__.py +0 -0
  180. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/patterns/detector.py +0 -0
  181. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/refactor/__init__.py +0 -0
  182. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm/refactor/prompt_engine.py +0 -0
  183. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm.egg-info/dependency_links.txt +0 -0
  184. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm.egg-info/entry_points.txt +0 -0
  185. {code2llm-0.5.169 → code2llm-0.5.172}/code2llm.egg-info/top_level.txt +0 -0
  186. {code2llm-0.5.169 → code2llm-0.5.172}/setup.cfg +0 -0
  187. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_advanced_analysis.py +0 -0
  188. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_analyzer.py +0 -0
  189. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_cache_invalidation_e2e.py +0 -0
  190. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_calls_toon_export.py +0 -0
  191. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_declarative_collection.py +0 -0
  192. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_deep_analysis.py +0 -0
  193. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_edge_cases.py +0 -0
  194. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_export_cache_flags.py +0 -0
  195. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_file_analyzer_tagging.py +0 -0
  196. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_flow_exporter.py +0 -0
  197. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_format_quality.py +0 -0
  198. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_multilanguage_e2e.py +0 -0
  199. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_nlp_pipeline.py +0 -0
  200. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_nonpython_cc_calls.py +0 -0
  201. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_orchestrator_cache_mtime.py +0 -0
  202. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_persistent_cache.py +0 -0
  203. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_pipeline_detector.py +0 -0
  204. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_planfile_tickets_exporter.py +0 -0
  205. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_project_toon_export.py +0 -0
  206. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_prompt_engine.py +0 -0
  207. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_prompt_txt.py +0 -0
  208. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_refactoring_engine.py +0 -0
  209. {code2llm-0.5.169 → code2llm-0.5.172}/tests/test_toon_v2.py +0 -0
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code2llm
3
- Version: 0.5.169
3
+ Version: 0.5.172
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
- Author: STTS Project
6
+ Author: Tom Sapletta
7
7
  Author-email: Tom Sapletta <tom@sapletta.com>
8
- License: Apache-2.0
8
+ License-Expression: Apache-2.0
9
9
  Project-URL: Homepage, https://github.com/wronai/stts
10
10
  Project-URL: Repository, https://github.com/wronai/stts
11
11
  Project-URL: Issues, https://github.com/wronai/stts/issues
@@ -32,6 +32,7 @@ Requires-Dist: numpy>=1.20
32
32
  Requires-Dist: jinja2>=3.0
33
33
  Requires-Dist: radon>=5.1
34
34
  Requires-Dist: astroid>=3.0
35
+ Requires-Dist: psutil>=5.9
35
36
  Requires-Dist: code2logic
36
37
  Requires-Dist: vulture>=2.10
37
38
  Requires-Dist: tiktoken>=0.5
@@ -66,11 +67,13 @@ Dynamic: requires-python
66
67
 
67
68
  ## AI Cost Tracking
68
69
 
69
- ![AI Cost](https://img.shields.io/badge/AI%20Cost-$7.50-yellow) ![AI Model](https://img.shields.io/badge/AI%20Model-openrouter%2Fdeep%2Fdeep-v4-pro-lightgrey)
70
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.5.172-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
71
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$17.33-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-92.8h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fdeep%2Fdeep--v4--pro-lightgrey)
70
72
 
71
- This project uses AI-generated code. Total cost: **$7.5000** with **243** AI commits.
73
+ - 🤖 **LLM usage:** $17.3260 (246 commits)
74
+ - 👤 **Human dev:** ~$9280 (92.8h @ $100/h, 30min dedup)
72
75
 
73
- Generated on 2026-06-29 using [openrouter/deep/deep-v4-pro](https://openrouter.ai/models/openrouter/deep/deep-v4-pro)
76
+ Generated on 2026-07-06 using [openrouter/deep/deep-v4-pro](https://openrouter.ai/deep/deep-v4-pro)
74
77
 
75
78
  ---
76
79
 
@@ -2,11 +2,13 @@
2
2
 
3
3
  ## AI Cost Tracking
4
4
 
5
- ![AI Cost](https://img.shields.io/badge/AI%20Cost-$7.50-yellow) ![AI Model](https://img.shields.io/badge/AI%20Model-openrouter%2Fdeep%2Fdeep-v4-pro-lightgrey)
5
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.5.172-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
6
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$17.33-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-92.8h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fdeep%2Fdeep--v4--pro-lightgrey)
6
7
 
7
- This project uses AI-generated code. Total cost: **$7.5000** with **243** AI commits.
8
+ - 🤖 **LLM usage:** $17.3260 (246 commits)
9
+ - 👤 **Human dev:** ~$9280 (92.8h @ $100/h, 30min dedup)
8
10
 
9
- Generated on 2026-06-29 using [openrouter/deep/deep-v4-pro](https://openrouter.ai/models/openrouter/deep/deep-v4-pro)
11
+ Generated on 2026-07-06 using [openrouter/deep/deep-v4-pro](https://openrouter.ai/deep/deep-v4-pro)
10
12
 
11
13
  ---
12
14
 
@@ -0,0 +1 @@
1
+ 0.5.172
@@ -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.169"
11
+ __version__ = "0.5.172"
12
12
  __author__ = "STTS Project"
13
13
 
14
14
  # Core analysis components (lightweight, always needed)
@@ -163,16 +163,33 @@ class SmellDetector:
163
163
  return smells
164
164
 
165
165
  def _detect_shotgun_surgery(self) -> List[CodeSmell]:
166
- """Detect variables whose mutation requires changes across many functions."""
166
+ """Detect variables whose mutation requires changes across many functions.
167
+
168
+ Grouped by (file, variable), not variable name alone: a generic local
169
+ name like `args`, `data`, or `client` is conventionally reused as an
170
+ independent local in unrelated functions across unrelated files/
171
+ packages (every argparse `main()` has an `args`) -- that's naming
172
+ coincidence, not a variable whose logic is genuinely coupled across
173
+ call sites. Grouping by bare name alone falsely flagged every such
174
+ coincidence as "shotgun surgery" (reproduced: 40+ false-positive
175
+ tickets in a single monorepo, e.g. `args` in a 40-line, one-function
176
+ CLI file reported as "spans 8 functions" -- the other 7 were
177
+ unrelated `args` locals in unrelated files elsewhere in the tree).
178
+ Real shotgun surgery -- one variable/attribute whose change genuinely
179
+ ripples across many functions -- is a same-file (or same-class)
180
+ phenomenon; scoping by file preserves that signal while dropping the
181
+ cross-file name-collision noise.
182
+ """
167
183
  smells = []
168
- var_mutators = {} # variable -> set(functions)
184
+ var_mutators = {} # (file, variable) -> set(functions)
169
185
 
170
186
  for mutation in self.result.mutations:
171
- if mutation.variable not in var_mutators:
172
- var_mutators[mutation.variable] = set()
173
- var_mutators[mutation.variable].add(mutation.scope)
187
+ key = (mutation.file, mutation.variable)
188
+ if key not in var_mutators:
189
+ var_mutators[key] = set()
190
+ var_mutators[key].add(mutation.scope)
174
191
 
175
- for var, funcs in var_mutators.items():
192
+ for (file, var), funcs in var_mutators.items():
176
193
  if len(funcs) >= 5:
177
194
  # Find a representative function to report the smell
178
195
  func_name = list(funcs)[0]
@@ -188,10 +205,11 @@ class SmellDetector:
188
205
  line=func_info.line,
189
206
  severity=0.8,
190
207
  description=(
191
- f"Mutation of variable '{var}' spans {len(funcs)} functions."
208
+ f"Mutation of variable '{var}' spans {len(funcs)} functions"
209
+ f" in {file}."
192
210
  " Changing this logic requires work in many places."
193
211
  ),
194
- context={"variable": var, "affected_functions": list(funcs)},
212
+ context={"variable": var, "file": file, "affected_functions": list(funcs)},
195
213
  )
196
214
  )
197
215
  return smells
@@ -42,12 +42,7 @@ _SKIP_DIR_NAMES = (
42
42
  "htmlcov",
43
43
  ".coverage",
44
44
  ".cache",
45
- "lib",
46
- "lib64",
47
45
  "site-packages",
48
- "include",
49
- "bin",
50
- "share",
51
46
  ".code2llm_cache",
52
47
  "tests",
53
48
  "test",
@@ -4,7 +4,7 @@ Provides query normalization, intent matching, and entity resolution
4
4
  with multilingual support and fuzzy matching.
5
5
  """
6
6
 
7
- __version__ = "0.5.169"
7
+ __version__ = "0.5.172"
8
8
 
9
9
  from .pipeline import NLPPipeline
10
10
  from .normalization import QueryNormalizer
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code2llm
3
- Version: 0.5.169
3
+ Version: 0.5.172
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
- Author: STTS Project
6
+ Author: Tom Sapletta
7
7
  Author-email: Tom Sapletta <tom@sapletta.com>
8
- License: Apache-2.0
8
+ License-Expression: Apache-2.0
9
9
  Project-URL: Homepage, https://github.com/wronai/stts
10
10
  Project-URL: Repository, https://github.com/wronai/stts
11
11
  Project-URL: Issues, https://github.com/wronai/stts/issues
@@ -32,6 +32,7 @@ Requires-Dist: numpy>=1.20
32
32
  Requires-Dist: jinja2>=3.0
33
33
  Requires-Dist: radon>=5.1
34
34
  Requires-Dist: astroid>=3.0
35
+ Requires-Dist: psutil>=5.9
35
36
  Requires-Dist: code2logic
36
37
  Requires-Dist: vulture>=2.10
37
38
  Requires-Dist: tiktoken>=0.5
@@ -66,11 +67,13 @@ Dynamic: requires-python
66
67
 
67
68
  ## AI Cost Tracking
68
69
 
69
- ![AI Cost](https://img.shields.io/badge/AI%20Cost-$7.50-yellow) ![AI Model](https://img.shields.io/badge/AI%20Model-openrouter%2Fdeep%2Fdeep-v4-pro-lightgrey)
70
+ ![PyPI](https://img.shields.io/badge/pypi-costs-blue) ![Version](https://img.shields.io/badge/version-0.5.172-blue) ![Python](https://img.shields.io/badge/python-3.9+-blue) ![License](https://img.shields.io/badge/license-Apache--2.0-green)
71
+ ![AI Cost](https://img.shields.io/badge/AI%20Cost-$17.33-orange) ![Human Time](https://img.shields.io/badge/Human%20Time-92.8h-blue) ![Model](https://img.shields.io/badge/Model-openrouter%2Fdeep%2Fdeep--v4--pro-lightgrey)
70
72
 
71
- This project uses AI-generated code. Total cost: **$7.5000** with **243** AI commits.
73
+ - 🤖 **LLM usage:** $17.3260 (246 commits)
74
+ - 👤 **Human dev:** ~$9280 (92.8h @ $100/h, 30min dedup)
72
75
 
73
- Generated on 2026-06-29 using [openrouter/deep/deep-v4-pro](https://openrouter.ai/models/openrouter/deep/deep-v4-pro)
76
+ Generated on 2026-07-06 using [openrouter/deep/deep-v4-pro](https://openrouter.ai/deep/deep-v4-pro)
74
77
 
75
78
  ---
76
79
 
@@ -202,4 +202,5 @@ tests/test_project_toon_export.py
202
202
  tests/test_prompt_engine.py
203
203
  tests/test_prompt_txt.py
204
204
  tests/test_refactoring_engine.py
205
+ tests/test_smells_shotgun_surgery.py
205
206
  tests/test_toon_v2.py
@@ -5,6 +5,7 @@ numpy>=1.20
5
5
  jinja2>=3.0
6
6
  radon>=5.1
7
7
  astroid>=3.0
8
+ psutil>=5.9
8
9
  code2logic
9
10
  vulture>=2.10
10
11
  tiktoken>=0.5
@@ -4,10 +4,10 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code2llm"
7
- version = "0.5.169"
7
+ version = "0.5.172"
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
- requires-python = ">=3.8"
10
+ requires-python = ">=3.10"
11
11
  authors = [
12
12
  {name = "Tom Sapletta", email = "tom@sapletta.com"},
13
13
  ]
@@ -45,6 +45,7 @@ dependencies = [
45
45
  "jinja2>=3.0",
46
46
  "radon>=5.1",
47
47
  "astroid>=3.0",
48
+ "psutil>=5.9",
48
49
  "code2logic",
49
50
  "vulture>=2.10",
50
51
  "tiktoken>=0.5",
@@ -62,9 +63,7 @@ dependencies = [
62
63
  "tree-sitter-ruby>=0.21",
63
64
  ]
64
65
 
65
- [project.license]
66
- text = "Apache-2.0"
67
-
66
+ license = "Apache-2.0"
68
67
  [project.optional-dependencies]
69
68
  dev = [
70
69
  "pytest>=6.2",
@@ -29,8 +29,8 @@ setup(
29
29
  description="Python code flow analysis tool - CFG, DFG, and call graph extraction",
30
30
  long_description=read_readme(),
31
31
  long_description_content_type="text/markdown",
32
- author="STTS Project",
33
- author_email="",
32
+ author="Tom Sapletta",
33
+ author_email="tom@sapletta.com",
34
34
  url="https://github.com/wronai/stts",
35
35
  packages=find_packages(),
36
36
  entry_points={
@@ -0,0 +1,97 @@
1
+ """Tests for SmellDetector._detect_shotgun_surgery.
2
+
3
+ 2026-07-06 incident: grouping mutations by variable *name* alone (ignoring
4
+ file) meant a generic local name like `args`/`data`/`client` -- conventionally
5
+ reused as an independent local in unrelated functions across unrelated
6
+ files -- falsely triggered "Shotgun Surgery" whenever 5+ unrelated functions
7
+ anywhere in the analyzed tree happened to share that name. Reproduced live:
8
+ 40+ false-positive tickets in one monorepo, including `args` in a 40-line,
9
+ one-function CLI file reported as "spans 8 functions" (the other 7 were
10
+ unrelated `args` locals in unrelated files elsewhere in the tree).
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from code2llm.analysis.smells import SmellDetector
16
+ from code2llm.core.models import AnalysisResult, FunctionInfo, Mutation
17
+
18
+
19
+ def _function(name: str, file: str, line: int = 1) -> FunctionInfo:
20
+ return FunctionInfo(name=name, qualified_name=f"{file}::{name}", file=file, line=line)
21
+
22
+
23
+ def _mutation(variable: str, file: str, scope: str, line: int = 1) -> Mutation:
24
+ return Mutation(
25
+ variable=variable, file=file, line=line, type="assign", scope=scope, context=""
26
+ )
27
+
28
+
29
+ def test_same_name_across_unrelated_files_is_not_shotgun_surgery():
30
+ """The core regression: `args` reused independently in 6 unrelated
31
+ files/functions must NOT be flagged -- no single file has more than one
32
+ mutating function."""
33
+ result = AnalysisResult()
34
+ for i in range(6):
35
+ file = f"pkg{i}/cli.py"
36
+ scope = f"pkg{i}.cli::main"
37
+ result.functions[scope] = _function("main", file)
38
+ result.mutations.append(_mutation("args", file, scope))
39
+
40
+ smells = SmellDetector(result)._detect_shotgun_surgery()
41
+
42
+ assert smells == []
43
+
44
+
45
+ def test_genuine_same_file_shotgun_surgery_still_detected():
46
+ """5+ functions *within the same file* mutating the same variable is the
47
+ real smell and must still be caught."""
48
+ result = AnalysisResult()
49
+ file = "core/session.py"
50
+ for i in range(5):
51
+ scope = f"core.session::step_{i}"
52
+ result.functions[scope] = _function(f"step_{i}", file, line=10 * i)
53
+ result.mutations.append(_mutation("state", file, scope))
54
+
55
+ smells = SmellDetector(result)._detect_shotgun_surgery()
56
+
57
+ assert len(smells) == 1
58
+ assert smells[0].name == "Shotgun Surgery: state"
59
+ assert set(smells[0].context["affected_functions"]) == {
60
+ f"core.session::step_{i}" for i in range(5)
61
+ }
62
+
63
+
64
+ def test_four_functions_in_one_file_below_threshold():
65
+ result = AnalysisResult()
66
+ file = "core/session.py"
67
+ for i in range(4):
68
+ scope = f"core.session::step_{i}"
69
+ result.functions[scope] = _function(f"step_{i}", file)
70
+ result.mutations.append(_mutation("state", file, scope))
71
+
72
+ smells = SmellDetector(result)._detect_shotgun_surgery()
73
+
74
+ assert smells == []
75
+
76
+
77
+ def test_same_variable_name_in_two_files_counts_separately_per_file():
78
+ """5 mutators of 'data' in file A (real smell) plus unrelated mutators of
79
+ 'data' in file B must not combine into a bigger, less accurate count,
80
+ and file B (below threshold) must not itself be flagged."""
81
+ result = AnalysisResult()
82
+ file_a = "a.py"
83
+ for i in range(5):
84
+ scope = f"a::fn_{i}"
85
+ result.functions[scope] = _function(f"fn_{i}", file_a)
86
+ result.mutations.append(_mutation("data", file_a, scope))
87
+
88
+ file_b = "b.py"
89
+ for i in range(3):
90
+ scope = f"b::fn_{i}"
91
+ result.functions[scope] = _function(f"fn_{i}", file_b)
92
+ result.mutations.append(_mutation("data", file_b, scope))
93
+
94
+ smells = SmellDetector(result)._detect_shotgun_surgery()
95
+
96
+ assert len(smells) == 1
97
+ assert smells[0].context["file"] == file_a
code2llm-0.5.169/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.5.169
File without changes
File without changes
File without changes
File without changes
File without changes