sourcecode 0.4.0__tar.gz → 0.6.0__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 (156) hide show
  1. {sourcecode-0.4.0 → sourcecode-0.6.0}/.gitignore +8 -2
  2. {sourcecode-0.4.0 → sourcecode-0.6.0}/PKG-INFO +45 -33
  3. {sourcecode-0.4.0 → sourcecode-0.6.0}/README.md +44 -32
  4. {sourcecode-0.4.0 → sourcecode-0.6.0}/docs/schema.md +42 -33
  5. {sourcecode-0.4.0 → sourcecode-0.6.0}/pyproject.toml +1 -1
  6. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/__init__.py +1 -1
  7. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/cli.py +68 -8
  8. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/graph_analyzer.py +484 -70
  9. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/schema.py +9 -0
  10. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_cli.py +3 -0
  11. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_graph_analyzer_polyglot.py +30 -3
  12. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_graph_analyzer_python_node.py +41 -4
  13. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_graph_schema.py +15 -2
  14. sourcecode-0.6.0/tests/test_integration_graph_modules.py +120 -0
  15. sourcecode-0.4.0/.github/workflows/ci.yml +0 -42
  16. sourcecode-0.4.0/.github/workflows/release.yml +0 -101
  17. sourcecode-0.4.0/.planning/PROJECT.md +0 -79
  18. sourcecode-0.4.0/.planning/REQUIREMENTS.md +0 -111
  19. sourcecode-0.4.0/.planning/ROADMAP.md +0 -204
  20. sourcecode-0.4.0/.planning/STATE.md +0 -110
  21. sourcecode-0.4.0/.planning/config.json +0 -42
  22. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-01-PLAN.md +0 -475
  23. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-01-SUMMARY.md +0 -151
  24. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-02-PLAN.md +0 -521
  25. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-02-SUMMARY.md +0 -149
  26. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-03-PLAN.md +0 -468
  27. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-03-SUMMARY.md +0 -216
  28. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-04-PLAN.md +0 -771
  29. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-04-SUMMARY.md +0 -202
  30. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-CONTEXT.md +0 -77
  31. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-DISCUSSION-LOG.md +0 -29
  32. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-RESEARCH.md +0 -652
  33. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-REVIEW.md +0 -222
  34. sourcecode-0.4.0/.planning/phases/01-fundaciones/01-VERIFICATION.md +0 -134
  35. sourcecode-0.4.0/.planning/phases/02-deteccion-core/02-01-PLAN.md +0 -225
  36. sourcecode-0.4.0/.planning/phases/02-deteccion-core/02-01-SUMMARY.md +0 -88
  37. sourcecode-0.4.0/.planning/phases/02-deteccion-core/02-02-PLAN.md +0 -206
  38. sourcecode-0.4.0/.planning/phases/02-deteccion-core/02-02-SUMMARY.md +0 -84
  39. sourcecode-0.4.0/.planning/phases/02-deteccion-core/02-03-PLAN.md +0 -196
  40. sourcecode-0.4.0/.planning/phases/02-deteccion-core/02-03-SUMMARY.md +0 -84
  41. sourcecode-0.4.0/.planning/phases/02-deteccion-core/02-04-PLAN.md +0 -222
  42. sourcecode-0.4.0/.planning/phases/02-deteccion-core/02-04-SUMMARY.md +0 -110
  43. sourcecode-0.4.0/.planning/phases/02-deteccion-core/02-RESEARCH.md +0 -256
  44. sourcecode-0.4.0/.planning/phases/03-clasificacion-y-multi-stack/03-01-PLAN.md +0 -214
  45. sourcecode-0.4.0/.planning/phases/03-clasificacion-y-multi-stack/03-01-SUMMARY.md +0 -101
  46. sourcecode-0.4.0/.planning/phases/03-clasificacion-y-multi-stack/03-02-PLAN.md +0 -220
  47. sourcecode-0.4.0/.planning/phases/03-clasificacion-y-multi-stack/03-02-SUMMARY.md +0 -108
  48. sourcecode-0.4.0/.planning/phases/03-clasificacion-y-multi-stack/03-RESEARCH.md +0 -191
  49. sourcecode-0.4.0/.planning/phases/04-pulido-y-publicacion/04-01-PLAN.md +0 -186
  50. sourcecode-0.4.0/.planning/phases/04-pulido-y-publicacion/04-01-SUMMARY.md +0 -58
  51. sourcecode-0.4.0/.planning/phases/04-pulido-y-publicacion/04-02-PLAN.md +0 -138
  52. sourcecode-0.4.0/.planning/phases/04-pulido-y-publicacion/04-02-SUMMARY.md +0 -48
  53. sourcecode-0.4.0/.planning/phases/04-pulido-y-publicacion/04-03-PLAN.md +0 -141
  54. sourcecode-0.4.0/.planning/phases/04-pulido-y-publicacion/04-03-SUMMARY.md +0 -53
  55. sourcecode-0.4.0/.planning/phases/04-pulido-y-publicacion/04-RESEARCH.md +0 -153
  56. sourcecode-0.4.0/.planning/phases/05-scanner-universal-ampliar-stacks-ecosistemas-y-senales-de-de/.gitkeep +0 -0
  57. sourcecode-0.4.0/.planning/phases/05-scanner-universal-ampliar-stacks-ecosistemas-y-senales-de-de/05-01-PLAN.md +0 -146
  58. sourcecode-0.4.0/.planning/phases/05-scanner-universal-ampliar-stacks-ecosistemas-y-senales-de-de/05-01-SUMMARY.md +0 -53
  59. sourcecode-0.4.0/.planning/phases/05-scanner-universal-ampliar-stacks-ecosistemas-y-senales-de-de/05-02-PLAN.md +0 -169
  60. sourcecode-0.4.0/.planning/phases/05-scanner-universal-ampliar-stacks-ecosistemas-y-senales-de-de/05-02-SUMMARY.md +0 -53
  61. sourcecode-0.4.0/.planning/phases/05-scanner-universal-ampliar-stacks-ecosistemas-y-senales-de-de/05-03-PLAN.md +0 -164
  62. sourcecode-0.4.0/.planning/phases/05-scanner-universal-ampliar-stacks-ecosistemas-y-senales-de-de/05-03-SUMMARY.md +0 -51
  63. sourcecode-0.4.0/.planning/phases/05-scanner-universal-ampliar-stacks-ecosistemas-y-senales-de-de/05-04-PLAN.md +0 -183
  64. sourcecode-0.4.0/.planning/phases/05-scanner-universal-ampliar-stacks-ecosistemas-y-senales-de-de/05-04-SUMMARY.md +0 -57
  65. sourcecode-0.4.0/.planning/phases/05-scanner-universal-ampliar-stacks-ecosistemas-y-senales-de-de/05-RESEARCH.md +0 -165
  66. sourcecode-0.4.0/.planning/phases/06-dependencias-inteligentes/.gitkeep +0 -0
  67. sourcecode-0.4.0/.planning/phases/06-dependencias-inteligentes/06-01-PLAN.md +0 -140
  68. sourcecode-0.4.0/.planning/phases/06-dependencias-inteligentes/06-01-SUMMARY.md +0 -52
  69. sourcecode-0.4.0/.planning/phases/06-dependencias-inteligentes/06-02-PLAN.md +0 -135
  70. sourcecode-0.4.0/.planning/phases/06-dependencias-inteligentes/06-02-SUMMARY.md +0 -47
  71. sourcecode-0.4.0/.planning/phases/06-dependencias-inteligentes/06-03-PLAN.md +0 -132
  72. sourcecode-0.4.0/.planning/phases/06-dependencias-inteligentes/06-03-SUMMARY.md +0 -46
  73. sourcecode-0.4.0/.planning/phases/06-dependencias-inteligentes/06-04-PLAN.md +0 -143
  74. sourcecode-0.4.0/.planning/phases/06-dependencias-inteligentes/06-04-SUMMARY.md +0 -51
  75. sourcecode-0.4.0/.planning/phases/06-dependencias-inteligentes/06-RESEARCH.md +0 -171
  76. sourcecode-0.4.0/.planning/phases/07-grafos-de-codigo/.gitkeep +0 -0
  77. sourcecode-0.4.0/.planning/phases/07-grafos-de-codigo/07-01-PLAN.md +0 -141
  78. sourcecode-0.4.0/.planning/phases/07-grafos-de-codigo/07-01-SUMMARY.md +0 -52
  79. sourcecode-0.4.0/.planning/phases/07-grafos-de-codigo/07-02-PLAN.md +0 -134
  80. sourcecode-0.4.0/.planning/phases/07-grafos-de-codigo/07-02-SUMMARY.md +0 -48
  81. sourcecode-0.4.0/.planning/phases/07-grafos-de-codigo/07-03-PLAN.md +0 -131
  82. sourcecode-0.4.0/.planning/phases/07-grafos-de-codigo/07-03-SUMMARY.md +0 -46
  83. sourcecode-0.4.0/.planning/phases/07-grafos-de-codigo/07-04-PLAN.md +0 -143
  84. sourcecode-0.4.0/.planning/phases/07-grafos-de-codigo/07-04-SUMMARY.md +0 -50
  85. sourcecode-0.4.0/.planning/phases/07-grafos-de-codigo/07-RESEARCH.md +0 -165
  86. sourcecode-0.4.0/.planning/phases/08-documentacion-extraida/.gitkeep +0 -0
  87. sourcecode-0.4.0/.planning/phases/09-metricas-de-calidad/.gitkeep +0 -0
  88. sourcecode-0.4.0/.planning/phases/10-contexto-git-y-operativo/.gitkeep +0 -0
  89. sourcecode-0.4.0/.planning/research/ARCHITECTURE.md +0 -631
  90. sourcecode-0.4.0/.planning/research/FEATURES.md +0 -543
  91. sourcecode-0.4.0/.planning/research/PITFALLS.md +0 -341
  92. sourcecode-0.4.0/.planning/research/STACK.md +0 -436
  93. sourcecode-0.4.0/tests/test_integration_graph_modules.py +0 -66
  94. {sourcecode-0.4.0 → sourcecode-0.6.0}/.ruff.toml +0 -0
  95. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/classifier.py +0 -0
  96. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/dependency_analyzer.py +0 -0
  97. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/__init__.py +0 -0
  98. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/base.py +0 -0
  99. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/dart.py +0 -0
  100. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/dotnet.py +0 -0
  101. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/elixir.py +0 -0
  102. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/go.py +0 -0
  103. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/heuristic.py +0 -0
  104. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/java.py +0 -0
  105. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
  106. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/nodejs.py +0 -0
  107. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/parsers.py +0 -0
  108. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/php.py +0 -0
  109. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/project.py +0 -0
  110. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/python.py +0 -0
  111. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/ruby.py +0 -0
  112. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/rust.py +0 -0
  113. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/systems.py +0 -0
  114. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/terraform.py +0 -0
  115. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/detectors/tooling.py +0 -0
  116. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/redactor.py +0 -0
  117. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/scanner.py +0 -0
  118. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/serializer.py +0 -0
  119. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/tree_utils.py +0 -0
  120. {sourcecode-0.4.0 → sourcecode-0.6.0}/src/sourcecode/workspace.py +0 -0
  121. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/__init__.py +0 -0
  122. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/conftest.py +0 -0
  123. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
  124. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/fastapi_app/src/main.py +0 -0
  125. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/go_service/cmd/api/main.go +0 -0
  126. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/go_service/go.mod +0 -0
  127. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
  128. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/nextjs_app/package.json +0 -0
  129. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
  130. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
  131. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
  132. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
  133. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
  134. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
  135. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_classifier.py +0 -0
  136. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_dependency_analyzer_node_python.py +0 -0
  137. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_dependency_analyzer_polyglot.py +0 -0
  138. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_dependency_schema.py +0 -0
  139. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_detector_go_rust_java.py +0 -0
  140. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_detector_nodejs.py +0 -0
  141. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_detector_php_ruby_dart.py +0 -0
  142. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_detector_python.py +0 -0
  143. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_detector_universal_managed.py +0 -0
  144. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_detector_universal_systems.py +0 -0
  145. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_detectors_base.py +0 -0
  146. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_integration.py +0 -0
  147. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_integration_dependencies.py +0 -0
  148. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_integration_detection.py +0 -0
  149. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_integration_multistack.py +0 -0
  150. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_integration_universal.py +0 -0
  151. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_packaging.py +0 -0
  152. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_real_projects.py +0 -0
  153. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_redactor.py +0 -0
  154. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_scanner.py +0 -0
  155. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_schema.py +0 -0
  156. {sourcecode-0.4.0 → sourcecode-0.6.0}/tests/test_workspace_analyzer.py +0 -0
@@ -1,3 +1,4 @@
1
+ # Python cache and build artifacts
1
2
  __pycache__/
2
3
  *.pyc
3
4
  *.pyo
@@ -11,8 +12,7 @@ build/
11
12
  .mypy_cache/
12
13
  .ruff_cache/
13
14
  .pytest_cache/
14
- *.pyc
15
- /src/*.egg-info/
15
+ src/*.egg-info/
16
16
 
17
17
  # Editor / IDE
18
18
  .idea/
@@ -22,6 +22,12 @@ build/
22
22
  .claude/
23
23
  .codex/
24
24
 
25
+ # Environment / secrets
26
+ *.env
27
+ *.secret.json
28
+
25
29
  # OS cruft
26
30
  .DS_Store
27
31
  Thumbs.db
32
+
33
+ .planning
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcecode
3
- Version: 0.4.0
3
+ Version: 0.6.0
4
4
  Summary: Genera un mapa de contexto estructurado de proyectos de software para agentes IA
5
5
  License: MIT
6
6
  Requires-Python: >=3.9
@@ -58,6 +58,14 @@ Include an internal module graph with imports and simple structural relations:
58
58
  sourcecode . --graph-modules
59
59
  ```
60
60
 
61
+ Choose how much graph detail you want:
62
+
63
+ ```bash
64
+ sourcecode . --graph-modules --graph-detail high
65
+ sourcecode . --graph-modules --graph-detail medium
66
+ sourcecode . --graph-modules --graph-detail full
67
+ ```
68
+
61
69
  Show the version:
62
70
 
63
71
  ```bash
@@ -70,7 +78,10 @@ Main options:
70
78
  - `--output PATH`: write to a file instead of `stdout`.
71
79
  - `--compact`: return a reduced view with `schema_version`, `project_type`, `stacks`, `entry_points`, and `file_tree_depth1`.
72
80
  - `--dependencies`: include direct dependencies, resolved versions, and transitive relationships when lockfiles make that possible.
73
- - `--graph-modules`: include a structural graph with modules, imports, and simple relations such as `contains`, `calls`, or `extends`.
81
+ - `--graph-modules`: include a structural graph optimized for repository reasoning.
82
+ - `--graph-detail high|medium|full`: choose a summarized, balanced, or full-fidelity graph. Default: `high`.
83
+ - `--max-nodes INTEGER`: cap graph size in `high` and `medium` modes.
84
+ - `--graph-edges imports,calls,contains,extends`: override the default edge kinds for the selected detail level.
74
85
  - `--depth INTEGER`: maximum file tree depth.
75
86
  - `--no-redact`: disable secret redaction.
76
87
 
@@ -169,6 +180,7 @@ The full schema includes:
169
180
  - `dependencies`: optional dependency records with declared and resolved versions.
170
181
  - `dependency_summary`: optional summary with ecosystem coverage, counts, and known limitations.
171
182
  - `module_graph`: optional structural graph with nodes, edges, and analysis limits.
183
+ - `module_graph_summary`: compact graph summary optimized for downstream LLM consumption.
172
184
 
173
185
  Example dependency block:
174
186
 
@@ -219,52 +231,52 @@ Example module graph block:
219
231
  "module_graph": {
220
232
  "nodes": [
221
233
  {
222
- "id": "module:app/main.py",
234
+ "id": "module:app",
223
235
  "kind": "module",
224
236
  "language": "python",
225
- "path": "app/main.py",
237
+ "path": "app",
226
238
  "symbol": null,
227
- "display_name": "app/main.py",
228
- "workspace": null
229
- },
230
- {
231
- "id": "function:app/main.py:run",
232
- "kind": "function",
233
- "language": "python",
234
- "path": "app/main.py",
235
- "symbol": "run",
236
- "display_name": "run",
237
- "workspace": null
238
- }
239
- ],
240
- "edges": [
241
- {
242
- "source": "module:app/main.py",
243
- "target": "module:app/utils.py",
244
- "kind": "imports",
245
- "confidence": "high",
246
- "method": "ast"
247
- },
248
- {
249
- "source": "function:app/main.py:run",
250
- "target": "function:app/utils.py:helper",
251
- "kind": "calls",
252
- "confidence": "medium",
253
- "method": "ast"
239
+ "display_name": "app",
240
+ "workspace": null,
241
+ "importance": "high"
254
242
  }
255
243
  ],
244
+ "edges": [],
256
245
  "summary": {
257
246
  "requested": true,
258
- "node_count": 2,
259
- "edge_count": 2,
247
+ "node_count": 1,
248
+ "edge_count": 0,
260
249
  "languages": ["python"],
261
250
  "methods": ["ast"],
251
+ "main_flows": [],
252
+ "layers": ["app"],
253
+ "entry_points_count": 1,
254
+ "truncated": false,
255
+ "detail": "high",
256
+ "max_nodes_applied": 80,
257
+ "edge_kinds": ["imports"],
262
258
  "limitations": []
263
259
  }
260
+ },
261
+ "module_graph_summary": {
262
+ "requested": true,
263
+ "node_count": 1,
264
+ "edge_count": 0,
265
+ "main_flows": [],
266
+ "layers": ["app"],
267
+ "entry_points_count": 1,
268
+ "truncated": false,
269
+ "limitations": []
264
270
  }
265
271
  }
266
272
  ```
267
273
 
274
+ `--graph-modules` is now tiered for LLM workflows:
275
+
276
+ - `high`: summarized graph, modules only, imports only, directory collapsing when useful.
277
+ - `medium`: balanced graph with key functions and selected call edges.
278
+ - `full`: full-fidelity graph, equivalent to the previous exhaustive behavior.
279
+
268
280
  Graph analysis is also offline and conservative. `sourcecode` prefers partial but defensible edges over pretending to build a perfect semantic call graph, and it records parse failures, unresolved imports, or analysis budgets in `module_graph.summary.limitations`.
269
281
 
270
282
  Detailed reference: [docs/schema.md](/Users/user/Documents/workspace/atlas/atlas-cli/docs/schema.md).
@@ -42,6 +42,14 @@ Include an internal module graph with imports and simple structural relations:
42
42
  sourcecode . --graph-modules
43
43
  ```
44
44
 
45
+ Choose how much graph detail you want:
46
+
47
+ ```bash
48
+ sourcecode . --graph-modules --graph-detail high
49
+ sourcecode . --graph-modules --graph-detail medium
50
+ sourcecode . --graph-modules --graph-detail full
51
+ ```
52
+
45
53
  Show the version:
46
54
 
47
55
  ```bash
@@ -54,7 +62,10 @@ Main options:
54
62
  - `--output PATH`: write to a file instead of `stdout`.
55
63
  - `--compact`: return a reduced view with `schema_version`, `project_type`, `stacks`, `entry_points`, and `file_tree_depth1`.
56
64
  - `--dependencies`: include direct dependencies, resolved versions, and transitive relationships when lockfiles make that possible.
57
- - `--graph-modules`: include a structural graph with modules, imports, and simple relations such as `contains`, `calls`, or `extends`.
65
+ - `--graph-modules`: include a structural graph optimized for repository reasoning.
66
+ - `--graph-detail high|medium|full`: choose a summarized, balanced, or full-fidelity graph. Default: `high`.
67
+ - `--max-nodes INTEGER`: cap graph size in `high` and `medium` modes.
68
+ - `--graph-edges imports,calls,contains,extends`: override the default edge kinds for the selected detail level.
58
69
  - `--depth INTEGER`: maximum file tree depth.
59
70
  - `--no-redact`: disable secret redaction.
60
71
 
@@ -153,6 +164,7 @@ The full schema includes:
153
164
  - `dependencies`: optional dependency records with declared and resolved versions.
154
165
  - `dependency_summary`: optional summary with ecosystem coverage, counts, and known limitations.
155
166
  - `module_graph`: optional structural graph with nodes, edges, and analysis limits.
167
+ - `module_graph_summary`: compact graph summary optimized for downstream LLM consumption.
156
168
 
157
169
  Example dependency block:
158
170
 
@@ -203,52 +215,52 @@ Example module graph block:
203
215
  "module_graph": {
204
216
  "nodes": [
205
217
  {
206
- "id": "module:app/main.py",
218
+ "id": "module:app",
207
219
  "kind": "module",
208
220
  "language": "python",
209
- "path": "app/main.py",
221
+ "path": "app",
210
222
  "symbol": null,
211
- "display_name": "app/main.py",
212
- "workspace": null
213
- },
214
- {
215
- "id": "function:app/main.py:run",
216
- "kind": "function",
217
- "language": "python",
218
- "path": "app/main.py",
219
- "symbol": "run",
220
- "display_name": "run",
221
- "workspace": null
222
- }
223
- ],
224
- "edges": [
225
- {
226
- "source": "module:app/main.py",
227
- "target": "module:app/utils.py",
228
- "kind": "imports",
229
- "confidence": "high",
230
- "method": "ast"
231
- },
232
- {
233
- "source": "function:app/main.py:run",
234
- "target": "function:app/utils.py:helper",
235
- "kind": "calls",
236
- "confidence": "medium",
237
- "method": "ast"
223
+ "display_name": "app",
224
+ "workspace": null,
225
+ "importance": "high"
238
226
  }
239
227
  ],
228
+ "edges": [],
240
229
  "summary": {
241
230
  "requested": true,
242
- "node_count": 2,
243
- "edge_count": 2,
231
+ "node_count": 1,
232
+ "edge_count": 0,
244
233
  "languages": ["python"],
245
234
  "methods": ["ast"],
235
+ "main_flows": [],
236
+ "layers": ["app"],
237
+ "entry_points_count": 1,
238
+ "truncated": false,
239
+ "detail": "high",
240
+ "max_nodes_applied": 80,
241
+ "edge_kinds": ["imports"],
246
242
  "limitations": []
247
243
  }
244
+ },
245
+ "module_graph_summary": {
246
+ "requested": true,
247
+ "node_count": 1,
248
+ "edge_count": 0,
249
+ "main_flows": [],
250
+ "layers": ["app"],
251
+ "entry_points_count": 1,
252
+ "truncated": false,
253
+ "limitations": []
248
254
  }
249
255
  }
250
256
  ```
251
257
 
258
+ `--graph-modules` is now tiered for LLM workflows:
259
+
260
+ - `high`: summarized graph, modules only, imports only, directory collapsing when useful.
261
+ - `medium`: balanced graph with key functions and selected call edges.
262
+ - `full`: full-fidelity graph, equivalent to the previous exhaustive behavior.
263
+
252
264
  Graph analysis is also offline and conservative. `sourcecode` prefers partial but defensible edges over pretending to build a perfect semantic call graph, and it records parse failures, unresolved imports, or analysis budgets in `module_graph.summary.limitations`.
253
265
 
254
266
  Detailed reference: [docs/schema.md](/Users/user/Documents/workspace/atlas/atlas-cli/docs/schema.md).
@@ -27,6 +27,7 @@ Campos:
27
27
  - `dependencies`: dependencias detectadas cuando se solicita `--dependencies`.
28
28
  - `dependency_summary`: resumen del analisis de dependencias o `null` si no se solicito.
29
29
  - `module_graph`: grafo estructural de codigo o `null` si no se solicito `--graph-modules`.
30
+ - `module_graph_summary`: resumen compacto del grafo pensado para consumo rapido por LLMs.
30
31
 
31
32
  ## metadata
32
33
 
@@ -34,7 +35,7 @@ Campos:
34
35
  {
35
36
  "schema_version": "1.0",
36
37
  "generated_at": "2026-04-07T19:41:05.686277+00:00",
37
- "sourcecode_version": "0.4.0",
38
+ "sourcecode_version": "0.6.0",
38
39
  "analyzed_path": "/abs/path/to/project"
39
40
  }
40
41
  ```
@@ -215,46 +216,30 @@ Cuando se usa `--graph-modules`, `module_graph` expone nodos, aristas y un resum
215
216
  {
216
217
  "nodes": [
217
218
  {
218
- "id": "module:app/main.py",
219
+ "id": "module:app",
219
220
  "kind": "module",
220
221
  "language": "python",
221
- "path": "app/main.py",
222
+ "path": "app",
222
223
  "symbol": null,
223
- "display_name": "app/main.py",
224
- "workspace": null
225
- },
226
- {
227
- "id": "function:app/main.py:run",
228
- "kind": "function",
229
- "language": "python",
230
- "path": "app/main.py",
231
- "symbol": "run",
232
- "display_name": "run",
233
- "workspace": null
234
- }
235
- ],
236
- "edges": [
237
- {
238
- "source": "module:app/main.py",
239
- "target": "module:app/utils.py",
240
- "kind": "imports",
241
- "confidence": "high",
242
- "method": "ast"
243
- },
244
- {
245
- "source": "function:app/main.py:run",
246
- "target": "function:app/utils.py:helper",
247
- "kind": "calls",
248
- "confidence": "medium",
249
- "method": "ast"
224
+ "display_name": "app",
225
+ "workspace": null,
226
+ "importance": "high"
250
227
  }
251
228
  ],
229
+ "edges": [],
252
230
  "summary": {
253
231
  "requested": true,
254
- "node_count": 2,
255
- "edge_count": 2,
232
+ "node_count": 1,
233
+ "edge_count": 0,
256
234
  "languages": ["python"],
257
235
  "methods": ["ast"],
236
+ "main_flows": [],
237
+ "layers": ["app"],
238
+ "entry_points_count": 1,
239
+ "truncated": false,
240
+ "detail": "high",
241
+ "max_nodes_applied": 80,
242
+ "edge_kinds": ["imports"],
258
243
  "limitations": []
259
244
  }
260
245
  }
@@ -271,6 +256,7 @@ Cada nodo describe un modulo o simbolo relevante:
271
256
  - `symbol`: simbolo asociado si aplica.
272
257
  - `display_name`: nombre legible para consumidores humanos.
273
258
  - `workspace`: workspace relativa cuando el nodo pertenece a un subproyecto.
259
+ - `importance`: importancia relativa del nodo (`high`, `medium`, `low`) usada para trimming y tambien expuesta al consumidor.
274
260
 
275
261
  ### module_graph.edges
276
262
 
@@ -291,8 +277,30 @@ Resume cobertura y limites del analisis:
291
277
  - `edge_count`: numero total de aristas emitidas.
292
278
  - `languages`: lenguajes presentes en el grafo.
293
279
  - `methods`: metodos usados para construir las aristas.
280
+ - `main_flows`: rutas principales inferidas desde entry points siguiendo cadenas de imports/calls de forma best-effort.
281
+ - `layers`: capas o clusters inferidos desde la estructura de directorios.
282
+ - `entry_points_count`: numero de entry points considerados al construir el resumen.
283
+ - `truncated`: `true` si se aplico recorte por `--max-nodes`.
284
+ - `detail`: nivel activo del grafo (`high`, `medium`, `full`).
285
+ - `max_nodes_applied`: presupuesto de nodos aplicado en `high` o `medium`.
286
+ - `edge_kinds`: tipos de arista incluidos finalmente en la salida.
294
287
  - `limitations`: parse errors, imports no resueltos, archivos omitidos o limites de presupuesto aplicados.
295
288
 
289
+ ## module_graph_summary
290
+
291
+ `module_graph_summary` replica el resumen esencial del grafo en un bloque top-level para que consumidores con ventanas de contexto pequeñas no tengan que recorrer `module_graph` completo.
292
+
293
+ Campos principales:
294
+
295
+ - `requested`
296
+ - `node_count`
297
+ - `edge_count`
298
+ - `main_flows`
299
+ - `layers`
300
+ - `entry_points_count`
301
+ - `truncated`
302
+ - `limitations`
303
+
296
304
  ## Modo compacto
297
305
 
298
306
  Con `--compact`, la salida no incluye `metadata` ni el arbol completo. Devuelve:
@@ -317,6 +325,7 @@ Campos:
317
325
 
318
326
  `--compact` no incluye `dependencies` ni `dependency_summary`, aunque se combine con `--dependencies`.
319
327
  Tampoco incluye `module_graph`, aunque se combine con `--graph-modules`.
328
+ Tampoco incluye `module_graph_summary`.
320
329
 
321
330
  ## Ejemplo completo
322
331
 
@@ -327,7 +336,7 @@ Ejemplo real de salida para un monorepo con web Node.js y API Python:
327
336
  "metadata": {
328
337
  "schema_version": "1.0",
329
338
  "generated_at": "2026-04-07T19:41:05.686277+00:00",
330
- "sourcecode_version": "0.4.0",
339
+ "sourcecode_version": "0.6.0",
331
340
  "analyzed_path": "/abs/path/to/project"
332
341
  },
333
342
  "file_tree": {
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "sourcecode"
7
- version = "0.4.0"
7
+ version = "0.6.0"
8
8
  description = "Genera un mapa de contexto estructurado de proyectos de software para agentes IA"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,3 +1,3 @@
1
1
  """sourcecode — Genera mapas de contexto estructurado para agentes IA."""
2
2
 
3
- __version__ = "0.4.0"
3
+ __version__ = "0.6.0"
@@ -3,7 +3,7 @@ from __future__ import annotations
3
3
 
4
4
  import json
5
5
  from pathlib import Path
6
- from typing import Any, Optional
6
+ from typing import Any, Optional, cast
7
7
 
8
8
  import typer
9
9
 
@@ -16,6 +16,8 @@ app = typer.Typer(
16
16
  )
17
17
 
18
18
  FORMAT_CHOICES = ["json", "yaml"]
19
+ GRAPH_DETAIL_CHOICES = ["high", "medium", "full"]
20
+ GRAPH_EDGE_CHOICES = {"imports", "calls", "contains", "extends"}
19
21
 
20
22
 
21
23
  def version_callback(value: bool) -> None:
@@ -56,6 +58,23 @@ def main(
56
58
  "--graph-modules",
57
59
  help="Incluir grafo estructural de modulos, imports y relaciones simples del codigo",
58
60
  ),
61
+ graph_detail: str = typer.Option(
62
+ "high",
63
+ "--graph-detail",
64
+ help="Nivel de detalle del grafo: high|medium|full",
65
+ show_default=True,
66
+ ),
67
+ max_nodes: Optional[int] = typer.Option(
68
+ None,
69
+ "--max-nodes",
70
+ help="Limite de nodos para `--graph-modules` en modos high/medium",
71
+ min=1,
72
+ ),
73
+ graph_edges: Optional[str] = typer.Option(
74
+ None,
75
+ "--graph-edges",
76
+ help="Tipos de arista para `--graph-modules` separados por comas: imports,calls,contains,extends",
77
+ ),
59
78
  no_redact: bool = typer.Option(
60
79
  False,
61
80
  "--no-redact",
@@ -85,6 +104,12 @@ def main(
85
104
  err=True,
86
105
  )
87
106
  raise typer.Exit(code=1)
107
+ if graph_detail not in GRAPH_DETAIL_CHOICES:
108
+ typer.echo(
109
+ f"Error: valor invalido '{graph_detail}' para --graph-detail. Opciones: {', '.join(GRAPH_DETAIL_CHOICES)}",
110
+ err=True,
111
+ )
112
+ raise typer.Exit(code=1)
88
113
 
89
114
  # Resolver y validar path
90
115
  target = path.resolve()
@@ -100,7 +125,7 @@ def main(
100
125
 
101
126
  from sourcecode.dependency_analyzer import DependencyAnalyzer
102
127
  from sourcecode.detectors import ProjectDetector, build_default_detectors
103
- from sourcecode.graph_analyzer import GraphAnalyzer
128
+ from sourcecode.graph_analyzer import GraphAnalyzer, GraphDetail
104
129
  from sourcecode.redactor import SecretRedactor, redact_dict
105
130
  from sourcecode.scanner import FileScanner
106
131
  from sourcecode.schema import AnalysisMetadata, EntryPoint, SourceMap, StackDetection
@@ -151,6 +176,21 @@ def main(
151
176
  workspace_analysis = WorkspaceAnalyzer().analyze(target, manifests)
152
177
  dependency_analyzer = DependencyAnalyzer() if dependencies else None
153
178
  graph_analyzer = GraphAnalyzer() if graph_modules else None
179
+ parsed_graph_edges = (
180
+ {edge.strip() for edge in graph_edges.split(",") if edge.strip()}
181
+ if graph_edges
182
+ else None
183
+ )
184
+ if parsed_graph_edges is not None:
185
+ invalid_edges = sorted(parsed_graph_edges - GRAPH_EDGE_CHOICES)
186
+ if invalid_edges:
187
+ typer.echo(
188
+ "Error: valores invalidos para --graph-edges: "
189
+ f"{', '.join(invalid_edges)}. Opciones: {', '.join(sorted(GRAPH_EDGE_CHOICES))}",
190
+ err=True,
191
+ )
192
+ raise typer.Exit(code=1)
193
+ graph_detail_typed = cast(GraphDetail, graph_detail)
154
194
 
155
195
  root_manifests = [
156
196
  manifest
@@ -180,7 +220,14 @@ def main(
180
220
  if workspace_analysis.workspaces
181
221
  else file_tree
182
222
  )
183
- module_graphs.append(graph_analyzer.analyze(target, root_graph_tree))
223
+ module_graphs.append(
224
+ graph_analyzer.analyze(
225
+ target,
226
+ root_graph_tree,
227
+ detail="full",
228
+ entry_points=entry_points,
229
+ )
230
+ )
184
231
 
185
232
  for workspace in workspace_analysis.workspaces:
186
233
  workspace_root = target / workspace.path
@@ -215,10 +262,12 @@ def main(
215
262
  dependency_summaries.append(workspace_summary)
216
263
  if graph_analyzer is not None:
217
264
  workspace_graph = graph_analyzer.analyze(
218
- workspace_root,
219
- workspace_tree,
220
- workspace=workspace.path,
221
- )
265
+ workspace_root,
266
+ workspace_tree,
267
+ workspace=workspace.path,
268
+ detail="full",
269
+ entry_points=workspace_entry_points,
270
+ )
222
271
  module_graphs.append(
223
272
  graph_analyzer.prefix_graph(workspace_graph, workspace.path, workspace.path)
224
273
  )
@@ -234,7 +283,17 @@ def main(
234
283
  if dependency_analyzer is not None
235
284
  else None
236
285
  )
237
- module_graph = graph_analyzer.merge_graphs(module_graphs) if graph_analyzer is not None else None
286
+ module_graph = (
287
+ graph_analyzer.merge_graphs(
288
+ module_graphs,
289
+ detail=graph_detail_typed,
290
+ edge_kinds=parsed_graph_edges,
291
+ max_nodes=max_nodes,
292
+ entry_points=entry_points,
293
+ )
294
+ if graph_analyzer is not None
295
+ else None
296
+ )
238
297
 
239
298
  # 3. Construir el schema
240
299
  metadata = AnalysisMetadata(analyzed_path=str(target))
@@ -247,6 +306,7 @@ def main(
247
306
  dependencies=dependency_records,
248
307
  dependency_summary=dependency_summary,
249
308
  module_graph=module_graph,
309
+ module_graph_summary=module_graph.summary if module_graph is not None else None,
250
310
  )
251
311
 
252
312
  # 4. Serializar (con o sin modo compact)