code2llm 0.3.10__tar.gz → 0.3.11__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 (70) hide show
  1. {code2llm-0.3.10 → code2llm-0.3.11}/PKG-INFO +1 -1
  2. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/__init__.py +2 -2
  3. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/__main__.py +1 -1
  4. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/analysis/__init__.py +1 -1
  5. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/analysis/data_analysis.py +1 -1
  6. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/analysis/pipeline_detector.py +1 -1
  7. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/cli.py +18 -27
  8. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/core/__init__.py +1 -1
  9. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/core/analyzer.py +1 -1
  10. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/core/config.py +2 -2
  11. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/core/streaming_analyzer.py +2 -2
  12. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/exporters/__init__.py +1 -1
  13. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/exporters/base.py +1 -1
  14. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/exporters/context_exporter.py +1 -1
  15. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/exporters/json_exporter.py +1 -1
  16. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/exporters/mermaid_exporter.py +1 -1
  17. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/exporters/toon.py +2 -2
  18. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/exporters/yaml_exporter.py +1 -1
  19. code2llm-0.3.11/code2llm/generators/__init__.py +12 -0
  20. code2llm-0.3.10/code2flow/llm_flow_generator.py → code2llm-0.3.11/code2llm/generators/llm_flow.py +1 -1
  21. code2llm-0.3.10/code2flow/mermaid_generator.py → code2llm-0.3.11/code2llm/generators/mermaid.py +1 -1
  22. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/nlp/__init__.py +1 -1
  23. {code2llm-0.3.10 → code2llm-0.3.11}/code2llm.egg-info/PKG-INFO +1 -1
  24. code2llm-0.3.11/code2llm.egg-info/SOURCES.txt +63 -0
  25. code2llm-0.3.11/code2llm.egg-info/entry_points.txt +2 -0
  26. code2llm-0.3.11/code2llm.egg-info/top_level.txt +1 -0
  27. {code2llm-0.3.10 → code2llm-0.3.11}/pyproject.toml +3 -3
  28. {code2llm-0.3.10 → code2llm-0.3.11}/setup.py +1 -1
  29. {code2llm-0.3.10 → code2llm-0.3.11}/tests/test_advanced_analysis.py +6 -6
  30. {code2llm-0.3.10 → code2llm-0.3.11}/tests/test_analyzer.py +6 -6
  31. code2llm-0.3.10/tests/test_sprint4.py → code2llm-0.3.11/tests/test_deep_analysis.py +3 -3
  32. {code2llm-0.3.10 → code2llm-0.3.11}/tests/test_edge_cases.py +5 -5
  33. code2llm-0.3.10/tests/test_sprint2_flow.py → code2llm-0.3.11/tests/test_flow_exporter.py +4 -4
  34. {code2llm-0.3.10 → code2llm-0.3.11}/tests/test_format_quality.py +11 -11
  35. {code2llm-0.3.10 → code2llm-0.3.11}/tests/test_nlp_pipeline.py +10 -10
  36. code2llm-0.3.10/tests/test_sprint3_pipelines.py → code2llm-0.3.11/tests/test_pipeline_detector.py +8 -8
  37. code2llm-0.3.10/tests/test_sprint5.py → code2llm-0.3.11/tests/test_prompt_engine.py +2 -2
  38. {code2llm-0.3.10 → code2llm-0.3.11}/tests/test_refactoring_engine.py +7 -7
  39. {code2llm-0.3.10 → code2llm-0.3.11}/tests/test_toon_v2.py +6 -6
  40. code2llm-0.3.10/code2flow/visualizers/__init__.py +0 -0
  41. code2llm-0.3.10/code2flow/visualizers/graph.py +0 -196
  42. code2llm-0.3.10/code2llm.egg-info/SOURCES.txt +0 -64
  43. code2llm-0.3.10/code2llm.egg-info/entry_points.txt +0 -2
  44. code2llm-0.3.10/code2llm.egg-info/top_level.txt +0 -1
  45. {code2llm-0.3.10 → code2llm-0.3.11}/LICENSE +0 -0
  46. {code2llm-0.3.10 → code2llm-0.3.11}/README.md +0 -0
  47. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/analysis/call_graph.py +0 -0
  48. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/analysis/cfg.py +0 -0
  49. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/analysis/coupling.py +0 -0
  50. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/analysis/dfg.py +0 -0
  51. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/analysis/side_effects.py +0 -0
  52. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/analysis/smells.py +0 -0
  53. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/analysis/type_inference.py +0 -0
  54. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/core/models.py +0 -0
  55. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/exporters/flow_exporter.py +0 -0
  56. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/exporters/llm_exporter.py +0 -0
  57. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/exporters/map_exporter.py +0 -0
  58. /code2llm-0.3.10/code2flow/llm_task_generator.py → /code2llm-0.3.11/code2llm/generators/llm_task.py +0 -0
  59. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/nlp/config.py +0 -0
  60. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/nlp/entity_resolution.py +0 -0
  61. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/nlp/intent_matching.py +0 -0
  62. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/nlp/normalization.py +0 -0
  63. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/nlp/pipeline.py +0 -0
  64. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/patterns/__init__.py +0 -0
  65. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/patterns/detector.py +0 -0
  66. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/refactor/__init__.py +0 -0
  67. {code2llm-0.3.10/code2flow → code2llm-0.3.11/code2llm}/refactor/prompt_engine.py +0 -0
  68. {code2llm-0.3.10 → code2llm-0.3.11}/code2llm.egg-info/dependency_links.txt +0 -0
  69. {code2llm-0.3.10 → code2llm-0.3.11}/code2llm.egg-info/requires.txt +0 -0
  70. {code2llm-0.3.10 → code2llm-0.3.11}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code2llm
3
- Version: 0.3.10
3
+ Version: 0.3.11
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
@@ -1,5 +1,5 @@
1
1
  """
2
- code2flow - Optimized Python Code Flow Analysis Tool
2
+ code2llm - Optimized Python Code Flow Analysis Tool
3
3
 
4
4
  A high-performance tool for analyzing Python code control flow, data flow,
5
5
  and call graphs with caching and parallel processing.
@@ -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.3.2"
11
+ __version__ = "0.3.3"
12
12
  __author__ = "STTS Project"
13
13
 
14
14
  # Core analysis components
@@ -1,4 +1,4 @@
1
- """Entry point for running code2flow as a module."""
1
+ """Entry point for running code2llm as a module."""
2
2
 
3
3
  from .cli import main
4
4
 
@@ -1,4 +1,4 @@
1
- """Analysis package for code2flow."""
1
+ """Analysis package for code2llm."""
2
2
 
3
3
  from .cfg import CFGExtractor
4
4
  from .dfg import DFGExtractor
@@ -1,4 +1,4 @@
1
- """Data Analysis logic for code2flow - extracted from YAMLExporter."""
1
+ """Data Analysis logic for code2llm - extracted from YAMLExporter."""
2
2
 
3
3
  from typing import Any, Dict, List
4
4
  from ..core.models import AnalysisResult
@@ -395,7 +395,7 @@ class PipelineDetector:
395
395
  parts = fi.module.split(".")
396
396
  # Use most specific module component
397
397
  for part in parts:
398
- if part and part not in ("code2flow", "__init__"):
398
+ if part and part not in ("code2llm", "__init__"):
399
399
  module_counts[part] += 1
400
400
 
401
401
  if module_counts:
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env python3
2
2
  """
3
- code2flow - CLI for Python code flow analysis
3
+ code2llm - CLI for Python code flow analysis
4
4
 
5
5
  Analyze control flow, data flow, and call graphs of Python codebases.
6
6
  """
@@ -16,23 +16,23 @@ from .exporters import (
16
16
  ContextExporter, LLMPromptExporter,
17
17
  ToonExporter, MapExporter, FlowExporter,
18
18
  )
19
- from .visualizers.graph import GraphVisualizer
19
+
20
20
 
21
21
 
22
22
  def create_parser() -> argparse.ArgumentParser:
23
23
  """Create CLI argument parser."""
24
24
  parser = argparse.ArgumentParser(
25
- prog='code2flow',
25
+ prog='code2llm',
26
26
  description='Analyze Python code control flow, data flow, and call graphs',
27
27
  formatter_class=argparse.RawDescriptionHelpFormatter,
28
28
  epilog='''
29
29
  Examples:
30
- code2flow /path/to/project # Default: TOON format only
31
- code2flow /path/to/project -f all # Generate all formats
32
- code2flow /path/to/project -f toon,map,flow # Diagnostics + structure + data-flow
33
- code2flow /path/to/project -f context # LLM narrative context
34
- code2flow /path/to/project -m static -o ./analysis
35
- code2flow llm-flow # Generate LLM flow summary
30
+ code2llm /path/to/project # Default: TOON format only
31
+ code2llm /path/to/project -f all # Generate all formats
32
+ code2llm /path/to/project -f toon,map,flow # Diagnostics + structure + data-flow
33
+ code2llm /path/to/project -f context # LLM narrative context
34
+ code2llm /path/to/project -m static -o ./analysis
35
+ code2llm llm-flow # Generate LLM flow summary
36
36
 
37
37
  Format Options:
38
38
  toon - Health diagnostics (analysis.toon) — default
@@ -42,7 +42,6 @@ Format Options:
42
42
  yaml - Standard YAML format
43
43
  json - Machine-readable JSON
44
44
  mermaid - Flowchart diagrams
45
- png - Visual graphs
46
45
  all - Generate all formats
47
46
  '''
48
47
  )
@@ -63,8 +62,8 @@ Format Options:
63
62
 
64
63
  parser.add_argument(
65
64
  '-o', '--output',
66
- default='./code2flow_output',
67
- help='Output directory (default: ./code2flow_output)'
65
+ default='./code2llm_output',
66
+ help='Output directory (default: ./code2llm_output)'
68
67
  )
69
68
 
70
69
  parser.add_argument(
@@ -179,7 +178,7 @@ def main():
179
178
  """Main CLI entry point."""
180
179
  # Handle special cases first
181
180
  if len(sys.argv) > 1 and sys.argv[1] == 'llm-flow':
182
- from .llm_flow_generator import main as llm_flow_main
181
+ from .generators.llm_flow import main as llm_flow_main
183
182
  return llm_flow_main(sys.argv[2:])
184
183
 
185
184
  if len(sys.argv) > 1 and sys.argv[1] == 'llm-context':
@@ -193,8 +192,8 @@ def main():
193
192
  # Handle analysis (default behavior)
194
193
  if not args.source:
195
194
  print("Error: missing required argument: source", file=sys.stderr)
196
- print("Usage: code2flow <source> [options]", file=sys.stderr)
197
- print(" or: code2flow llm-flow [options]", file=sys.stderr)
195
+ print("Usage: code2llm <source> [options]", file=sys.stderr)
196
+ print(" or: code2llm llm-flow [options]", file=sys.stderr)
198
197
  sys.exit(2)
199
198
 
200
199
  # Validate source path
@@ -293,7 +292,7 @@ def main():
293
292
 
294
293
  # Handle 'all' format
295
294
  if 'all' in formats:
296
- formats = ['toon', 'map', 'flow', 'context', 'yaml', 'json', 'mermaid', 'png']
295
+ formats = ['toon', 'map', 'flow', 'context', 'yaml', 'json', 'mermaid']
297
296
 
298
297
  try:
299
298
  if 'toon' in formats:
@@ -365,7 +364,7 @@ def main():
365
364
  # Auto-generate PNG from Mermaid files (unless disabled)
366
365
  if not args.no_png:
367
366
  try:
368
- from .mermaid_generator import generate_pngs
367
+ from .generators.mermaid import generate_pngs
369
368
  png_count = generate_pngs(output_dir, output_dir)
370
369
  if args.verbose and png_count > 0:
371
370
  print(f" - PNG: {png_count} files generated")
@@ -387,15 +386,7 @@ def main():
387
386
  elif args.verbose:
388
387
  print(f" - PNG: Skipped (--no-png)")
389
388
 
390
- if 'png' in formats:
391
- visualizer = GraphVisualizer(result)
392
- filepath = output_dir / 'cfg.png'
393
- visualizer.visualize_cfg(str(filepath))
394
- filepath = output_dir / 'call_graph.png'
395
- visualizer.visualize_call_graph(str(filepath))
396
- if args.verbose:
397
- print(f" - PNG: {output_dir / '*.png'}")
398
-
389
+
399
390
  if args.data_structures:
400
391
  exporter = YAMLExporter()
401
392
  struct_path = output_dir / 'data_structures.yaml'
@@ -450,7 +441,7 @@ def generate_llm_context(args_list):
450
441
  import argparse
451
442
 
452
443
  parser = argparse.ArgumentParser(
453
- prog='code2flow llm-context',
444
+ prog='code2llm llm-context',
454
445
  description='Generate LLM-friendly context for a project'
455
446
  )
456
447
  parser.add_argument('source', help='Path to Python project')
@@ -1,4 +1,4 @@
1
- """Core analysis components for code2flow."""
1
+ """Core analysis components for code2llm."""
2
2
 
3
3
  from .analyzer import ProjectAnalyzer, FileCache, FastFileFilter
4
4
  from .streaming_analyzer import (
@@ -29,7 +29,7 @@ from ..analysis.smells import SmellDetector
29
29
  class FileCache:
30
30
  """Cache for parsed AST files."""
31
31
 
32
- def __init__(self, cache_dir: str = ".code2flow_cache", ttl_hours: int = 24):
32
+ def __init__(self, cache_dir: str = ".code2llm_cache", ttl_hours: int = 24):
33
33
  self.cache_dir = Path(cache_dir)
34
34
  self.cache_dir.mkdir(parents=True, exist_ok=True)
35
35
  self.ttl_seconds = ttl_hours * 3600
@@ -1,4 +1,4 @@
1
- """Configuration and constants for code2flow."""
1
+ """Configuration and constants for code2llm."""
2
2
 
3
3
  from dataclasses import dataclass, field
4
4
  from typing import List, Set
@@ -18,7 +18,7 @@ class AnalysisMode(str, Enum):
18
18
  class PerformanceConfig:
19
19
  """Performance optimization settings."""
20
20
  enable_cache: bool = True
21
- cache_dir: str = ".code2flow_cache"
21
+ cache_dir: str = ".code2llm_cache"
22
22
  cache_ttl_hours: int = 24
23
23
  parallel_workers: int = 4
24
24
  parallel_enabled: bool = True
@@ -110,7 +110,7 @@ STRATEGY_DEEP = ScanStrategy(
110
110
  class StreamingFileCache:
111
111
  """Memory-efficient cache with LRU eviction."""
112
112
 
113
- def __init__(self, max_size: int = 100, cache_dir: str = ".code2flow_cache"):
113
+ def __init__(self, max_size: int = 100, cache_dir: str = ".code2llm_cache"):
114
114
  self.max_size = max_size
115
115
  self.cache_dir = Path(cache_dir)
116
116
  self.cache_dir.mkdir(parents=True, exist_ok=True)
@@ -605,7 +605,7 @@ class IncrementalAnalyzer:
605
605
 
606
606
  def __init__(self, config: Optional[Config] = None):
607
607
  self.config = config or FAST_CONFIG
608
- self.state_file = Path(".code2flow_state.json")
608
+ self.state_file = Path(".code2llm_state.json")
609
609
  self.previous_state: Dict[str, str] = {}
610
610
  self._load_state()
611
611
 
@@ -1,4 +1,4 @@
1
- """Exporters package for code2flow.
1
+ """Exporters package for code2llm.
2
2
 
3
3
  Available exporters:
4
4
  - ToonExporter → analysis.toon (health diagnostics)
@@ -1,4 +1,4 @@
1
- """Base Exporter class for code2flow."""
1
+ """Base Exporter class for code2llm."""
2
2
 
3
3
  from abc import ABC, abstractmethod
4
4
  from ..core.models import AnalysisResult
@@ -1,4 +1,4 @@
1
- """Context Exporter for code2flow — generates context.md (LLM narrative).
1
+ """Context Exporter for code2llm — generates context.md (LLM narrative).
2
2
 
3
3
  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.
@@ -1,4 +1,4 @@
1
- """JSON Exporter for code2flow."""
1
+ """JSON Exporter for code2llm."""
2
2
 
3
3
  import json
4
4
  from pathlib import Path
@@ -1,4 +1,4 @@
1
- """Mermaid Exporter for code2flow."""
1
+ """Mermaid Exporter for code2llm."""
2
2
 
3
3
  from pathlib import Path
4
4
  from typing import Dict
@@ -1,4 +1,4 @@
1
- """Toon Exporter v2 — scannable plain-text format for code2flow.
1
+ """Toon Exporter v2 — scannable plain-text format for code2llm.
2
2
 
3
3
  Structure communicates health: sorting by severity, inline markers,
4
4
  coupling matrix, duplicate detection, filtered functions.
@@ -490,7 +490,7 @@ class ToonExporter:
490
490
  ncycles = len(ctx["cycles"])
491
491
 
492
492
  lines = [
493
- f"# code2flow | {nfiles}f {total_lines}L | py:{nfiles} | {ctx['timestamp']}",
493
+ f"# code2llm | {nfiles}f {total_lines}L | py:{nfiles} | {ctx['timestamp']}",
494
494
  f"# CC\u0304={avg_cc} | critical:{critical}/{nfuncs} | dups:{ndups} | cycles:{ncycles}",
495
495
  ]
496
496
  return lines
@@ -1,4 +1,4 @@
1
- """YAML Exporter for code2flow."""
1
+ """YAML Exporter for code2llm."""
2
2
 
3
3
  import yaml
4
4
  from collections import defaultdict
@@ -0,0 +1,12 @@
1
+ """code2llm generators package.
2
+
3
+ Generators for LLM flow summaries, task breakdowns, and Mermaid diagrams.
4
+ """
5
+
6
+ from .llm_flow import main as llm_flow_main
7
+ from .mermaid import generate_pngs
8
+
9
+ __all__ = [
10
+ 'llm_flow_main',
11
+ 'generate_pngs',
12
+ ]
@@ -394,7 +394,7 @@ def dump_yaml(data: Dict[str, Any]) -> str:
394
394
  def create_parser() -> argparse.ArgumentParser:
395
395
  p = argparse.ArgumentParser(
396
396
  prog="llm-flow-generator",
397
- description="Generate compact LLM-friendly app flow summary from code2flow analysis.yaml",
397
+ description="Generate compact LLM-friendly app flow summary from code2llm analysis.yaml",
398
398
  )
399
399
  p.add_argument(
400
400
  "-i",
@@ -1,5 +1,5 @@
1
1
  """
2
- Mermaid PNG Generator for code2flow
2
+ Mermaid PNG Generator for code2llm
3
3
  Integrates with CLI to auto-generate PNG from Mermaid files.
4
4
  """
5
5
 
@@ -1,4 +1,4 @@
1
- """NLP Processing Pipeline for code2flow.
1
+ """NLP Processing Pipeline for code2llm.
2
2
 
3
3
  Provides query normalization, intent matching, and entity resolution
4
4
  with multilingual support and fuzzy matching.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code2llm
3
- Version: 0.3.10
3
+ Version: 0.3.11
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
@@ -0,0 +1,63 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ code2llm/__init__.py
6
+ code2llm/__main__.py
7
+ code2llm/cli.py
8
+ code2llm.egg-info/PKG-INFO
9
+ code2llm.egg-info/SOURCES.txt
10
+ code2llm.egg-info/dependency_links.txt
11
+ code2llm.egg-info/entry_points.txt
12
+ code2llm.egg-info/requires.txt
13
+ code2llm.egg-info/top_level.txt
14
+ code2llm/analysis/__init__.py
15
+ code2llm/analysis/call_graph.py
16
+ code2llm/analysis/cfg.py
17
+ code2llm/analysis/coupling.py
18
+ code2llm/analysis/data_analysis.py
19
+ code2llm/analysis/dfg.py
20
+ code2llm/analysis/pipeline_detector.py
21
+ code2llm/analysis/side_effects.py
22
+ code2llm/analysis/smells.py
23
+ code2llm/analysis/type_inference.py
24
+ code2llm/core/__init__.py
25
+ code2llm/core/analyzer.py
26
+ code2llm/core/config.py
27
+ code2llm/core/models.py
28
+ code2llm/core/streaming_analyzer.py
29
+ code2llm/exporters/__init__.py
30
+ code2llm/exporters/base.py
31
+ code2llm/exporters/context_exporter.py
32
+ code2llm/exporters/flow_exporter.py
33
+ code2llm/exporters/json_exporter.py
34
+ code2llm/exporters/llm_exporter.py
35
+ code2llm/exporters/map_exporter.py
36
+ code2llm/exporters/mermaid_exporter.py
37
+ code2llm/exporters/toon.py
38
+ code2llm/exporters/yaml_exporter.py
39
+ code2llm/generators/__init__.py
40
+ code2llm/generators/llm_flow.py
41
+ code2llm/generators/llm_task.py
42
+ code2llm/generators/mermaid.py
43
+ code2llm/nlp/__init__.py
44
+ code2llm/nlp/config.py
45
+ code2llm/nlp/entity_resolution.py
46
+ code2llm/nlp/intent_matching.py
47
+ code2llm/nlp/normalization.py
48
+ code2llm/nlp/pipeline.py
49
+ code2llm/patterns/__init__.py
50
+ code2llm/patterns/detector.py
51
+ code2llm/refactor/__init__.py
52
+ code2llm/refactor/prompt_engine.py
53
+ tests/test_advanced_analysis.py
54
+ tests/test_analyzer.py
55
+ tests/test_deep_analysis.py
56
+ tests/test_edge_cases.py
57
+ tests/test_flow_exporter.py
58
+ tests/test_format_quality.py
59
+ tests/test_nlp_pipeline.py
60
+ tests/test_pipeline_detector.py
61
+ tests/test_prompt_engine.py
62
+ tests/test_refactoring_engine.py
63
+ tests/test_toon_v2.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ code2llm = code2llm.cli:main
@@ -0,0 +1 @@
1
+ code2llm
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code2llm"
7
- version = "0.3.10"
7
+ version = "0.3.11"
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"
@@ -62,7 +62,7 @@ dev = [
62
62
  ]
63
63
 
64
64
  [project.scripts]
65
- code2flow = "code2flow.cli:main"
65
+ code2llm = "code2llm.cli:main"
66
66
 
67
67
  [project.urls]
68
68
  Homepage = "https://github.com/wronai/stts"
@@ -74,7 +74,7 @@ line-length = 100
74
74
  target-version = ['py38']
75
75
 
76
76
  [tool.mypy]
77
- python_version = "0.3.10"
77
+ python_version = "0.3.11"
78
78
  ignore_missing_imports = true
79
79
 
80
80
  [tool.pytest.ini_options]
@@ -26,7 +26,7 @@ setup(
26
26
  packages=find_packages(),
27
27
  entry_points={
28
28
  'console_scripts': [
29
- 'code2llm=code2flow.cli:main',
29
+ 'code2llm=code2llm.cli:main',
30
30
  ],
31
31
  },
32
32
  install_requires=[
@@ -1,8 +1,8 @@
1
1
  import pytest
2
2
  import ast
3
- from code2flow.core.analyzer import ProjectAnalyzer
4
- from code2flow.core.config import Config
5
- from code2flow.core.models import AnalysisResult
3
+ from code2llm.core.analyzer import ProjectAnalyzer
4
+ from code2llm.core.config import Config
5
+ from code2llm.core.models import AnalysisResult
6
6
 
7
7
  def test_radon_complexity():
8
8
  content = """
@@ -20,7 +20,7 @@ def complex_func(x):
20
20
  print(i)
21
21
  return 0
22
22
  """
23
- from code2flow.core.analyzer import FileAnalyzer
23
+ from code2llm.core.analyzer import FileAnalyzer
24
24
  config = Config()
25
25
  config.verbose = True
26
26
  analyzer = FileAnalyzer(config)
@@ -49,7 +49,7 @@ def test_graph_metrics():
49
49
  # Actually Betweenness Centrality on:
50
50
  # A -> B, B -> C, A -> D, D -> C
51
51
 
52
- from code2flow.core.models import FunctionInfo
52
+ from code2llm.core.models import FunctionInfo
53
53
 
54
54
  func_names = ["A", "B", "C", "D"]
55
55
  for name in func_names:
@@ -73,7 +73,7 @@ def test_graph_metrics():
73
73
 
74
74
  def test_circular_dependency():
75
75
  result = AnalysisResult()
76
- from code2flow.core.models import FunctionInfo
76
+ from code2llm.core.models import FunctionInfo
77
77
 
78
78
  # A -> B -> A
79
79
  result.functions["A"] = FunctionInfo(name="A", qualified_name="A", file="test.py", line=1)
@@ -1,11 +1,11 @@
1
- """Test suite for code2flow."""
1
+ """Test suite for code2llm."""
2
2
 
3
3
  import pytest
4
4
  import tempfile
5
5
  import shutil
6
6
  from pathlib import Path
7
- from code2flow import ProjectAnalyzer, Config
8
- from code2flow.core.config import FAST_CONFIG, FilterConfig
7
+ from code2llm import ProjectAnalyzer, Config
8
+ from code2llm.core.config import FAST_CONFIG, FilterConfig
9
9
 
10
10
 
11
11
  class TestProjectAnalyzer:
@@ -175,7 +175,7 @@ class TestExporters:
175
175
  @pytest.fixture
176
176
  def sample_result(self):
177
177
  """Create sample analysis result."""
178
- from code2flow.core.models import AnalysisResult, FunctionInfo
178
+ from code2llm.core.models import AnalysisResult, FunctionInfo
179
179
 
180
180
  result = AnalysisResult(
181
181
  project_path="/test",
@@ -199,7 +199,7 @@ class TestExporters:
199
199
 
200
200
  def test_json_export(self, sample_result, tmp_path):
201
201
  """Test JSON export."""
202
- from code2flow.exporters.base import JSONExporter
202
+ from code2llm.exporters.base import JSONExporter
203
203
 
204
204
  output = tmp_path / "output.json"
205
205
  exporter = JSONExporter()
@@ -212,7 +212,7 @@ class TestExporters:
212
212
 
213
213
  def test_mermaid_export(self, sample_result, tmp_path):
214
214
  """Test Mermaid export."""
215
- from code2flow.exporters.base import MermaidExporter
215
+ from code2llm.exporters.base import MermaidExporter
216
216
 
217
217
  output = tmp_path / "output.mmd"
218
218
  exporter = MermaidExporter()
@@ -1,9 +1,9 @@
1
1
  import pytest
2
2
  import os
3
3
  from pathlib import Path
4
- from code2flow.core.analyzer import ProjectAnalyzer, FileAnalyzer
5
- from code2flow.core.config import Config
6
- from code2flow.core.models import AnalysisResult
4
+ from code2llm.core.analyzer import ProjectAnalyzer, FileAnalyzer
5
+ from code2llm.core.config import Config
6
+ from code2llm.core.models import AnalysisResult
7
7
 
8
8
  def test_astroid_resolution_mock(tmp_path):
9
9
  # Create two files. A.py calls B.func() via an instance.
@@ -1,12 +1,12 @@
1
- """Additional tests for code2flow - edge cases and integration tests."""
1
+ """Additional tests for code2llm - edge cases and integration tests."""
2
2
 
3
3
  import pytest
4
4
  import tempfile
5
5
  import shutil
6
6
  from pathlib import Path
7
- from code2flow import ProjectAnalyzer, FAST_CONFIG, NLPPipeline, FAST_NLP_CONFIG, Config
8
- from code2flow.core.analyzer import FileCache, FastFileFilter
9
- from code2flow.core.config import FilterConfig, PerformanceConfig
7
+ from code2llm import ProjectAnalyzer, FAST_CONFIG, NLPPipeline, FAST_NLP_CONFIG, Config
8
+ from code2llm.core.analyzer import FileCache, FastFileFilter
9
+ from code2llm.core.config import FilterConfig, PerformanceConfig
10
10
 
11
11
 
12
12
  class TestEdgeCases:
@@ -305,7 +305,7 @@ def standalone_func(): pass
305
305
  analysis = analyzer.analyze_project(str(tmp_dir))
306
306
 
307
307
  # Load entities
308
- from code2flow.nlp import EntityResolver
308
+ from code2llm.nlp import EntityResolver
309
309
  resolver = EntityResolver()
310
310
  resolver.load_from_analysis(analysis)
311
311
 
@@ -12,10 +12,10 @@ import tempfile
12
12
  import pytest
13
13
  from pathlib import Path
14
14
 
15
- from code2flow.core.models import AnalysisResult, FunctionInfo, ModuleInfo
16
- from code2flow.analysis.type_inference import TypeInferenceEngine
17
- from code2flow.analysis.side_effects import SideEffectDetector, SideEffectInfo
18
- from code2flow.exporters.flow_exporter import FlowExporter
15
+ from code2llm.core.models import AnalysisResult, FunctionInfo, ModuleInfo
16
+ from code2llm.analysis.type_inference import TypeInferenceEngine
17
+ from code2llm.analysis.side_effects import SideEffectDetector, SideEffectInfo
18
+ from code2llm.exporters.flow_exporter import FlowExporter
19
19
 
20
20
 
21
21
  # ---------------------------------------------------------------------------
@@ -2,7 +2,7 @@
2
2
  """
3
3
  Pytest-based format quality tests.
4
4
 
5
- These verify that each code2flow output format correctly detects
5
+ These verify that each code2llm output format correctly detects
6
6
  known problems in a controlled test project.
7
7
 
8
8
  Run with: pytest tests/test_format_quality.py -v
@@ -143,8 +143,8 @@ def ground_truth_project(tmp_path_factory) -> Path:
143
143
 
144
144
  @pytest.fixture(scope="module")
145
145
  def analysis_result(ground_truth_project):
146
- """Run code2flow analysis on ground truth project."""
147
- from code2flow import ProjectAnalyzer, Config
146
+ """Run code2llm analysis on ground truth project."""
147
+ from code2llm import ProjectAnalyzer, Config
148
148
  cfg = Config()
149
149
  cfg.filters.exclude_patterns = [
150
150
  '*__pycache__*', '*.pyc', '*venv*', '*.venv*',
@@ -165,7 +165,7 @@ class TestAnalysisToon:
165
165
 
166
166
  @pytest.fixture
167
167
  def toon_content(self, analysis_result, tmp_path):
168
- from code2flow.exporters.toon import ToonExporter
168
+ from code2llm.exporters.toon import ToonExporter
169
169
  out = tmp_path / "analysis.toon"
170
170
  ToonExporter().export(analysis_result, str(out))
171
171
  return out.read_text()
@@ -206,7 +206,7 @@ class TestFlowToon:
206
206
 
207
207
  @pytest.fixture
208
208
  def flow_content(self, analysis_result, tmp_path):
209
- from code2flow.exporters.flow_exporter import FlowExporter
209
+ from code2llm.exporters.flow_exporter import FlowExporter
210
210
  out = tmp_path / "flow.toon"
211
211
  FlowExporter().export(analysis_result, str(out))
212
212
  return out.read_text()
@@ -246,7 +246,7 @@ class TestProjectMap:
246
246
 
247
247
  @pytest.fixture
248
248
  def map_content(self, analysis_result, tmp_path):
249
- from code2flow.exporters.map_exporter import MapExporter
249
+ from code2llm.exporters.map_exporter import MapExporter
250
250
  out = tmp_path / "project.map"
251
251
  MapExporter().export(analysis_result, str(out))
252
252
  return out.read_text()
@@ -279,7 +279,7 @@ class TestContextMd:
279
279
 
280
280
  @pytest.fixture
281
281
  def context_content(self, analysis_result, tmp_path):
282
- from code2flow.exporters.llm_exporter import LLMPromptExporter
282
+ from code2llm.exporters.llm_exporter import LLMPromptExporter
283
283
  out = tmp_path / "context.md"
284
284
  LLMPromptExporter().export(analysis_result, str(out))
285
285
  return out.read_text()
@@ -305,10 +305,10 @@ class TestCrossFormat:
305
305
  def all_formats(self, analysis_result, tmp_path):
306
306
  formats = {}
307
307
  exporters = {
308
- "analysis.toon": ("code2flow.exporters.toon", "ToonExporter"),
309
- "flow.toon": ("code2flow.exporters.flow_exporter", "FlowExporter"),
310
- "project.map": ("code2flow.exporters.map_exporter", "MapExporter"),
311
- "context.md": ("code2flow.exporters.llm_exporter", "LLMPromptExporter"),
308
+ "analysis.toon": ("code2llm.exporters.toon", "ToonExporter"),
309
+ "flow.toon": ("code2llm.exporters.flow_exporter", "FlowExporter"),
310
+ "project.map": ("code2llm.exporters.map_exporter", "MapExporter"),
311
+ "context.md": ("code2llm.exporters.llm_exporter", "LLMPromptExporter"),
312
312
  }
313
313
  for name, (mod_path, cls_name) in exporters.items():
314
314
  try:
@@ -1,14 +1,14 @@
1
1
  """Tests for NLP Processing Pipeline."""
2
2
 
3
3
  import pytest
4
- from code2flow.nlp import (
4
+ from code2llm.nlp import (
5
5
  NLPPipeline, QueryNormalizer, IntentMatcher, EntityResolver,
6
6
  NLPConfig, FAST_NLP_CONFIG, PRECISE_NLP_CONFIG
7
7
  )
8
- from code2flow.nlp.normalization import NormalizationResult
9
- from code2flow.nlp.intent_matching import IntentMatchingResult, IntentMatch
10
- from code2flow.nlp.entity_resolution import EntityResolutionResult, Entity
11
- from code2flow.nlp.config import EntityResolutionConfig
8
+ from code2llm.nlp.normalization import NormalizationResult
9
+ from code2llm.nlp.intent_matching import IntentMatchingResult, IntentMatch
10
+ from code2llm.nlp.entity_resolution import EntityResolutionResult, Entity
11
+ from code2llm.nlp.config import EntityResolutionConfig
12
12
 
13
13
 
14
14
  class TestQueryNormalization:
@@ -48,7 +48,7 @@ class TestQueryNormalization:
48
48
 
49
49
  def test_step_1e_remove_stopwords(self):
50
50
  """1e. Stopword removal."""
51
- from code2flow.nlp.config import NormalizationConfig
51
+ from code2llm.nlp.config import NormalizationConfig
52
52
 
53
53
  config = NormalizationConfig(remove_stopwords=True)
54
54
  normalizer = QueryNormalizer(config)
@@ -103,7 +103,7 @@ class TestIntentMatching:
103
103
 
104
104
  def test_step_2e_multi_intent_resolution(self):
105
105
  """2e. Multi-intent resolution strategy."""
106
- from code2flow.nlp.config import IntentMatchingConfig
106
+ from code2llm.nlp.config import IntentMatchingConfig
107
107
 
108
108
  config = IntentMatchingConfig(multi_intent_strategy="best_match")
109
109
  matcher = IntentMatcher(config)
@@ -134,7 +134,7 @@ class TestEntityResolution:
134
134
  Entity("analyze", "analyzer.analyze", "function", 1.0),
135
135
  ],
136
136
  "class": [
137
- Entity("Pipeline", "code2flow.Pipeline", "class", 1.0),
137
+ Entity("Pipeline", "code2llm.Pipeline", "class", 1.0),
138
138
  ],
139
139
  }
140
140
 
@@ -148,7 +148,7 @@ class TestEntityResolution:
148
148
 
149
149
  def test_step_3b_name_match_threshold(self, mock_entities):
150
150
  """3b. Name matching threshold."""
151
- from code2flow.nlp.config import EntityResolutionConfig
151
+ from code2llm.nlp.config import EntityResolutionConfig
152
152
 
153
153
  config = EntityResolutionConfig(name_match_threshold=0.9)
154
154
  resolver = EntityResolver(config, mock_entities)
@@ -176,7 +176,7 @@ class TestEntityResolution:
176
176
 
177
177
  # Add hierarchical entity
178
178
  mock_entities["function"].append(
179
- Entity("Pipeline.run", "code2flow.Pipeline.run", "function", 1.0)
179
+ Entity("Pipeline.run", "code2llm.Pipeline.run", "function", 1.0)
180
180
  )
181
181
 
182
182
  result = resolver.resolve("run method")
@@ -10,13 +10,13 @@ import textwrap
10
10
  import pytest
11
11
  from pathlib import Path
12
12
 
13
- from code2flow.core.models import AnalysisResult, FunctionInfo, ModuleInfo
14
- from code2flow.analysis.pipeline_detector import (
13
+ from code2llm.core.models import AnalysisResult, FunctionInfo, ModuleInfo
14
+ from code2llm.analysis.pipeline_detector import (
15
15
  PipelineDetector, Pipeline, PipelineStage,
16
16
  )
17
- from code2flow.analysis.side_effects import SideEffectDetector
18
- from code2flow.analysis.type_inference import TypeInferenceEngine
19
- from code2flow.exporters.flow_exporter import FlowExporter
17
+ from code2llm.analysis.side_effects import SideEffectDetector
18
+ from code2llm.analysis.type_inference import TypeInferenceEngine
19
+ from code2llm.exporters.flow_exporter import FlowExporter
20
20
 
21
21
 
22
22
  # ---------------------------------------------------------------------------
@@ -178,7 +178,7 @@ class TestDomainClassification:
178
178
  def test_nlp_domain(self):
179
179
  funcs = _build_chain_funcs([
180
180
  ("normalize_query", 2), ("match_intent", 5), ("resolve_entity", 3),
181
- ], module="code2flow.nlp")
181
+ ], module="code2llm.nlp")
182
182
  detector = PipelineDetector()
183
183
  pipelines = detector.detect(funcs)
184
184
 
@@ -188,7 +188,7 @@ class TestDomainClassification:
188
188
  def test_analysis_domain(self):
189
189
  funcs = _build_chain_funcs([
190
190
  ("analyze_file", 4), ("compute_metrics", 6), ("build_call_graph", 3),
191
- ], module="code2flow.analysis")
191
+ ], module="code2llm.analysis")
192
192
  detector = PipelineDetector()
193
193
  pipelines = detector.detect(funcs)
194
194
 
@@ -198,7 +198,7 @@ class TestDomainClassification:
198
198
  def test_export_domain(self):
199
199
  funcs = _build_chain_funcs([
200
200
  ("export_toon", 3), ("render_header", 2), ("format_output", 2),
201
- ], module="code2flow.exporters")
201
+ ], module="code2llm.exporters")
202
202
  detector = PipelineDetector()
203
203
  pipelines = detector.detect(funcs)
204
204
 
@@ -1,6 +1,6 @@
1
1
  import pytest
2
- from code2flow.refactor.prompt_engine import PromptEngine
3
- from code2flow.core.models import AnalysisResult, CodeSmell, FunctionInfo
2
+ from code2llm.refactor.prompt_engine import PromptEngine
3
+ from code2llm.core.models import AnalysisResult, CodeSmell, FunctionInfo
4
4
 
5
5
  def test_tiktoken_truncation():
6
6
  result = AnalysisResult()
@@ -1,10 +1,10 @@
1
1
  import pytest
2
2
  import ast
3
- from code2flow.core.config import Config
4
- from code2flow.analysis.call_graph import CallGraphExtractor
5
- from code2flow.analysis.dfg import DFGExtractor
6
- from code2flow.analysis.smells import SmellDetector
7
- from code2flow.refactor.prompt_engine import PromptEngine
3
+ from code2llm.core.config import Config
4
+ from code2llm.analysis.call_graph import CallGraphExtractor
5
+ from code2llm.analysis.dfg import DFGExtractor
6
+ from code2llm.analysis.smells import SmellDetector
7
+ from code2llm.refactor.prompt_engine import PromptEngine
8
8
 
9
9
  def test_metrics_calculation():
10
10
  code = """
@@ -23,7 +23,7 @@ def c():
23
23
 
24
24
  # Manual population of functions (since cg_extractor assumes they are in result.functions)
25
25
  # ProjectAnalyzer normally does this merge. For unit test, we simulate:
26
- from code2flow.core.models import FunctionInfo
26
+ from code2llm.core.models import FunctionInfo
27
27
  result.functions = {
28
28
  "test.a": FunctionInfo(name="a", qualified_name="test.a", file="test.py", line=2, calls=["test.b", "test.c"]),
29
29
  "test.b": FunctionInfo(name="b", qualified_name="test.b", file="test.py", line=5, calls=[]),
@@ -55,7 +55,7 @@ def update_data(obj):
55
55
  assert "method_call" in types # .append()
56
56
 
57
57
  def test_smell_detection():
58
- from code2flow.core.models import AnalysisResult, FunctionInfo, Mutation
58
+ from code2llm.core.models import AnalysisResult, FunctionInfo, Mutation
59
59
  result = AnalysisResult(project_path=".", analysis_mode="static")
60
60
  result.functions = {
61
61
  "test.god_func": FunctionInfo(name="god_func", qualified_name="test.god_func", file="test.py", line=10)
@@ -1,8 +1,8 @@
1
1
  """Tests for ToonExporter v2 format."""
2
2
  import pytest
3
3
  from pathlib import Path
4
- from code2flow.core.models import AnalysisResult, FunctionInfo, ClassInfo, ModuleInfo
5
- from code2flow.exporters.toon import ToonExporter, EXCLUDE_PATTERNS
4
+ from code2llm.core.models import AnalysisResult, FunctionInfo, ClassInfo, ModuleInfo
5
+ from code2llm.exporters.toon import ToonExporter, EXCLUDE_PATTERNS
6
6
 
7
7
 
8
8
  @pytest.fixture
@@ -91,7 +91,7 @@ class TestToonExporterV2:
91
91
  lines = content.split("\n")
92
92
 
93
93
  # Check header
94
- assert lines[0].startswith("# code2flow |")
94
+ assert lines[0].startswith("# code2llm |")
95
95
  assert "CC" in lines[1]
96
96
  assert "critical:" in lines[1]
97
97
 
@@ -182,12 +182,12 @@ class TestToonExporterV2:
182
182
  """Test that normal project paths are included."""
183
183
  exporter = ToonExporter()
184
184
 
185
- assert exporter._is_excluded("/project/code2flow/analyzer.py") is False
185
+ assert exporter._is_excluded("/project/code2llm/analyzer.py") is False
186
186
  assert exporter._is_excluded("/project/tests/test_analyzer.py") is False
187
187
 
188
188
  def test_max_health_issues_limit(self, sample_result, tmp_path):
189
189
  """Test that HEALTH section respects MAX_HEALTH_ISSUES limit."""
190
- from code2flow.exporters.toon import MAX_HEALTH_ISSUES
190
+ from code2llm.exporters.toon import MAX_HEALTH_ISSUES
191
191
 
192
192
  # Add many high CC functions
193
193
  for i in range(100):
@@ -213,7 +213,7 @@ class TestToonExporterV2:
213
213
 
214
214
  def test_coupling_matrix_limited(self, sample_result, tmp_path):
215
215
  """Test that COUPLING matrix is limited to top packages."""
216
- from code2flow.exporters.toon import MAX_COUPLING_PACKAGES
216
+ from code2llm.exporters.toon import MAX_COUPLING_PACKAGES
217
217
 
218
218
  exporter = ToonExporter()
219
219
  output_file = tmp_path / "test.toon"
File without changes
@@ -1,196 +0,0 @@
1
- """Graph visualization using NetworkX and matplotlib."""
2
-
3
- import matplotlib.pyplot as plt
4
- import matplotlib.patches as patches
5
- import networkx as nx
6
- from typing import Dict
7
- from pathlib import Path
8
-
9
- from ..core.models import AnalysisResult
10
- from ..core.config import NODE_COLORS
11
-
12
-
13
- class GraphVisualizer:
14
- """Visualize analysis results as graphs."""
15
-
16
- def __init__(self, result: AnalysisResult):
17
- self.result = result
18
- self.graph = nx.DiGraph()
19
- self._build_graph()
20
-
21
- def _build_graph(self):
22
- """Build NetworkX graph from analysis result."""
23
- # Add nodes
24
- for node_id, node in self.result.nodes.items():
25
- color = NODE_COLORS.get(node.type, '#757575')
26
- self.graph.add_node(
27
- node_id,
28
- label=node.label[:30],
29
- type=node.type,
30
- color=color,
31
- function=node.function
32
- )
33
-
34
- # Add edges
35
- for edge in self.result.edges:
36
- self.graph.add_edge(
37
- edge.source,
38
- edge.target,
39
- edge_type=edge.edge_type,
40
- conditions=edge.conditions
41
- )
42
-
43
- def visualize_cfg(self, filepath: str, layout: str = 'spring'):
44
- """Create control flow visualization."""
45
- plt.figure(figsize=(16, 12))
46
-
47
- # Choose layout
48
- if layout == 'spring':
49
- pos = nx.spring_layout(self.graph, k=2, iterations=50, seed=42)
50
- elif layout == 'hierarchical':
51
- pos = self._hierarchical_layout()
52
- elif layout == 'kamada':
53
- pos = nx.kamada_kawai_layout(self.graph)
54
- else:
55
- pos = nx.shell_layout(self.graph)
56
-
57
- # Get node colors
58
- node_colors = []
59
- for node_id in self.graph.nodes():
60
- node_type = self.graph.nodes[node_id].get('type', 'DEFAULT')
61
- node_colors.append(NODE_COLORS.get(node_type, '#757575'))
62
-
63
- # Draw graph
64
- nx.draw_networkx_nodes(
65
- self.graph, pos,
66
- node_color=node_colors,
67
- node_size=600,
68
- alpha=0.8,
69
- edgecolors='white',
70
- linewidths=2
71
- )
72
-
73
- nx.draw_networkx_edges(
74
- self.graph, pos,
75
- alpha=0.4,
76
- arrows=True,
77
- arrowsize=15,
78
- arrowstyle='->',
79
- edge_color='#666666',
80
- width=1.5
81
- )
82
-
83
- # Draw labels for important nodes
84
- labels = {}
85
- for node_id in self.graph.nodes():
86
- node_data = self.graph.nodes[node_id]
87
- if node_data.get('type') in ['FUNC', 'IF', 'CALL']:
88
- label = node_data.get('label', '') or ''
89
- labels[node_id] = label[:25]
90
-
91
- nx.draw_networkx_labels(
92
- self.graph, pos, labels,
93
- font_size=8,
94
- font_color='white',
95
- font_weight='bold'
96
- )
97
-
98
- # Add legend
99
- legend_elements = [
100
- patches.Patch(color=NODE_COLORS['FUNC'], label='Function'),
101
- patches.Patch(color=NODE_COLORS['CALL'], label='Call'),
102
- patches.Patch(color=NODE_COLORS['IF'], label='Decision'),
103
- patches.Patch(color=NODE_COLORS['FOR'], label='Loop'),
104
- patches.Patch(color=NODE_COLORS['RETURN'], label='Return')
105
- ]
106
- plt.legend(handles=legend_elements, loc='upper right', fontsize=10)
107
-
108
- plt.title('Control Flow Graph', fontsize=16, fontweight='bold')
109
- plt.axis('off')
110
- plt.tight_layout()
111
- plt.savefig(filepath, dpi=300, bbox_inches='tight', facecolor='white')
112
- plt.close()
113
-
114
- def visualize_call_graph(self, filepath: str):
115
- """Visualize call graph."""
116
- # Build call graph
117
- call_graph = nx.DiGraph()
118
-
119
- for func_name, func_info in self.result.functions.items():
120
- short_name = func_name.split('.')[-1]
121
- call_graph.add_node(func_name, label=short_name)
122
-
123
- for callee in func_info.calls:
124
- call_graph.add_edge(func_name, callee)
125
-
126
- if len(call_graph.nodes()) == 0:
127
- return # Nothing to visualize
128
-
129
- plt.figure(figsize=(14, 10))
130
-
131
- # Layout
132
- pos = nx.spring_layout(call_graph, k=1.5, iterations=50, seed=42)
133
-
134
- # Node sizes based on calls
135
- node_sizes = []
136
- for node in call_graph.nodes():
137
- out_degree = call_graph.out_degree(node)
138
- in_degree = call_graph.in_degree(node)
139
- size = 300 + (out_degree + in_degree) * 150
140
- node_sizes.append(size)
141
-
142
- # Draw
143
- nx.draw_networkx_nodes(
144
- call_graph, pos,
145
- node_color='#4CAF50',
146
- node_size=node_sizes,
147
- alpha=0.8,
148
- edgecolors='white',
149
- linewidths=2
150
- )
151
-
152
- nx.draw_networkx_edges(
153
- call_graph, pos,
154
- alpha=0.5,
155
- arrows=True,
156
- arrowsize=20,
157
- edge_color='#2196F3',
158
- width=2
159
- )
160
-
161
- # Labels
162
- labels = {n: (call_graph.nodes[n].get('label') or n)[:20] for n in call_graph.nodes()}
163
- nx.draw_networkx_labels(
164
- call_graph, pos, labels,
165
- font_size=9,
166
- font_weight='bold'
167
- )
168
-
169
- plt.title('Function Call Graph', fontsize=16, fontweight='bold')
170
- plt.axis('off')
171
- plt.tight_layout()
172
- plt.savefig(filepath, dpi=300, bbox_inches='tight', facecolor='white')
173
- plt.close()
174
-
175
- def _hierarchical_layout(self) -> Dict:
176
- """Create hierarchical layout grouped by function."""
177
- from collections import defaultdict
178
-
179
- # Group nodes by function
180
- function_groups = defaultdict(list)
181
- for node_id, node in self.result.nodes.items():
182
- func = node.function or '__global__'
183
- function_groups[func].append(node_id)
184
-
185
- # Position nodes
186
- pos = {}
187
- y_offset = 0
188
-
189
- for func_name, nodes in sorted(function_groups.items()):
190
- for i, node_id in enumerate(nodes):
191
- x = i * 2
192
- y = -y_offset
193
- pos[node_id] = (x, y)
194
- y_offset += 3
195
-
196
- return pos
@@ -1,64 +0,0 @@
1
- LICENSE
2
- README.md
3
- pyproject.toml
4
- setup.py
5
- code2flow/__init__.py
6
- code2flow/__main__.py
7
- code2flow/cli.py
8
- code2flow/llm_flow_generator.py
9
- code2flow/llm_task_generator.py
10
- code2flow/mermaid_generator.py
11
- code2flow/analysis/__init__.py
12
- code2flow/analysis/call_graph.py
13
- code2flow/analysis/cfg.py
14
- code2flow/analysis/coupling.py
15
- code2flow/analysis/data_analysis.py
16
- code2flow/analysis/dfg.py
17
- code2flow/analysis/pipeline_detector.py
18
- code2flow/analysis/side_effects.py
19
- code2flow/analysis/smells.py
20
- code2flow/analysis/type_inference.py
21
- code2flow/core/__init__.py
22
- code2flow/core/analyzer.py
23
- code2flow/core/config.py
24
- code2flow/core/models.py
25
- code2flow/core/streaming_analyzer.py
26
- code2flow/exporters/__init__.py
27
- code2flow/exporters/base.py
28
- code2flow/exporters/context_exporter.py
29
- code2flow/exporters/flow_exporter.py
30
- code2flow/exporters/json_exporter.py
31
- code2flow/exporters/llm_exporter.py
32
- code2flow/exporters/map_exporter.py
33
- code2flow/exporters/mermaid_exporter.py
34
- code2flow/exporters/toon.py
35
- code2flow/exporters/yaml_exporter.py
36
- code2flow/nlp/__init__.py
37
- code2flow/nlp/config.py
38
- code2flow/nlp/entity_resolution.py
39
- code2flow/nlp/intent_matching.py
40
- code2flow/nlp/normalization.py
41
- code2flow/nlp/pipeline.py
42
- code2flow/patterns/__init__.py
43
- code2flow/patterns/detector.py
44
- code2flow/refactor/__init__.py
45
- code2flow/refactor/prompt_engine.py
46
- code2flow/visualizers/__init__.py
47
- code2flow/visualizers/graph.py
48
- code2llm.egg-info/PKG-INFO
49
- code2llm.egg-info/SOURCES.txt
50
- code2llm.egg-info/dependency_links.txt
51
- code2llm.egg-info/entry_points.txt
52
- code2llm.egg-info/requires.txt
53
- code2llm.egg-info/top_level.txt
54
- tests/test_advanced_analysis.py
55
- tests/test_analyzer.py
56
- tests/test_edge_cases.py
57
- tests/test_format_quality.py
58
- tests/test_nlp_pipeline.py
59
- tests/test_refactoring_engine.py
60
- tests/test_sprint2_flow.py
61
- tests/test_sprint3_pipelines.py
62
- tests/test_sprint4.py
63
- tests/test_sprint5.py
64
- tests/test_toon_v2.py
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- code2flow = code2flow.cli:main
@@ -1 +0,0 @@
1
- code2flow
File without changes
File without changes
File without changes