sourcecode 0.20.0__tar.gz → 0.21.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.
- {sourcecode-0.20.0 → sourcecode-0.21.0}/PKG-INFO +70 -1
- {sourcecode-0.20.0 → sourcecode-0.21.0}/README.md +69 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/docs/schema.md +2 -2
- {sourcecode-0.20.0 → sourcecode-0.21.0}/pyproject.toml +1 -1
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/cli.py +93 -17
- sourcecode-0.21.0/src/sourcecode/prepare_context.py +486 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/semantic_analyzer.py +2 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_dependency_analyzer_node_python.py +2 -2
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_integration_dependencies.py +1 -1
- sourcecode-0.20.0/src/sourcecode/prepare_context.py +0 -197
- {sourcecode-0.20.0 → sourcecode-0.21.0}/.gitignore +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/.ruff.toml +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/serializer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/__init__.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/conftest.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/coverage.xml +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/jacoco.xml +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/lcov.info +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_architecture_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_architecture_summary.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_classifier.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_cli.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_code_notes_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_coverage_parser.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_cross_consistency.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_dependency_schema.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_detector_python.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_detectors_base.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_graph_schema.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_integration.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_integration_detection.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_integration_docs.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_integration_lqn.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_integration_metrics.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_integration_multistack.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_integration_semantics.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_integration_universal.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_metrics_analyzer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_packaging.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_real_projects.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_redactor.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_scanner.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_schema.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_schema_normalization.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_semantic_analyzer_node.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_semantic_analyzer_python.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_semantic_import_resolution.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_semantic_schema.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_summarizer.py +0 -0
- {sourcecode-0.20.0 → sourcecode-0.21.0}/tests/test_workspace_analyzer.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.21.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
|
|
@@ -636,6 +636,75 @@ Combine flags for a comprehensive project handoff:
|
|
|
636
636
|
sourcecode --compact --env-map --code-notes --git-context .
|
|
637
637
|
```
|
|
638
638
|
|
|
639
|
+
## `prepare-context` — Task-aware context for LLMs
|
|
640
|
+
|
|
641
|
+
`prepare-context` is a subcommand that builds a focused, task-specific context optimized for LLM reasoning. Instead of a full project dump, it returns only the data an LLM needs for a specific goal.
|
|
642
|
+
|
|
643
|
+
> **Note:** Because `sourcecode` has a positional `PATH` argument, you must provide it explicitly before the subcommand:
|
|
644
|
+
> ```bash
|
|
645
|
+
> sourcecode . prepare-context <task> # current directory
|
|
646
|
+
> sourcecode /my/project prepare-context <task>
|
|
647
|
+
> ```
|
|
648
|
+
|
|
649
|
+
### Available tasks
|
|
650
|
+
|
|
651
|
+
| Task | Goal | Output |
|
|
652
|
+
|------|------|--------|
|
|
653
|
+
| `explain` | Onboard an LLM to the project | `project_summary`, `architecture_summary`, `relevant_files`, `key_dependencies` |
|
|
654
|
+
| `fix-bug` | Identify likely bug locations | `relevant_files` (ranked by risk), `suspected_areas`, `code_notes_summary` |
|
|
655
|
+
| `refactor` | Surface improvement opportunities | `relevant_files`, `improvement_opportunities`, `architecture_summary` |
|
|
656
|
+
| `generate-tests` | Find untested areas | `test_gaps`, `relevant_files` (source without tests), `key_dependencies` |
|
|
657
|
+
|
|
658
|
+
### Usage
|
|
659
|
+
|
|
660
|
+
```bash
|
|
661
|
+
# List tasks with descriptions
|
|
662
|
+
sourcecode . prepare-context --task-help
|
|
663
|
+
|
|
664
|
+
# Explain the project
|
|
665
|
+
sourcecode . prepare-context explain
|
|
666
|
+
|
|
667
|
+
# Find bug areas, with a ready-to-paste LLM prompt
|
|
668
|
+
sourcecode . prepare-context fix-bug --llm-prompt
|
|
669
|
+
|
|
670
|
+
# Find untested files in a specific project
|
|
671
|
+
sourcecode . prepare-context generate-tests --path /my/project
|
|
672
|
+
|
|
673
|
+
# Preview what will be analyzed (no analysis run)
|
|
674
|
+
sourcecode . prepare-context refactor --dry-run
|
|
675
|
+
```
|
|
676
|
+
|
|
677
|
+
### Output format
|
|
678
|
+
|
|
679
|
+
```json
|
|
680
|
+
{
|
|
681
|
+
"task": "fix-bug",
|
|
682
|
+
"goal": "Identify the most likely files and areas where a bug may be located.",
|
|
683
|
+
"project_summary": "CLI en Python (Typer). Entry points: src/cli.py. 4 dependencias.",
|
|
684
|
+
"architecture_summary": null,
|
|
685
|
+
"relevant_files": [
|
|
686
|
+
{ "path": "src/handler.py", "role": "source", "score": 2.0, "reason": "matches 'handler'" },
|
|
687
|
+
{ "path": "src/cli.py", "role": "entrypoint", "score": 3.0, "reason": "entry point" }
|
|
688
|
+
],
|
|
689
|
+
"suspected_areas": ["src/handler.py (2 annotations)", "src/parser.py (1 annotation)"],
|
|
690
|
+
"code_notes_summary": { "total": 5, "by_kind": { "FIXME": 3, "BUG": 2 }, "top_files": ["src/handler.py"] }
|
|
691
|
+
}
|
|
692
|
+
```
|
|
693
|
+
|
|
694
|
+
### `--llm-prompt`
|
|
695
|
+
|
|
696
|
+
Add `--llm-prompt` to include a ready-to-use prompt that you can paste directly into any LLM:
|
|
697
|
+
|
|
698
|
+
```bash
|
|
699
|
+
sourcecode . prepare-context explain --llm-prompt | jq -r '.llm_prompt'
|
|
700
|
+
```
|
|
701
|
+
|
|
702
|
+
The prompt is task-specific and includes the project context, relevant files, and concrete instructions for the LLM.
|
|
703
|
+
|
|
704
|
+
### Task auto-selection with `--agent`
|
|
705
|
+
|
|
706
|
+
For zero-config usage, `--agent` on the main command automatically selects the right flags for the project type. For task-aware context, use `prepare-context` explicitly with the task that matches your goal.
|
|
707
|
+
|
|
639
708
|
## Development
|
|
640
709
|
|
|
641
710
|
Editable install with development dependencies:
|
|
@@ -620,6 +620,75 @@ Combine flags for a comprehensive project handoff:
|
|
|
620
620
|
sourcecode --compact --env-map --code-notes --git-context .
|
|
621
621
|
```
|
|
622
622
|
|
|
623
|
+
## `prepare-context` — Task-aware context for LLMs
|
|
624
|
+
|
|
625
|
+
`prepare-context` is a subcommand that builds a focused, task-specific context optimized for LLM reasoning. Instead of a full project dump, it returns only the data an LLM needs for a specific goal.
|
|
626
|
+
|
|
627
|
+
> **Note:** Because `sourcecode` has a positional `PATH` argument, you must provide it explicitly before the subcommand:
|
|
628
|
+
> ```bash
|
|
629
|
+
> sourcecode . prepare-context <task> # current directory
|
|
630
|
+
> sourcecode /my/project prepare-context <task>
|
|
631
|
+
> ```
|
|
632
|
+
|
|
633
|
+
### Available tasks
|
|
634
|
+
|
|
635
|
+
| Task | Goal | Output |
|
|
636
|
+
|------|------|--------|
|
|
637
|
+
| `explain` | Onboard an LLM to the project | `project_summary`, `architecture_summary`, `relevant_files`, `key_dependencies` |
|
|
638
|
+
| `fix-bug` | Identify likely bug locations | `relevant_files` (ranked by risk), `suspected_areas`, `code_notes_summary` |
|
|
639
|
+
| `refactor` | Surface improvement opportunities | `relevant_files`, `improvement_opportunities`, `architecture_summary` |
|
|
640
|
+
| `generate-tests` | Find untested areas | `test_gaps`, `relevant_files` (source without tests), `key_dependencies` |
|
|
641
|
+
|
|
642
|
+
### Usage
|
|
643
|
+
|
|
644
|
+
```bash
|
|
645
|
+
# List tasks with descriptions
|
|
646
|
+
sourcecode . prepare-context --task-help
|
|
647
|
+
|
|
648
|
+
# Explain the project
|
|
649
|
+
sourcecode . prepare-context explain
|
|
650
|
+
|
|
651
|
+
# Find bug areas, with a ready-to-paste LLM prompt
|
|
652
|
+
sourcecode . prepare-context fix-bug --llm-prompt
|
|
653
|
+
|
|
654
|
+
# Find untested files in a specific project
|
|
655
|
+
sourcecode . prepare-context generate-tests --path /my/project
|
|
656
|
+
|
|
657
|
+
# Preview what will be analyzed (no analysis run)
|
|
658
|
+
sourcecode . prepare-context refactor --dry-run
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
### Output format
|
|
662
|
+
|
|
663
|
+
```json
|
|
664
|
+
{
|
|
665
|
+
"task": "fix-bug",
|
|
666
|
+
"goal": "Identify the most likely files and areas where a bug may be located.",
|
|
667
|
+
"project_summary": "CLI en Python (Typer). Entry points: src/cli.py. 4 dependencias.",
|
|
668
|
+
"architecture_summary": null,
|
|
669
|
+
"relevant_files": [
|
|
670
|
+
{ "path": "src/handler.py", "role": "source", "score": 2.0, "reason": "matches 'handler'" },
|
|
671
|
+
{ "path": "src/cli.py", "role": "entrypoint", "score": 3.0, "reason": "entry point" }
|
|
672
|
+
],
|
|
673
|
+
"suspected_areas": ["src/handler.py (2 annotations)", "src/parser.py (1 annotation)"],
|
|
674
|
+
"code_notes_summary": { "total": 5, "by_kind": { "FIXME": 3, "BUG": 2 }, "top_files": ["src/handler.py"] }
|
|
675
|
+
}
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
### `--llm-prompt`
|
|
679
|
+
|
|
680
|
+
Add `--llm-prompt` to include a ready-to-use prompt that you can paste directly into any LLM:
|
|
681
|
+
|
|
682
|
+
```bash
|
|
683
|
+
sourcecode . prepare-context explain --llm-prompt | jq -r '.llm_prompt'
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
The prompt is task-specific and includes the project context, relevant files, and concrete instructions for the LLM.
|
|
687
|
+
|
|
688
|
+
### Task auto-selection with `--agent`
|
|
689
|
+
|
|
690
|
+
For zero-config usage, `--agent` on the main command automatically selects the right flags for the project type. For task-aware context, use `prepare-context` explicitly with the task that matches your goal.
|
|
691
|
+
|
|
623
692
|
## Development
|
|
624
693
|
|
|
625
694
|
Editable install with development dependencies:
|
|
@@ -81,7 +81,7 @@ Campos:
|
|
|
81
81
|
{
|
|
82
82
|
"schema_version": "1.0",
|
|
83
83
|
"generated_at": "2026-04-07T19:41:05.686277+00:00",
|
|
84
|
-
"sourcecode_version": "0.
|
|
84
|
+
"sourcecode_version": "0.21.0",
|
|
85
85
|
"analyzed_path": "/abs/path/to/project"
|
|
86
86
|
}
|
|
87
87
|
```
|
|
@@ -645,7 +645,7 @@ Ejemplo de salida para un monorepo con web Node.js y API Python con `--dependenc
|
|
|
645
645
|
"metadata": {
|
|
646
646
|
"schema_version": "1.0",
|
|
647
647
|
"generated_at": "2026-04-07T19:41:05.686277+00:00",
|
|
648
|
-
"sourcecode_version": "0.
|
|
648
|
+
"sourcecode_version": "0.21.0",
|
|
649
649
|
"analyzed_path": "/abs/path/to/project"
|
|
650
650
|
},
|
|
651
651
|
"file_tree": {
|
|
@@ -163,6 +163,10 @@ def main(
|
|
|
163
163
|
),
|
|
164
164
|
) -> None:
|
|
165
165
|
"""Genera un mapa de contexto estructurado del proyecto en formato JSON o YAML."""
|
|
166
|
+
# When a subcommand (e.g. prepare-context) is invoked, skip the main analysis.
|
|
167
|
+
if ctx.invoked_subcommand is not None:
|
|
168
|
+
return
|
|
169
|
+
|
|
166
170
|
# Validar formato
|
|
167
171
|
if format not in FORMAT_CHOICES:
|
|
168
172
|
typer.echo(
|
|
@@ -654,31 +658,103 @@ def main(
|
|
|
654
658
|
|
|
655
659
|
@app.command("prepare-context")
|
|
656
660
|
def prepare_context_cmd(
|
|
657
|
-
task: str = typer.Argument(
|
|
658
|
-
|
|
661
|
+
task: Optional[str] = typer.Argument(
|
|
662
|
+
None,
|
|
663
|
+
help="Task: explain | fix-bug | refactor | generate-tests",
|
|
664
|
+
),
|
|
665
|
+
path: Path = typer.Option(
|
|
666
|
+
Path("."),
|
|
667
|
+
"--path", "-p",
|
|
668
|
+
help="Project directory to analyze (default: current directory)",
|
|
669
|
+
),
|
|
670
|
+
llm_prompt: bool = typer.Option(
|
|
671
|
+
False,
|
|
672
|
+
"--llm-prompt",
|
|
673
|
+
help="Append a ready-to-use LLM prompt to the output",
|
|
674
|
+
),
|
|
675
|
+
task_help: bool = typer.Option(
|
|
676
|
+
False,
|
|
677
|
+
"--task-help",
|
|
678
|
+
help="List available tasks with descriptions and exit",
|
|
679
|
+
),
|
|
680
|
+
dry_run: bool = typer.Option(
|
|
681
|
+
False,
|
|
682
|
+
"--dry-run",
|
|
683
|
+
help="Show what would be analyzed without running it",
|
|
684
|
+
),
|
|
659
685
|
) -> None:
|
|
660
|
-
"""
|
|
661
|
-
|
|
686
|
+
"""Prepare task-aware context optimized for LLM reasoning.
|
|
687
|
+
|
|
688
|
+
\b
|
|
689
|
+
Note: PATH must be provided before the subcommand (default: '.'):
|
|
690
|
+
sourcecode . prepare-context explain
|
|
691
|
+
sourcecode . prepare-context fix-bug --path /my/project
|
|
692
|
+
sourcecode . prepare-context generate-tests --llm-prompt
|
|
693
|
+
sourcecode . prepare-context --task-help
|
|
694
|
+
"""
|
|
695
|
+
from sourcecode.prepare_context import TASKS, TaskContextBuilder
|
|
696
|
+
|
|
697
|
+
if task_help:
|
|
698
|
+
typer.echo("Available tasks:\n")
|
|
699
|
+
for name, spec in TASKS.items():
|
|
700
|
+
typer.echo(f" {name:<20} {spec.description}")
|
|
701
|
+
typer.echo(f" {'':20} Output: {spec.output_hint}\n")
|
|
702
|
+
raise typer.Exit()
|
|
662
703
|
|
|
663
|
-
|
|
704
|
+
if task is None:
|
|
705
|
+
typer.echo(
|
|
706
|
+
f"Error: task is required. Available: {', '.join(TASKS)}\n"
|
|
707
|
+
"Use --task-help for descriptions.",
|
|
708
|
+
err=True,
|
|
709
|
+
)
|
|
710
|
+
raise typer.Exit(code=1)
|
|
664
711
|
|
|
665
|
-
|
|
712
|
+
if task not in TASKS:
|
|
713
|
+
typer.echo(
|
|
714
|
+
f"Error: unknown task '{task}'. Available: {', '.join(TASKS)}",
|
|
715
|
+
err=True,
|
|
716
|
+
)
|
|
717
|
+
raise typer.Exit(code=1)
|
|
666
718
|
|
|
719
|
+
target = path.resolve()
|
|
667
720
|
if not target.exists() or not target.is_dir():
|
|
668
721
|
typer.echo(f"Error: '{target}' no es un directorio válido.", err=True)
|
|
669
722
|
raise typer.Exit(code=1)
|
|
670
723
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
"
|
|
676
|
-
"
|
|
677
|
-
|
|
678
|
-
"
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
724
|
+
if dry_run:
|
|
725
|
+
spec = TASKS[task]
|
|
726
|
+
typer.echo(f"task: {task}")
|
|
727
|
+
typer.echo(f"goal: {spec.goal}")
|
|
728
|
+
typer.echo(f"path: {target}")
|
|
729
|
+
typer.echo(f"analyzers: dependencies={'yes' if spec.enable_dependencies else 'no'}"
|
|
730
|
+
f", code_notes={'yes' if spec.enable_code_notes else 'no'}")
|
|
731
|
+
typer.echo(f"output: {spec.output_hint}")
|
|
732
|
+
raise typer.Exit()
|
|
733
|
+
|
|
734
|
+
from dataclasses import asdict
|
|
735
|
+
|
|
736
|
+
builder = TaskContextBuilder(target)
|
|
737
|
+
output = builder.build(task)
|
|
738
|
+
|
|
739
|
+
out: dict[str, Any] = {
|
|
740
|
+
"task": output.task,
|
|
741
|
+
"goal": output.goal,
|
|
742
|
+
"project_summary": output.project_summary,
|
|
743
|
+
"architecture_summary": output.architecture_summary,
|
|
744
|
+
"relevant_files": [asdict(f) for f in output.relevant_files],
|
|
745
|
+
"key_dependencies": output.key_dependencies,
|
|
682
746
|
}
|
|
747
|
+
if output.suspected_areas:
|
|
748
|
+
out["suspected_areas"] = output.suspected_areas
|
|
749
|
+
if output.improvement_opportunities:
|
|
750
|
+
out["improvement_opportunities"] = output.improvement_opportunities
|
|
751
|
+
if output.test_gaps:
|
|
752
|
+
out["test_gaps"] = output.test_gaps
|
|
753
|
+
if output.code_notes_summary:
|
|
754
|
+
out["code_notes_summary"] = output.code_notes_summary
|
|
755
|
+
if output.limitations:
|
|
756
|
+
out["limitations"] = output.limitations
|
|
757
|
+
if llm_prompt:
|
|
758
|
+
out["llm_prompt"] = builder.render_prompt(output)
|
|
683
759
|
|
|
684
760
|
typer.echo(json.dumps(out, indent=2, ensure_ascii=False))
|