code2llm 0.5.87__tar.gz → 0.5.88__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 (120) hide show
  1. {code2llm-0.5.87 → code2llm-0.5.88}/PKG-INFO +3 -3
  2. {code2llm-0.5.87 → code2llm-0.5.88}/README.md +2 -2
  3. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/__init__.py +1 -1
  4. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/cli_exports/prompt.py +18 -3
  5. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/cli_parser.py +2 -2
  6. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/readme_exporter.py +1 -1
  7. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/nlp/__init__.py +1 -1
  8. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm.egg-info/PKG-INFO +3 -3
  9. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm.egg-info/SOURCES.txt +1 -0
  10. {code2llm-0.5.87 → code2llm-0.5.88}/pyproject.toml +1 -1
  11. {code2llm-0.5.87 → code2llm-0.5.88}/setup.py +1 -1
  12. code2llm-0.5.88/tests/test_project_toon_export.py +75 -0
  13. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_prompt_txt.py +1 -1
  14. {code2llm-0.5.87 → code2llm-0.5.88}/LICENSE +0 -0
  15. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/__main__.py +0 -0
  16. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/analysis/__init__.py +0 -0
  17. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/analysis/call_graph.py +0 -0
  18. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/analysis/cfg.py +0 -0
  19. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/analysis/coupling.py +0 -0
  20. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/analysis/data_analysis.py +0 -0
  21. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/analysis/dfg.py +0 -0
  22. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/analysis/pipeline_detector.py +0 -0
  23. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/analysis/side_effects.py +0 -0
  24. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/analysis/smells.py +0 -0
  25. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/analysis/type_inference.py +0 -0
  26. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/api.py +0 -0
  27. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/cli.py +0 -0
  28. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/cli_analysis.py +0 -0
  29. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/cli_commands.py +0 -0
  30. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/cli_exports/__init__.py +0 -0
  31. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/cli_exports/code2logic.py +0 -0
  32. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/cli_exports/formats.py +0 -0
  33. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/cli_exports/orchestrator.py +0 -0
  34. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/__init__.py +0 -0
  35. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/analyzer.py +0 -0
  36. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/config.py +0 -0
  37. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/file_analyzer.py +0 -0
  38. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/file_cache.py +0 -0
  39. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/file_filter.py +0 -0
  40. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/gitignore.py +0 -0
  41. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/__init__.py +0 -0
  42. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/base.py +0 -0
  43. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/cpp.py +0 -0
  44. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/csharp.py +0 -0
  45. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/generic.py +0 -0
  46. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/go_lang.py +0 -0
  47. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/java.py +0 -0
  48. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/php.py +0 -0
  49. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/ruby.py +0 -0
  50. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/rust.py +0 -0
  51. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/lang/typescript.py +0 -0
  52. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/large_repo.py +0 -0
  53. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/models.py +0 -0
  54. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/refactoring.py +0 -0
  55. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/repo_files.py +0 -0
  56. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/streaming/__init__.py +0 -0
  57. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/streaming/cache.py +0 -0
  58. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/streaming/incremental.py +0 -0
  59. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/streaming/prioritizer.py +0 -0
  60. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/streaming/scanner.py +0 -0
  61. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/streaming/strategies.py +0 -0
  62. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/streaming_analyzer.py +0 -0
  63. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/core/toon_size_manager.py +0 -0
  64. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/__init__.py +0 -0
  65. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/article_view.py +0 -0
  66. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/base.py +0 -0
  67. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/context_exporter.py +0 -0
  68. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/context_view.py +0 -0
  69. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/evolution_exporter.py +0 -0
  70. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/flow_constants.py +0 -0
  71. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/flow_exporter.py +0 -0
  72. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/flow_renderer.py +0 -0
  73. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/html_dashboard.py +0 -0
  74. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/index_generator.py +0 -0
  75. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/json_exporter.py +0 -0
  76. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/llm_exporter.py +0 -0
  77. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/map_exporter.py +0 -0
  78. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/mermaid_exporter.py +0 -0
  79. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/project_yaml_exporter.py +0 -0
  80. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/report_generators.py +0 -0
  81. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/toon/__init__.py +0 -0
  82. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/toon/helpers.py +0 -0
  83. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/toon/metrics.py +0 -0
  84. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/toon/module_detail.py +0 -0
  85. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/toon/renderer.py +0 -0
  86. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/toon.py +0 -0
  87. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/toon_view.py +0 -0
  88. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/validate_project.py +0 -0
  89. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/exporters/yaml_exporter.py +0 -0
  90. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/generators/__init__.py +0 -0
  91. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/generators/llm_flow.py +0 -0
  92. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/generators/llm_task.py +0 -0
  93. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/generators/mermaid.py +0 -0
  94. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/nlp/config.py +0 -0
  95. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/nlp/entity_resolution.py +0 -0
  96. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/nlp/intent_matching.py +0 -0
  97. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/nlp/normalization.py +0 -0
  98. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/nlp/pipeline.py +0 -0
  99. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/patterns/__init__.py +0 -0
  100. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/patterns/detector.py +0 -0
  101. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/refactor/__init__.py +0 -0
  102. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm/refactor/prompt_engine.py +0 -0
  103. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm.egg-info/dependency_links.txt +0 -0
  104. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm.egg-info/entry_points.txt +0 -0
  105. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm.egg-info/requires.txt +0 -0
  106. {code2llm-0.5.87 → code2llm-0.5.88}/code2llm.egg-info/top_level.txt +0 -0
  107. {code2llm-0.5.87 → code2llm-0.5.88}/setup.cfg +0 -0
  108. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_advanced_analysis.py +0 -0
  109. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_analyzer.py +0 -0
  110. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_deep_analysis.py +0 -0
  111. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_edge_cases.py +0 -0
  112. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_flow_exporter.py +0 -0
  113. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_format_quality.py +0 -0
  114. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_multilanguage_e2e.py +0 -0
  115. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_nlp_pipeline.py +0 -0
  116. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_nonpython_cc_calls.py +0 -0
  117. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_pipeline_detector.py +0 -0
  118. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_prompt_engine.py +0 -0
  119. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_refactoring_engine.py +0 -0
  120. {code2llm-0.5.87 → code2llm-0.5.88}/tests/test_toon_v2.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code2llm
3
- Version: 0.5.87
3
+ Version: 0.5.88
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
@@ -76,7 +76,7 @@ When you run `code2llm ./ -f all`, the following files are created:
76
76
  # Quick health check (TOON format only)
77
77
  code2llm ./ -f toon
78
78
 
79
- # Generate all formats + prompt.txt (single-project mode)
79
+ # Generate all formats + project.toon.yaml + prompt.txt (single-project mode)
80
80
  code2llm ./ -f all -o ./project --no-chunk
81
81
 
82
82
  # LLM-ready context only
@@ -192,7 +192,7 @@ grep -E "^ .*[0-9]{3,}$" project.toon.yaml | sort -t',' -k2 -n -r | head -10
192
192
 
193
193
  ### `prompt.txt` - Ready-to-Send LLM Prompt
194
194
  **Purpose**: Pre-formatted prompt listing all generated files for LLM conversation
195
- **Generation**: Written when `code2llm` runs with a source path and requests `-f all` (including `--no-chunk`) or `code2logic`
195
+ **Generation**: Written when `code2llm` runs with a source path and requests `-f all` (including `--no-chunk`) or `code2logic`; `-f all` also writes `project.toon.yaml`
196
196
  **Contents**:
197
197
  - **Files section**: Lists all existing generated files with descriptions
198
198
  - **Source files section**: Highlights important source files such as `cli_exports/orchestrator.py`
@@ -26,7 +26,7 @@ When you run `code2llm ./ -f all`, the following files are created:
26
26
  # Quick health check (TOON format only)
27
27
  code2llm ./ -f toon
28
28
 
29
- # Generate all formats + prompt.txt (single-project mode)
29
+ # Generate all formats + project.toon.yaml + prompt.txt (single-project mode)
30
30
  code2llm ./ -f all -o ./project --no-chunk
31
31
 
32
32
  # LLM-ready context only
@@ -142,7 +142,7 @@ grep -E "^ .*[0-9]{3,}$" project.toon.yaml | sort -t',' -k2 -n -r | head -10
142
142
 
143
143
  ### `prompt.txt` - Ready-to-Send LLM Prompt
144
144
  **Purpose**: Pre-formatted prompt listing all generated files for LLM conversation
145
- **Generation**: Written when `code2llm` runs with a source path and requests `-f all` (including `--no-chunk`) or `code2logic`
145
+ **Generation**: Written when `code2llm` runs with a source path and requests `-f all` (including `--no-chunk`) or `code2logic`; `-f all` also writes `project.toon.yaml`
146
146
  **Contents**:
147
147
  - **Files section**: Lists all existing generated files with descriptions
148
148
  - **Source files section**: Highlights important source files such as `cli_exports/orchestrator.py`
@@ -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.87"
11
+ __version__ = "0.5.88"
12
12
  __author__ = "STTS Project"
13
13
 
14
14
  # Core analysis components (lightweight, always needed)
@@ -84,6 +84,7 @@ _MAIN_FILES = [
84
84
  ('analysis.toon', 'Health diagnostics - complexity metrics, god modules, coupling issues, refactoring priorities', ('analysis.toon', 'analysis.toon.yaml')),
85
85
  ('map.toon.yaml', 'Structural map - files, sizes, imports, exports, signatures, project header', ('map.toon.yaml',)),
86
86
  ('evolution.toon.yaml', 'Refactoring queue - ranked actions by impact/effort, risks, metrics targets, history', ('evolution.toon.yaml',)),
87
+ ('project.toon.yaml', 'Compact project overview - generated from project.yaml data', ('project.toon.yaml',)),
87
88
  ('context.md', 'LLM narrative - architecture summary and project context', ('context.md',)),
88
89
  ('README.md', 'Generated documentation - overview and usage guide', ('README.md',)),
89
90
  ]
@@ -242,6 +243,7 @@ def _analyze_generated_files(output_dir: Path, subprojects: list = None) -> dict
242
243
  analysis_file = _find_existing_prompt_file(output_dir, ('analysis.toon', 'analysis.toon.yaml'))
243
244
  map_file = _find_existing_prompt_file(output_dir, ('map.toon.yaml',))
244
245
  evolution_file = _find_existing_prompt_file(output_dir, ('evolution.toon.yaml',))
246
+ project_toon_file = _find_existing_prompt_file(output_dir, ('project.toon.yaml',))
245
247
  context_file = _find_existing_prompt_file(output_dir, ('context.md',))
246
248
  readme_file = _find_existing_prompt_file(output_dir, ('README.md',))
247
249
  project_logic_file = _find_existing_prompt_file(output_dir, ('project.toon', 'project/project.toon', 'project.toon.txt'))
@@ -255,6 +257,8 @@ def _analyze_generated_files(output_dir: Path, subprojects: list = None) -> dict
255
257
  'map_file': map_file or 'map.toon.yaml',
256
258
  'has_evolution_toon': evolution_file is not None,
257
259
  'evolution_file': evolution_file or 'evolution.toon.yaml',
260
+ 'has_project_toon_yaml': project_toon_file is not None,
261
+ 'project_toon_file': project_toon_file or 'project.toon.yaml',
258
262
  'has_context_md': context_file is not None,
259
263
  'context_file': context_file or 'context.md',
260
264
  'has_readme_md': readme_file is not None,
@@ -274,6 +278,7 @@ def _analyze_generated_files(output_dir: Path, subprojects: list = None) -> dict
274
278
  'has_analysis_toon',
275
279
  'has_map_toon',
276
280
  'has_evolution_toon',
281
+ 'has_project_toon_yaml',
277
282
  'has_project_logic',
278
283
  'has_validation_toon',
279
284
  'has_duplication_toon',
@@ -292,6 +297,7 @@ def _build_dynamic_focus_areas(file_analysis: dict) -> List[str]:
292
297
  analysis_file = file_analysis.get('analysis_file', 'analysis.toon')
293
298
  map_file = file_analysis.get('map_file', 'map.toon.yaml')
294
299
  evolution_file = file_analysis.get('evolution_file', 'evolution.toon.yaml')
300
+ project_toon_file = file_analysis.get('project_toon_file', 'project.toon.yaml')
295
301
  project_logic_file = file_analysis.get('project_logic_file', 'project.toon')
296
302
  validation_file = file_analysis.get('validation_file', 'project/validation.toon.yaml')
297
303
  duplication_file = file_analysis.get('duplication_file', 'project/duplication.toon.yaml')
@@ -305,14 +311,17 @@ def _build_dynamic_focus_areas(file_analysis: dict) -> List[str]:
305
311
  if file_analysis['has_evolution_toon']:
306
312
  focus_areas.append(f"3. **Refactoring Priorities** - Examine ranked refactoring actions and risk assessment from {evolution_file}")
307
313
 
314
+ if file_analysis.get('has_project_toon_yaml'):
315
+ focus_areas.append(f"4. **Project Overview** - Review the compact project overview from {project_toon_file}")
316
+
308
317
  if file_analysis.get('has_project_logic'):
309
- focus_areas.append(f"4. **Project Logic** - Review the compact module overview from {project_logic_file}")
318
+ focus_areas.append(f"5. **Project Logic** - Review the compact module overview from {project_logic_file}")
310
319
 
311
320
  if file_analysis['has_validation_toon']:
312
- focus_areas.append(f"5. **Validation Analysis** - Review validation results and issues identified by vallm from {validation_file}")
321
+ focus_areas.append(f"6. **Validation Analysis** - Review validation results and issues identified by vallm from {validation_file}")
313
322
 
314
323
  if file_analysis['has_duplication_toon']:
315
- focus_areas.append(f"6. **Code Duplication** - Examine duplicate code patterns detected by redup from {duplication_file}")
324
+ focus_areas.append(f"7. **Code Duplication** - Examine duplicate code patterns detected by redup from {duplication_file}")
316
325
 
317
326
  if not focus_areas:
318
327
  focus_areas.append("1. **General Code Review** - Provide overall architecture assessment and improvement recommendations")
@@ -325,6 +334,7 @@ def _build_dynamic_tasks(file_analysis: dict) -> List[str]:
325
334
  analysis_file = file_analysis.get('analysis_file', 'analysis.toon')
326
335
  map_file = file_analysis.get('map_file', 'map.toon.yaml')
327
336
  evolution_file = file_analysis.get('evolution_file', 'evolution.toon.yaml')
337
+ project_toon_file = file_analysis.get('project_toon_file', 'project.toon.yaml')
328
338
  validation_file = file_analysis.get('validation_file', 'project/validation.toon.yaml')
329
339
  duplication_file = file_analysis.get('duplication_file', 'project/duplication.toon.yaml')
330
340
  project_logic_file = file_analysis.get('project_logic_file', 'project.toon')
@@ -344,6 +354,9 @@ def _build_dynamic_tasks(file_analysis: dict) -> List[str]:
344
354
  if file_analysis['has_evolution_toon']:
345
355
  tasks.append(f"- Prioritize refactoring actions by impact/effort ratio from {evolution_file}.")
346
356
 
357
+ if file_analysis.get('has_project_toon_yaml'):
358
+ tasks.append(f"- Compare the compact project overview in {project_toon_file} with the main analysis files.")
359
+
347
360
  if file_analysis.get('has_project_logic'):
348
361
  tasks.append(f"- Use {project_logic_file} to validate the compact project overview against the rest of the analysis.")
349
362
 
@@ -385,6 +398,8 @@ def _build_prompt_footer(chunked: bool = False, file_analysis: dict = None) -> L
385
398
  lines.append(f"- Start with {file_analysis.get('analysis_file', 'analysis.toon')} for health metrics, then {file_analysis.get('map_file', 'map.toon.yaml')} for structure and signatures")
386
399
  if file_analysis['has_evolution_toon']:
387
400
  lines.append(f"- Review {file_analysis.get('evolution_file', 'evolution.toon.yaml')} for action priorities and next steps")
401
+ if file_analysis.get('has_project_toon_yaml'):
402
+ lines.append(f"- Compare the compact project overview in {file_analysis.get('project_toon_file', 'project.toon.yaml')} with the main analysis files")
388
403
  if file_analysis.get('has_project_logic'):
389
404
  lines.append(f"- Compare the compact project overview in {file_analysis.get('project_logic_file', 'project.toon')} with the main analysis files")
390
405
  if file_analysis['has_validation_toon']:
@@ -14,7 +14,7 @@ def create_parser() -> argparse.ArgumentParser:
14
14
  epilog='''
15
15
  Examples:
16
16
  code2llm ./ # Default: TOON diagnostics + README
17
- code2llm ./ -f all -o ./docs --no-chunk # All core formats + prompt.txt to ./docs/
17
+ code2llm ./ -f all -o ./docs --no-chunk # All core formats + project.toon.yaml + prompt.txt to ./docs/
18
18
  code2llm ./ -f toon,map,evolution # Consolidated diagnostics + structure + roadmap
19
19
  code2llm ./ -f context # LLM narrative (context.md)
20
20
  code2llm ./ --streaming --strategy deep -f all # Deep streaming analysis, all core outputs
@@ -43,7 +43,7 @@ Format Options (-f):
43
43
  flow — Data-flow analysis (flow.toon) — legacy, explicit opt-in
44
44
  code2logic — Generate project logic (legacy project.toon) via external code2logic
45
45
  project-yaml — Legacy project.yaml export (single source of truth) + generated views
46
- all — Generate core formats (analysis.toon, map.toon.yaml, evolution.toon.yaml, context, mermaid) plus prompt.txt in single-project runs
46
+ all — Generate core formats (analysis.toon, map.toon.yaml, evolution.toon.yaml, context, mermaid) plus project.toon.yaml and prompt.txt in single-project runs
47
47
 
48
48
  Strategy Options (--strategy):
49
49
  quick — Fast overview, fewer files analyzed
@@ -235,7 +235,7 @@ grep -E "^ .*[0-9]{{3,}}$" project.toon.yaml | sort -t',' -k2 -n -r | head -10
235
235
  **Purpose**: Pre-formatted prompt listing all generated files for LLM conversation
236
236
  **Generation**: Written when `code2llm` runs with a source path and requests `-f all` (including `--no-chunk`) or `code2logic`
237
237
  **Contents**:
238
- - **Files section**: Lists all existing generated files with descriptions
238
+ - **Files section**: Lists all existing generated files with descriptions, including `project.toon.yaml` when generated by `-f all`
239
239
  - **Source files section**: Highlights important source files such as `cli_exports/orchestrator.py`
240
240
  - **Missing section**: Shows which files weren't generated (if any)
241
241
  - **Task section**: Instructions for LLM analysis
@@ -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.87"
7
+ __version__ = "0.5.88"
8
8
 
9
9
  from .pipeline import NLPPipeline
10
10
  from .normalization import QueryNormalizer
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code2llm
3
- Version: 0.5.87
3
+ Version: 0.5.88
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
@@ -76,7 +76,7 @@ When you run `code2llm ./ -f all`, the following files are created:
76
76
  # Quick health check (TOON format only)
77
77
  code2llm ./ -f toon
78
78
 
79
- # Generate all formats + prompt.txt (single-project mode)
79
+ # Generate all formats + project.toon.yaml + prompt.txt (single-project mode)
80
80
  code2llm ./ -f all -o ./project --no-chunk
81
81
 
82
82
  # LLM-ready context only
@@ -192,7 +192,7 @@ grep -E "^ .*[0-9]{3,}$" project.toon.yaml | sort -t',' -k2 -n -r | head -10
192
192
 
193
193
  ### `prompt.txt` - Ready-to-Send LLM Prompt
194
194
  **Purpose**: Pre-formatted prompt listing all generated files for LLM conversation
195
- **Generation**: Written when `code2llm` runs with a source path and requests `-f all` (including `--no-chunk`) or `code2logic`
195
+ **Generation**: Written when `code2llm` runs with a source path and requests `-f all` (including `--no-chunk`) or `code2logic`; `-f all` also writes `project.toon.yaml`
196
196
  **Contents**:
197
197
  - **Files section**: Lists all existing generated files with descriptions
198
198
  - **Source files section**: Highlights important source files such as `cli_exports/orchestrator.py`
@@ -111,6 +111,7 @@ tests/test_multilanguage_e2e.py
111
111
  tests/test_nlp_pipeline.py
112
112
  tests/test_nonpython_cc_calls.py
113
113
  tests/test_pipeline_detector.py
114
+ tests/test_project_toon_export.py
114
115
  tests/test_prompt_engine.py
115
116
  tests/test_prompt_txt.py
116
117
  tests/test_refactoring_engine.py
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code2llm"
7
- version = "0.5.87"
7
+ version = "0.5.88"
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"
@@ -4,7 +4,7 @@ from setuptools import setup, find_packages
4
4
  import os
5
5
 
6
6
  # Read version
7
- version = "0.5.86"
7
+ version = "0.5.87"
8
8
 
9
9
  # Read long description
10
10
  def read_readme():
@@ -0,0 +1,75 @@
1
+ """Tests for automatic project.toon.yaml export in all-format runs."""
2
+
3
+ from pathlib import Path
4
+ from types import SimpleNamespace
5
+ from unittest.mock import MagicMock, patch
6
+
7
+ from code2llm.cli_exports.formats import _export_project_toon
8
+ from code2llm.cli_exports.orchestrator import _export_single_project
9
+
10
+
11
+ def test_export_project_toon_writes_file(tmp_path):
12
+ args = SimpleNamespace(verbose=False)
13
+ result = MagicMock()
14
+
15
+ fake_data = {
16
+ "project": {
17
+ "name": "sample",
18
+ "stats": {"functions": 1, "files": 1, "lines": 10, "classes": 0},
19
+ "language": "python",
20
+ "analyzed_at": "2026-03-26T12:34:56Z",
21
+ },
22
+ "health": {
23
+ "cc_avg": 1.0,
24
+ "critical_count": 0,
25
+ "critical_limit": 10,
26
+ "duplicates": 0,
27
+ "cycles": 0,
28
+ "alerts": [],
29
+ },
30
+ "modules": [
31
+ {"path": "sample.py", "lines": 10, "classes": 0, "methods": 1, "cc_max": 1, "inbound_deps": 0},
32
+ ],
33
+ "hotspots": [],
34
+ "refactoring": {},
35
+ "evolution": [],
36
+ }
37
+
38
+ with patch("code2llm.cli_exports.formats.ProjectYAMLExporter._load_previous_evolution", return_value=[]), \
39
+ patch("code2llm.cli_exports.formats.ProjectYAMLExporter._build_project_yaml", return_value=fake_data):
40
+ output_path = _export_project_toon(args, result, tmp_path)
41
+
42
+ assert output_path == tmp_path / "project.toon.yaml"
43
+ assert output_path.exists()
44
+
45
+ content = output_path.read_text(encoding="utf-8")
46
+ assert content.startswith("# sample | 1 func | 1f | 10L | python | 2026-03-26")
47
+ assert "HEALTH:" in content
48
+ assert "MODULES[1]" in content
49
+
50
+
51
+ def test_export_single_project_all_triggers_project_toon(tmp_path):
52
+ args = SimpleNamespace(verbose=False, refactor=False)
53
+ result = MagicMock()
54
+ source_path = Path("/tmp/source")
55
+
56
+ with patch("code2llm.cli_exports.orchestrator._export_simple_formats"), \
57
+ patch("code2llm.cli_exports.orchestrator._export_mermaid"), \
58
+ patch("code2llm.cli_exports.orchestrator._export_evolution"), \
59
+ patch("code2llm.cli_exports.orchestrator._export_data_structures"), \
60
+ patch("code2llm.cli_exports.orchestrator._export_context_fallback"), \
61
+ patch("code2llm.cli_exports.orchestrator._export_project_toon") as project_toon_mock, \
62
+ patch("code2llm.cli_exports.orchestrator._export_code2logic"), \
63
+ patch("code2llm.cli_exports.orchestrator._export_prompt_txt"), \
64
+ patch("code2llm.cli_exports.orchestrator._export_readme"), \
65
+ patch("code2llm.cli_exports.orchestrator._export_index_html"):
66
+ _export_single_project(
67
+ args,
68
+ result,
69
+ tmp_path,
70
+ ['toon', 'map', 'context', 'mermaid', 'evolution'],
71
+ requested_formats=['all'],
72
+ source_path=source_path,
73
+ )
74
+
75
+ project_toon_mock.assert_called_once_with(args, result, tmp_path)
@@ -148,7 +148,7 @@ class TestPromptTxtGeneration:
148
148
  source_path = Path('/home/user/myproject')
149
149
 
150
150
  # Create all expected files
151
- all_files = ['analysis.toon', 'map.toon.yaml', 'context.md', 'evolution.toon.yaml', 'README.md']
151
+ all_files = ['analysis.toon', 'map.toon.yaml', 'evolution.toon.yaml', 'project.toon.yaml', 'context.md', 'README.md']
152
152
  for f in all_files:
153
153
  (temp_output_dir / f).write_text('test')
154
154
 
File without changes
File without changes
File without changes
File without changes