sourcecode 1.30.30__tar.gz → 1.31.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-1.31.0/.continue-here.md +101 -0
- sourcecode-1.30.30/.sourcecode-cache/snapshot-85d4217-37df4554.json → sourcecode-1.31.0/.sourcecode-cache/snapshot-0e430c1-37df4554.json +2 -2
- sourcecode-1.30.30/.sourcecode-cache/snapshot-85d4217-e9801942.json → sourcecode-1.31.0/.sourcecode-cache/snapshot-0e430c1-e9801942.json +19 -18
- sourcecode-1.30.30/.sourcecode-cache/snapshot-c6e9d39-ee60e0cd.json → sourcecode-1.31.0/.sourcecode-cache/snapshot-0e430c1-ee60e0cd.json +24 -26
- {sourcecode-1.30.30 → sourcecode-1.31.0}/PKG-INFO +6 -3
- {sourcecode-1.30.30 → sourcecode-1.31.0}/README.md +2 -2
- {sourcecode-1.30.30 → sourcecode-1.31.0}/pyproject.toml +5 -1
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/__init__.py +1 -1
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/cli.py +272 -1
- sourcecode-1.31.0/src/sourcecode/mcp/__init__.py +5 -0
- sourcecode-1.31.0/src/sourcecode/mcp/onboarding/__init__.py +1 -0
- sourcecode-1.31.0/src/sourcecode/mcp/onboarding/applier.py +63 -0
- sourcecode-1.31.0/src/sourcecode/mcp/onboarding/backup.py +40 -0
- sourcecode-1.31.0/src/sourcecode/mcp/onboarding/detector.py +59 -0
- sourcecode-1.31.0/src/sourcecode/mcp/onboarding/planner.py +40 -0
- sourcecode-1.31.0/src/sourcecode/mcp/runner.py +40 -0
- sourcecode-1.31.0/src/sourcecode/mcp/server.py +147 -0
- sourcecode-1.31.0/tests/test_mcp_runner.py +65 -0
- sourcecode-1.31.0/tests/test_mcp_serve.py +47 -0
- sourcecode-1.31.0/tests/test_mcp_tools.py +242 -0
- sourcecode-1.30.30/.continue-here.md +0 -150
- sourcecode-1.30.30/.sourcecode-cache/snapshot-85d4217-0911b79e.json +0 -3492
- sourcecode-1.30.30/.sourcecode-cache/snapshot-85d4217-624321f3.json +0 -11466
- sourcecode-1.30.30/.sourcecode-cache/snapshot-85d4217-776b4676.json +0 -367
- sourcecode-1.30.30/.sourcecode-cache/snapshot-85d4217-9770fba7.json +0 -374
- sourcecode-1.30.30/.sourcecode-cache/snapshot-85d4217-c4e3c102.json +0 -262
- sourcecode-1.30.30/.sourcecode-cache/snapshot-85d4217-e8bc5fb4.json +0 -122
- sourcecode-1.30.30/.sourcecode-cache/snapshot-85d4217-ee60e0cd.json +0 -328
- sourcecode-1.30.30/.sourcecode-cache/snapshot-85d4217-fdd9d3f7.json +0 -514
- sourcecode-1.30.30/.sourcecode-cache/snapshot-c6e9d39-0911b79e.json +0 -3471
- sourcecode-1.30.30/.sourcecode-cache/snapshot-c6e9d39-37df4554.json +0 -262
- sourcecode-1.30.30/.sourcecode-cache/snapshot-c6e9d39-624321f3.json +0 -11389
- sourcecode-1.30.30/.sourcecode-cache/snapshot-c6e9d39-776b4676.json +0 -367
- sourcecode-1.30.30/.sourcecode-cache/snapshot-c6e9d39-9770fba7.json +0 -374
- sourcecode-1.30.30/.sourcecode-cache/snapshot-c6e9d39-c4e3c102.json +0 -262
- sourcecode-1.30.30/.sourcecode-cache/snapshot-c6e9d39-e8bc5fb4.json +0 -122
- sourcecode-1.30.30/.sourcecode-cache/snapshot-c6e9d39-e9801942.json +0 -218
- sourcecode-1.30.30/.sourcecode-cache/snapshot-c6e9d39-fdd9d3f7.json +0 -512
- {sourcecode-1.30.30 → sourcecode-1.31.0}/.agents/skills/source-command-gsd-join-discord/SKILL.md +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/.agents/skills/source-command-gsd-review-backlog/SKILL.md +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/.agents/skills/source-command-gsd-workstreams/SKILL.md +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/.github/workflows/build-windows.yml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/.gitignore +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/.ruff.toml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/CHANGELOG.md +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/CONTRIBUTING.md +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/LICENSE +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/SECURITY.md +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/docs/privacy.md +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/docs/schema.md +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/raw +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/run_cli.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/adaptive_scanner.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/architecture_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/architecture_summary.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/ast_extractor.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/classifier.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/code_notes_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/confidence_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/context_scorer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/context_summarizer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/contract_model.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/contract_pipeline.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/coverage_parser.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/dependency_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/__init__.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/base.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/csproj_parser.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/dart.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/dotnet.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/elixir.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/go.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/heuristic.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/hybrid.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/java.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/jvm_ext.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/nodejs.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/parsers.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/php.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/project.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/python.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/ruby.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/rust.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/systems.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/terraform.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/detectors/tooling.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/doc_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/entrypoint_classifier.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/env_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/file_classifier.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/flow_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/git_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/graph_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/metrics_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/pr_comment_renderer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/prepare_context.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/progress.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/ranking_engine.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/redactor.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/relevance_scorer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/repo_classifier.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/repository_ir.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/runtime_classifier.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/scanner.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/schema.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/semantic_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/serializer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/summarizer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/telemetry/__init__.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/telemetry/config.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/telemetry/consent.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/telemetry/events.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/telemetry/filters.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/telemetry/transport.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/tree_utils.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/src/sourcecode/workspace.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/__init__.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/conftest.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/coverage.xml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/fastapi_app/pyproject.toml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/fastapi_app/src/main.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/go_service/cmd/api/main.go +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/go_service/go.mod +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/jacoco.xml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/latin1_sample.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/latin1_sample_iso.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/lcov.info +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/nextjs_app/app/page.tsx +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/nextjs_app/package.json +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/nextjs_app/pnpm-lock.yaml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/pnpm_monorepo/apps/web/app/page.tsx +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/pnpm_monorepo/apps/web/package.json +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/pnpm_monorepo/packages/api/main.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/pnpm_monorepo/packages/api/pyproject.toml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/pnpm_monorepo/pnpm-workspace.yaml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/pom.xml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/application/service/FindAusenteService.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/domain/entities/Ausente.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/ausente/infrastructure/rest/AusenteRestController.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/application/service/FindAutocoberturasService.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/domain/entities/Autocoberturas.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/autocoberturas/infrastructure/rest/AutocoberturasRestController.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/application/service/FindCalendarioTrabajadorService.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/domain/entities/CalendarioTrabajador.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/calendarioTrabajador/infrastructure/rest/CalendarioTrabajadorRestController.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/application/service/FindDepartamentoService.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/domain/entities/Departamento.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/departamento/infrastructure/rest/DepartamentoRestController.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/application/service/FindEmpleadoService.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/domain/entities/Empleado.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/ddd/empleado/infrastructure/rest/EmpleadoRestController.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/DemoApplication.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/config/FilterConfig.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/domain/Health.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/mapper/HealthMapper.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/repository/HealthRepository.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/service/HealthService.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/HealthRestController.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/java/com/example/demo/web/NominaRestController.java +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/resources/application-dev.yml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/resources/application.yml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/fixtures/spring_boot_minimal/src/main/resources/mapper/HealthMapper.xml +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_architecture_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_architecture_summary.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_ast_extractor.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_block1_reliability.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_block2_coverage.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_block5_quality.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_bug_fixes_v1302.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_bug_fixes_v16.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_bug_fixes_v2.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_classifier.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_cli.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_code_notes_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_context_scorer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_contract_pipeline.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_coverage_parser.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_cross_consistency.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_dependency_analyzer_node_python.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_dependency_analyzer_polyglot.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_dependency_schema.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_detector_dotnet.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_detector_go_rust_java.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_detector_nodejs.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_detector_php_ruby_dart.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_detector_python.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_detector_universal_managed.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_detector_universal_systems.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_detectors_base.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_doc_analyzer_jsdom.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_doc_analyzer_python.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_encoding_regression.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_graph_analyzer_polyglot.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_graph_analyzer_python_node.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_graph_schema.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_hybrid_inference.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_integration.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_integration_dependencies.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_integration_detection.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_integration_docs.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_integration_graph_modules.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_integration_lqn.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_integration_metrics.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_integration_multistack.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_integration_semantics.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_integration_universal.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_java_spring_integration.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_metrics_analyzer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_output_ux.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_packaging.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_phase1_improvements.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_pipeline_integrity.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_real_projects.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_redactor.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_repository_ir.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_scanner.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_schema.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_schema_normalization.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_scoring_calibration.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_semantic_analyzer_node.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_semantic_analyzer_python.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_semantic_import_resolution.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_semantic_schema.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_signal_hierarchy.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_summarizer.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_surface_honesty.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_task_differentiation.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_telemetry.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_v131_improvements.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_v1_10_regressions.py +0 -0
- {sourcecode-1.30.30 → sourcecode-1.31.0}/tests/test_workspace_analyzer.py +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# Continue Here — atlas-cli sesión 16
|
|
2
|
+
|
|
3
|
+
**Paused:** 2026-05-20
|
|
4
|
+
**Repo:** `/Users/user/Downloads/atlas-cli`
|
|
5
|
+
**Branch:** master
|
|
6
|
+
**Working tree:** CHANGELOG.md sin commitear (untracked)
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## Trabajo de esta sesión (ya commiteado)
|
|
11
|
+
|
|
12
|
+
**Commit:** `0e430c1 fix(cli+serializer): BUG-1..5 + IMP-1 — UTF-8 stdout, --exclude parsing, onboard fast scan, angular_version null, lazy_routes_count zero, test_gaps config filter`
|
|
13
|
+
|
|
14
|
+
| ID | Fix | Archivo | Líneas clave |
|
|
15
|
+
|---|---|---|---|
|
|
16
|
+
| BUG-1 | `repo_ir_cmd` usa `stdout.buffer.write(encode("utf-8"))` en vez de `stdout.write()`. `main_entry` llama `stdout.reconfigure(encoding="utf-8")`. UnicodeEncodeError capturado con hint a `--output`. | `cli.py` | ~2367, ~2443 |
|
|
17
|
+
| BUG-2 | `--exclude` añadido a `_OPTIONS_WITH_VALUE` → valor no consumido como repo path. Warning si valor es directorio existente. | `cli.py` | ~173, ~856 |
|
|
18
|
+
| BUG-3 | `onboard --fast` siempre usa `AdaptiveScanner(base_depth=2)`; ya no usa git-index-only (que devolvía solo `.idea/vcs.xml`). | `prepare_context.py` | ~791 |
|
|
19
|
+
| BUG-4 | `deps = {**(pkg.get("dependencies") or {}), ...}` para manejar `null` explícito en package.json. Añade `peerDependencies` como fallback. | `serializer.py` | ~1663 |
|
|
20
|
+
| BUG-5 | Cuenta `loadChildren:` y `loadComponent:` (property syntax modern Angular) en vez del inexistente `loadChildren(`. | `serializer.py` | ~1644 |
|
|
21
|
+
| IMP-1 | `test_gaps` excluye `.eslintrc*`, `karma.conf.js`, `tsconfig*`, `.claude/**`, etc. por defecto. Nuevo flag `--include-config` para override. | `prepare_context.py`, `cli.py` | ~1663, ~1806 |
|
|
22
|
+
| IMP-2 | Stderr warning con workaround exacto cuando se detecta UnicodeEncodeError (BUG-1) o exclude value = directorio (BUG-2). | `cli.py` | ~2373, ~858 |
|
|
23
|
+
|
|
24
|
+
**Tests:** `tests/test_bug_fixes_v2.py` — 14 tests, todos pasan.
|
|
25
|
+
**Suite completa:** 1010 passed, 0 nuevos failures (3 pre-existentes sin tocar).
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Primera acción al retomar
|
|
30
|
+
|
|
31
|
+
CHANGELOG.md quedó fuera del commit (untracked). Commitear:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
cd /Users/user/Downloads/atlas-cli
|
|
35
|
+
git add CHANGELOG.md
|
|
36
|
+
git commit -m "docs: add CHANGELOG.md with BUG-1..5 and IMP-1 entries for v1.30.29
|
|
37
|
+
|
|
38
|
+
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Pendientes (heredados de sesión 15, siguen vigentes)
|
|
44
|
+
|
|
45
|
+
1. **Spring bean wiring graph** — `_build_relations` emite `injects` edges para `@Autowired`. Falta: trazar `@Configuration → @Bean → @Autowired` completo, exponer como `wiring_graph`.
|
|
46
|
+
|
|
47
|
+
2. **Smoke test en repo spring-boot real:**
|
|
48
|
+
```bash
|
|
49
|
+
cd ~/Documents/workspace/spring-boot-realworld-example-app
|
|
50
|
+
sourcecode repo-ir . --since HEAD~1 2>/dev/null | python3 -c "
|
|
51
|
+
import json, sys; d=json.load(sys.stdin)
|
|
52
|
+
print('nodes:', len(d['graph']['nodes']))
|
|
53
|
+
print('route_surface:', d.get('route_surface', []))
|
|
54
|
+
print('reverse_graph keys:', len(d.get('reverse_graph', {})))
|
|
55
|
+
"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
3. **Transaction boundary tracking** — `@Transactional` detectado. Falta: emitir `transactional_boundary` edges.
|
|
59
|
+
|
|
60
|
+
4. **`_diff_routes` para `@RequestMapping` en clase** — class-level mapping change debería propagarse a todos los endpoints del controller.
|
|
61
|
+
|
|
62
|
+
5. **Tests para el symptom fix (sesión 15)** — validar `--symptom "sesiones"` con mock commits produce ranking diferente al baseline. Cubrir en `tests/test_prepare_context_symptom.py`.
|
|
63
|
+
|
|
64
|
+
6. **`_FRONTEND_SYMPTOM_MAP`** — añadir "sesiones"/"session" con backend terms `["httpsession", "sessionmanager", "sessionservice", "sessionrepository"]`.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Estado de tests al pausar
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
1010 passed, 3 skipped (pre-existing)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Pre-existing failures (no tocar):
|
|
75
|
+
- `tests/test_block2_coverage.py::TestDocAnalyzerLanguageCoverage::test_java_marked_unsupported` — `DocRecord.__init__()` unexpected kwarg `name`
|
|
76
|
+
- `tests/test_dependency_analyzer_node_python.py::test_python_requirements_without_lockfile_keeps_declared_versions` — typer version mismatch
|
|
77
|
+
- `tests/test_scoring_calibration.py` — varios score calibration tests
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Para retomar
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
cd /Users/user/Downloads/atlas-cli
|
|
85
|
+
git log --oneline -3 # 0e430c1 debe estar arriba
|
|
86
|
+
git status # solo CHANGELOG.md untracked
|
|
87
|
+
|
|
88
|
+
# 1. Commitear CHANGELOG.md (comando arriba)
|
|
89
|
+
|
|
90
|
+
# 2. Verificar suite
|
|
91
|
+
python3 -m pytest tests/ \
|
|
92
|
+
--ignore=tests/test_block2_coverage.py \
|
|
93
|
+
--ignore=tests/test_scoring_calibration.py \
|
|
94
|
+
--deselect=tests/test_dependency_analyzer_node_python.py::test_python_requirements_without_lockfile_keeps_declared_versions \
|
|
95
|
+
-q
|
|
96
|
+
# Expected: 1010 passed, 3 skipped
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
*Pausado 2026-05-20 — gsd:pause-work*
|
|
@@ -33,7 +33,7 @@ stacks:
|
|
|
33
33
|
- package_manager:pip
|
|
34
34
|
- entry:src/sourcecode/cli.py
|
|
35
35
|
- entry:run_cli.py
|
|
36
|
-
- extensions:
|
|
36
|
+
- extensions:144
|
|
37
37
|
produced_by: python
|
|
38
38
|
language_version: null
|
|
39
39
|
packaging: null
|
|
@@ -48,8 +48,9 @@ contracts:
|
|
|
48
48
|
- config_cmd() -> None
|
|
49
49
|
- 'main(ctx: typer.Context, format: str, output: Optional[Pa...'
|
|
50
50
|
- main_entry() -> None
|
|
51
|
-
-
|
|
51
|
+
- mcp_serve() -> None
|
|
52
52
|
exports:
|
|
53
|
+
- prepare_context_cmd
|
|
53
54
|
- repo_ir_cmd
|
|
54
55
|
- telemetry_disable
|
|
55
56
|
- telemetry_enable
|
|
@@ -59,6 +60,20 @@ contracts:
|
|
|
59
60
|
deps:
|
|
60
61
|
- sourcecode
|
|
61
62
|
- typer
|
|
63
|
+
- path: src/sourcecode/mcp/server.py
|
|
64
|
+
role: entrypoint
|
|
65
|
+
fn:
|
|
66
|
+
- 'agent(path: str, git_context: bool) -> dict'
|
|
67
|
+
- 'compact(path: str, git_context: bool) -> dict'
|
|
68
|
+
- config() -> dict
|
|
69
|
+
- "prepare_context(task: Literal['delta', 'review-pr', 'fix-..."
|
|
70
|
+
- 'repo_ir(path: str) -> dict'
|
|
71
|
+
exports:
|
|
72
|
+
- telemetry
|
|
73
|
+
- version
|
|
74
|
+
deps:
|
|
75
|
+
- mcp
|
|
76
|
+
- sourcecode
|
|
62
77
|
- path: src/sourcecode/context_scorer.py
|
|
63
78
|
role: util
|
|
64
79
|
exports:
|
|
@@ -173,29 +188,15 @@ contracts:
|
|
|
173
188
|
- TaskContextBuilder
|
|
174
189
|
- TaskOutput
|
|
175
190
|
- TaskSpec
|
|
176
|
-
- path: src/sourcecode/ranking_engine.py
|
|
177
|
-
role: util
|
|
178
|
-
fn:
|
|
179
|
-
- 'compute_impact_score(runtime_impact: float, dependency_ce...'
|
|
180
|
-
- 'resolve_framework_signal(category: str | None) -> float'
|
|
181
|
-
- 'resolve_runtime_impact(category: str | None) -> float'
|
|
182
|
-
exports:
|
|
183
|
-
- k: class
|
|
184
|
-
names:
|
|
185
|
-
- FileScore
|
|
186
|
-
- RankingEngine
|
|
187
|
-
- TaskWeights
|
|
188
|
-
deps:
|
|
189
|
-
- sourcecode
|
|
190
191
|
contracts_meta:
|
|
191
192
|
total: 15
|
|
192
193
|
shown: 15
|
|
193
194
|
truncated: false
|
|
194
195
|
summary:
|
|
195
196
|
files: 15
|
|
196
|
-
total:
|
|
197
|
+
total: 70
|
|
197
198
|
methods:
|
|
198
|
-
ast:
|
|
199
|
+
ast: 70
|
|
199
200
|
confidence:
|
|
200
201
|
overall: high
|
|
201
202
|
stack: high
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"package_manager:pip",
|
|
43
43
|
"entry:src/sourcecode/cli.py",
|
|
44
44
|
"entry:run_cli.py",
|
|
45
|
-
"extensions:
|
|
45
|
+
"extensions:144"
|
|
46
46
|
],
|
|
47
47
|
"produced_by": "python",
|
|
48
48
|
"language_version": null,
|
|
@@ -61,9 +61,10 @@
|
|
|
61
61
|
"config_cmd() -> None",
|
|
62
62
|
"main(ctx: typer.Context, format: str, output: Optional[Pa...",
|
|
63
63
|
"main_entry() -> None",
|
|
64
|
-
"
|
|
64
|
+
"mcp_serve() -> None"
|
|
65
65
|
],
|
|
66
66
|
"exports": [
|
|
67
|
+
"prepare_context_cmd",
|
|
67
68
|
"repo_ir_cmd",
|
|
68
69
|
"telemetry_disable",
|
|
69
70
|
"telemetry_enable",
|
|
@@ -76,6 +77,25 @@
|
|
|
76
77
|
"typer"
|
|
77
78
|
]
|
|
78
79
|
},
|
|
80
|
+
{
|
|
81
|
+
"path": "src/sourcecode/mcp/server.py",
|
|
82
|
+
"role": "entrypoint",
|
|
83
|
+
"fn": [
|
|
84
|
+
"agent(path: str, git_context: bool) -> dict",
|
|
85
|
+
"compact(path: str, git_context: bool) -> dict",
|
|
86
|
+
"config() -> dict",
|
|
87
|
+
"prepare_context(task: Literal['delta', 'review-pr', 'fix-...",
|
|
88
|
+
"repo_ir(path: str) -> dict"
|
|
89
|
+
],
|
|
90
|
+
"exports": [
|
|
91
|
+
"telemetry",
|
|
92
|
+
"version"
|
|
93
|
+
],
|
|
94
|
+
"deps": [
|
|
95
|
+
"mcp",
|
|
96
|
+
"sourcecode"
|
|
97
|
+
]
|
|
98
|
+
},
|
|
79
99
|
{
|
|
80
100
|
"path": "src/sourcecode/context_scorer.py",
|
|
81
101
|
"role": "util",
|
|
@@ -262,28 +282,6 @@
|
|
|
262
282
|
]
|
|
263
283
|
}
|
|
264
284
|
]
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
"path": "src/sourcecode/ranking_engine.py",
|
|
268
|
-
"role": "util",
|
|
269
|
-
"fn": [
|
|
270
|
-
"compute_impact_score(runtime_impact: float, dependency_ce...",
|
|
271
|
-
"resolve_framework_signal(category: str | None) -> float",
|
|
272
|
-
"resolve_runtime_impact(category: str | None) -> float"
|
|
273
|
-
],
|
|
274
|
-
"exports": [
|
|
275
|
-
{
|
|
276
|
-
"k": "class",
|
|
277
|
-
"names": [
|
|
278
|
-
"FileScore",
|
|
279
|
-
"RankingEngine",
|
|
280
|
-
"TaskWeights"
|
|
281
|
-
]
|
|
282
|
-
}
|
|
283
|
-
],
|
|
284
|
-
"deps": [
|
|
285
|
-
"sourcecode"
|
|
286
|
-
]
|
|
287
285
|
}
|
|
288
286
|
],
|
|
289
287
|
"contracts_meta": {
|
|
@@ -293,9 +291,9 @@
|
|
|
293
291
|
},
|
|
294
292
|
"summary": {
|
|
295
293
|
"files": 15,
|
|
296
|
-
"total":
|
|
294
|
+
"total": 70,
|
|
297
295
|
"methods": {
|
|
298
|
-
"ast":
|
|
296
|
+
"ast": 70
|
|
299
297
|
}
|
|
300
298
|
},
|
|
301
299
|
"confidence": {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: sourcecode
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.31.0
|
|
4
4
|
Summary: Deterministic codebase context for AI coding agents
|
|
5
5
|
License: Apache License
|
|
6
6
|
Version 2.0, January 2004
|
|
@@ -212,16 +212,19 @@ Requires-Dist: tree-sitter-javascript>=0.21; extra == 'ast'
|
|
|
212
212
|
Requires-Dist: tree-sitter-typescript>=0.21; extra == 'ast'
|
|
213
213
|
Requires-Dist: tree-sitter>=0.21; extra == 'ast'
|
|
214
214
|
Provides-Extra: dev
|
|
215
|
+
Requires-Dist: mcp>=1.0.0; extra == 'dev'
|
|
215
216
|
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
216
217
|
Requires-Dist: pytest>=8; extra == 'dev'
|
|
217
218
|
Requires-Dist: ruff>=0.15; extra == 'dev'
|
|
219
|
+
Provides-Extra: mcp
|
|
220
|
+
Requires-Dist: mcp>=1.0.0; extra == 'mcp'
|
|
218
221
|
Description-Content-Type: text/markdown
|
|
219
222
|
|
|
220
223
|
# sourcecode
|
|
221
224
|
|
|
222
225
|
**Deterministic, behavior-aware codebase context for AI agents and PR review.**
|
|
223
226
|
|
|
224
|
-

|
|
225
228
|

|
|
226
229
|
|
|
227
230
|
---
|
|
@@ -257,7 +260,7 @@ pipx install sourcecode
|
|
|
257
260
|
|
|
258
261
|
```bash
|
|
259
262
|
sourcecode version
|
|
260
|
-
# sourcecode 1.
|
|
263
|
+
# sourcecode 1.31.0
|
|
261
264
|
```
|
|
262
265
|
|
|
263
266
|
---
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
**Deterministic, behavior-aware codebase context for AI agents and PR review.**
|
|
4
4
|
|
|
5
|
-

|
|
6
6
|

|
|
7
7
|
|
|
8
8
|
---
|
|
@@ -38,7 +38,7 @@ pipx install sourcecode
|
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
40
|
sourcecode version
|
|
41
|
-
# sourcecode 1.
|
|
41
|
+
# sourcecode 1.31.0
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
---
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "sourcecode"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.31.0"
|
|
8
8
|
description = "Deterministic codebase context for AI coding agents"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.9"
|
|
@@ -39,12 +39,16 @@ dev = [
|
|
|
39
39
|
"pytest>=8",
|
|
40
40
|
"ruff>=0.15",
|
|
41
41
|
"mypy>=1.10",
|
|
42
|
+
"mcp>=1.0.0",
|
|
42
43
|
]
|
|
43
44
|
ast = [
|
|
44
45
|
"tree-sitter>=0.21",
|
|
45
46
|
"tree-sitter-typescript>=0.21",
|
|
46
47
|
"tree-sitter-javascript>=0.21",
|
|
47
48
|
]
|
|
49
|
+
mcp = [
|
|
50
|
+
"mcp>=1.0.0",
|
|
51
|
+
]
|
|
48
52
|
|
|
49
53
|
[[tool.mypy.overrides]]
|
|
50
54
|
module = ["tree_sitter", "tree_sitter_typescript", "tree_sitter_javascript"]
|
|
@@ -154,6 +154,10 @@ Compressed AI-ready context for Java/Spring enterprise codebases.
|
|
|
154
154
|
|
|
155
155
|
[bold]Subcommands:[/bold]
|
|
156
156
|
prepare-context TASK [PATH] [dim]# task-specific context (onboard, delta, fix-bug, ...)[/dim]
|
|
157
|
+
mcp init [dim]# setup MCP integration (Claude Desktop, Cursor)[/dim]
|
|
158
|
+
mcp status [dim]# show MCP integration status[/dim]
|
|
159
|
+
mcp remove [dim]# remove MCP integration safely[/dim]
|
|
160
|
+
mcp serve [dim]# start MCP server for AI agent integration[/dim]
|
|
157
161
|
telemetry status|enable|disable
|
|
158
162
|
version
|
|
159
163
|
"""
|
|
@@ -161,7 +165,7 @@ Compressed AI-ready context for Java/Spring enterprise codebases.
|
|
|
161
165
|
# Known subcommand names — tokens matching these are routed as subcommands,
|
|
162
166
|
# not consumed as a repository path.
|
|
163
167
|
_SUBCOMMANDS: frozenset[str] = frozenset(
|
|
164
|
-
{"telemetry", "prepare-context", "version", "config", "analyze", "repo-ir"}
|
|
168
|
+
{"telemetry", "prepare-context", "version", "config", "analyze", "repo-ir", "mcp"}
|
|
165
169
|
)
|
|
166
170
|
|
|
167
171
|
# Mutable container holding the path extracted by _preprocess_argv().
|
|
@@ -300,6 +304,9 @@ except Exception:
|
|
|
300
304
|
telemetry_app = typer.Typer(help="Manage anonymous telemetry (opt-in).", rich_markup_mode="rich")
|
|
301
305
|
app.add_typer(telemetry_app, name="telemetry")
|
|
302
306
|
|
|
307
|
+
mcp_app = typer.Typer(help="MCP integration: setup, status, serve, remove.", rich_markup_mode="rich")
|
|
308
|
+
app.add_typer(mcp_app, name="mcp")
|
|
309
|
+
|
|
303
310
|
|
|
304
311
|
def _maybe_ask_consent() -> None:
|
|
305
312
|
"""Show first-run consent prompt once, on interactive TTYs only."""
|
|
@@ -317,6 +324,26 @@ def _maybe_ask_consent() -> None:
|
|
|
317
324
|
pass
|
|
318
325
|
|
|
319
326
|
|
|
327
|
+
def _maybe_show_mcp_hint() -> None:
|
|
328
|
+
"""Show MCP integration hint once after first install, on TTY only."""
|
|
329
|
+
import sys as _sys
|
|
330
|
+
try:
|
|
331
|
+
if not _sys.stderr.isatty():
|
|
332
|
+
return
|
|
333
|
+
from sourcecode.telemetry.config import _CONFIG_FILE, _load, _save
|
|
334
|
+
data = _load()
|
|
335
|
+
if data.get("mcp", {}).get("hint_shown"):
|
|
336
|
+
return
|
|
337
|
+
typer.echo("", err=True)
|
|
338
|
+
typer.echo(" MCP integration available:", err=True)
|
|
339
|
+
typer.echo(" → sourcecode mcp init", err=True)
|
|
340
|
+
typer.echo("", err=True)
|
|
341
|
+
data.setdefault("mcp", {})["hint_shown"] = True
|
|
342
|
+
_save(data)
|
|
343
|
+
except Exception:
|
|
344
|
+
pass
|
|
345
|
+
|
|
346
|
+
|
|
320
347
|
def _active_flags(
|
|
321
348
|
dependencies: bool, graph_modules: bool, docs: bool, full_metrics: bool,
|
|
322
349
|
semantics: bool, architecture: bool, git_context: bool, env_map: bool,
|
|
@@ -616,6 +643,7 @@ def main(
|
|
|
616
643
|
# First-run consent (skip for telemetry/version/config subcommands)
|
|
617
644
|
if ctx.invoked_subcommand not in ("telemetry", "version", "config"):
|
|
618
645
|
_maybe_ask_consent()
|
|
646
|
+
_maybe_show_mcp_hint()
|
|
619
647
|
|
|
620
648
|
# When a subcommand is invoked, skip the main analysis.
|
|
621
649
|
if ctx.invoked_subcommand is not None:
|
|
@@ -2432,6 +2460,249 @@ def analyze_cmd(
|
|
|
2432
2460
|
raise typer.Exit(code=1)
|
|
2433
2461
|
|
|
2434
2462
|
|
|
2463
|
+
# ── MCP server ────────────────────────────────────────────────────────────────
|
|
2464
|
+
|
|
2465
|
+
@mcp_app.command("serve")
|
|
2466
|
+
def mcp_serve() -> None:
|
|
2467
|
+
"""Start the MCP server on stdio for AI agent integration.
|
|
2468
|
+
|
|
2469
|
+
\b
|
|
2470
|
+
Requires the 'mcp' extra:
|
|
2471
|
+
pip install sourcecode[mcp]
|
|
2472
|
+
|
|
2473
|
+
\b
|
|
2474
|
+
Configure in your MCP client (e.g. Claude Desktop):
|
|
2475
|
+
{
|
|
2476
|
+
"sourcecode": {
|
|
2477
|
+
"command": "sourcecode",
|
|
2478
|
+
"args": ["mcp", "serve"]
|
|
2479
|
+
}
|
|
2480
|
+
}
|
|
2481
|
+
"""
|
|
2482
|
+
import logging
|
|
2483
|
+
import sys as _sys
|
|
2484
|
+
|
|
2485
|
+
logging.basicConfig(
|
|
2486
|
+
stream=_sys.stderr,
|
|
2487
|
+
level=logging.INFO,
|
|
2488
|
+
format="[sourcecode-mcp] %(levelname)s %(message)s",
|
|
2489
|
+
)
|
|
2490
|
+
try:
|
|
2491
|
+
from sourcecode.mcp.server import mcp as _mcp
|
|
2492
|
+
except ImportError:
|
|
2493
|
+
typer.echo(
|
|
2494
|
+
"MCP support not available. Install with:\n"
|
|
2495
|
+
" pip install sourcecode[mcp]",
|
|
2496
|
+
err=True,
|
|
2497
|
+
)
|
|
2498
|
+
raise typer.Exit(code=1)
|
|
2499
|
+
|
|
2500
|
+
log = logging.getLogger(__name__)
|
|
2501
|
+
log.info("sourcecode-mcp starting (stdio transport)")
|
|
2502
|
+
try:
|
|
2503
|
+
_mcp.run()
|
|
2504
|
+
except KeyboardInterrupt:
|
|
2505
|
+
log.info("sourcecode-mcp stopped")
|
|
2506
|
+
except Exception as exc:
|
|
2507
|
+
log.critical("sourcecode-mcp fatal error: %s", exc, exc_info=True)
|
|
2508
|
+
raise typer.Exit(code=1)
|
|
2509
|
+
|
|
2510
|
+
|
|
2511
|
+
# ── MCP onboarding ────────────────────────────────────────────────────────────
|
|
2512
|
+
|
|
2513
|
+
@mcp_app.command("init")
|
|
2514
|
+
def mcp_init(
|
|
2515
|
+
yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt."),
|
|
2516
|
+
) -> None:
|
|
2517
|
+
"""Setup MCP integration for Claude Desktop, Cursor, and other clients.
|
|
2518
|
+
|
|
2519
|
+
\b
|
|
2520
|
+
Detects installed MCP clients, backs up their config files, and safely
|
|
2521
|
+
inserts the sourcecode server entry. Fully idempotent — safe to re-run.
|
|
2522
|
+
"""
|
|
2523
|
+
from sourcecode.mcp.onboarding.detector import detect_clients
|
|
2524
|
+
from sourcecode.mcp.onboarding.planner import build_install_plan
|
|
2525
|
+
from sourcecode.mcp.onboarding import backup, applier
|
|
2526
|
+
|
|
2527
|
+
typer.echo("Detecting MCP clients...")
|
|
2528
|
+
typer.echo("")
|
|
2529
|
+
|
|
2530
|
+
clients = detect_clients()
|
|
2531
|
+
if not clients:
|
|
2532
|
+
typer.echo("No MCP clients found on this system.")
|
|
2533
|
+
typer.echo("")
|
|
2534
|
+
typer.echo("Manual setup — add to your MCP client config:")
|
|
2535
|
+
typer.echo(' "sourcecode": {"command": "sourcecode", "args": ["mcp", "serve"]}')
|
|
2536
|
+
raise typer.Exit(code=0)
|
|
2537
|
+
|
|
2538
|
+
# Show detection results
|
|
2539
|
+
for client in clients:
|
|
2540
|
+
mark = "✓" if client.app_installed else "○"
|
|
2541
|
+
note = "" if client.app_installed else " (not found)"
|
|
2542
|
+
typer.echo(f" {mark} {client.name:<18} {client.config_path}{note}")
|
|
2543
|
+
typer.echo("")
|
|
2544
|
+
|
|
2545
|
+
# Build plan
|
|
2546
|
+
plan = build_install_plan(clients)
|
|
2547
|
+
actionable = [a for a in plan if a.client.app_installed and not a.already_installed]
|
|
2548
|
+
already_done = [a for a in plan if a.client.app_installed and a.already_installed]
|
|
2549
|
+
|
|
2550
|
+
if already_done and not actionable:
|
|
2551
|
+
typer.echo("Already configured:")
|
|
2552
|
+
for a in already_done:
|
|
2553
|
+
typer.echo(f" ✓ {a.client.name} {a.client.config_path}")
|
|
2554
|
+
typer.echo("")
|
|
2555
|
+
typer.echo("Nothing to do. Remove: sourcecode mcp remove")
|
|
2556
|
+
raise typer.Exit(code=0)
|
|
2557
|
+
|
|
2558
|
+
if already_done:
|
|
2559
|
+
typer.echo("Already configured:")
|
|
2560
|
+
for a in already_done:
|
|
2561
|
+
typer.echo(f" ✓ {a.client.name} {a.client.config_path}")
|
|
2562
|
+
typer.echo("")
|
|
2563
|
+
|
|
2564
|
+
# Show plan for actionable items
|
|
2565
|
+
typer.echo("This will:")
|
|
2566
|
+
for a in actionable:
|
|
2567
|
+
verb = "Create " if a.will_create_file else "Modify "
|
|
2568
|
+
typer.echo(f" {verb} {a.client.config_path}")
|
|
2569
|
+
typer.echo(f" Backup → ~/.config/sourcecode/mcp-backups/")
|
|
2570
|
+
typer.echo("")
|
|
2571
|
+
|
|
2572
|
+
if not yes:
|
|
2573
|
+
confirmed = typer.confirm("Proceed?", default=False)
|
|
2574
|
+
if not confirmed:
|
|
2575
|
+
typer.echo("Aborted.")
|
|
2576
|
+
raise typer.Exit(code=0)
|
|
2577
|
+
typer.echo("")
|
|
2578
|
+
|
|
2579
|
+
# Apply
|
|
2580
|
+
errors: list[str] = []
|
|
2581
|
+
for a in actionable:
|
|
2582
|
+
try:
|
|
2583
|
+
config = applier.read_config(a.client.config_path)
|
|
2584
|
+
if a.client.config_path.exists():
|
|
2585
|
+
bak = backup.create(a.client.config_path)
|
|
2586
|
+
typer.echo(f" ✓ Backup {bak}")
|
|
2587
|
+
updated = applier.apply_entry(config)
|
|
2588
|
+
applier.write_config(a.client.config_path, updated)
|
|
2589
|
+
if not applier.validate(a.client.config_path):
|
|
2590
|
+
errors.append(f"{a.client.name}: JSON validation failed after write")
|
|
2591
|
+
continue
|
|
2592
|
+
typer.echo(f" ✓ Updated {a.client.config_path}")
|
|
2593
|
+
except Exception as exc:
|
|
2594
|
+
errors.append(f"{a.client.name}: {exc}")
|
|
2595
|
+
|
|
2596
|
+
typer.echo("")
|
|
2597
|
+
|
|
2598
|
+
if errors:
|
|
2599
|
+
for err in errors:
|
|
2600
|
+
typer.echo(f" ✗ {err}", err=True)
|
|
2601
|
+
raise typer.Exit(code=1)
|
|
2602
|
+
|
|
2603
|
+
typer.echo("MCP integration active.")
|
|
2604
|
+
typer.echo("")
|
|
2605
|
+
|
|
2606
|
+
restart_needed = [a.client.name for a in actionable if not a.will_create_file]
|
|
2607
|
+
if restart_needed:
|
|
2608
|
+
typer.echo(f" Restart {', '.join(restart_needed)} to apply changes.")
|
|
2609
|
+
typer.echo(" Remove: sourcecode mcp remove")
|
|
2610
|
+
|
|
2611
|
+
|
|
2612
|
+
@mcp_app.command("status")
|
|
2613
|
+
def mcp_status() -> None:
|
|
2614
|
+
"""Show MCP integration status for all detected clients."""
|
|
2615
|
+
from sourcecode.mcp.onboarding.detector import detect_clients
|
|
2616
|
+
from sourcecode.mcp.onboarding import applier
|
|
2617
|
+
|
|
2618
|
+
clients = detect_clients()
|
|
2619
|
+
typer.echo("MCP Integration Status")
|
|
2620
|
+
typer.echo("")
|
|
2621
|
+
|
|
2622
|
+
if not clients:
|
|
2623
|
+
typer.echo(" No MCP clients detected on this system.")
|
|
2624
|
+
raise typer.Exit(code=0)
|
|
2625
|
+
|
|
2626
|
+
for client in clients:
|
|
2627
|
+
if not client.app_installed:
|
|
2628
|
+
typer.echo(f" ○ {client.name:<18} not found")
|
|
2629
|
+
continue
|
|
2630
|
+
config = applier.read_config(client.config_path)
|
|
2631
|
+
if applier.is_installed(config):
|
|
2632
|
+
typer.echo(f" ✓ {client.name:<18} configured {client.config_path}")
|
|
2633
|
+
else:
|
|
2634
|
+
typer.echo(f" ✗ {client.name:<18} not configured")
|
|
2635
|
+
typer.echo("")
|
|
2636
|
+
typer.echo(" Setup: sourcecode mcp init")
|
|
2637
|
+
typer.echo(" Remove: sourcecode mcp remove")
|
|
2638
|
+
|
|
2639
|
+
|
|
2640
|
+
@mcp_app.command("remove")
|
|
2641
|
+
def mcp_remove(
|
|
2642
|
+
yes: bool = typer.Option(False, "--yes", "-y", help="Skip confirmation prompt."),
|
|
2643
|
+
) -> None:
|
|
2644
|
+
"""Remove sourcecode MCP integration from all configured clients.
|
|
2645
|
+
|
|
2646
|
+
\b
|
|
2647
|
+
Backs up config files before modifying. Restores from backup when available,
|
|
2648
|
+
otherwise removes the sourcecode entry while preserving all other config.
|
|
2649
|
+
"""
|
|
2650
|
+
from sourcecode.mcp.onboarding.detector import detect_clients
|
|
2651
|
+
from sourcecode.mcp.onboarding.planner import build_remove_plan
|
|
2652
|
+
from sourcecode.mcp.onboarding import backup, applier
|
|
2653
|
+
|
|
2654
|
+
clients = detect_clients()
|
|
2655
|
+
plan = build_remove_plan(clients)
|
|
2656
|
+
installed = [a for a in plan if a.already_installed]
|
|
2657
|
+
|
|
2658
|
+
if not installed:
|
|
2659
|
+
typer.echo("sourcecode MCP integration not found in any client config.")
|
|
2660
|
+
typer.echo(" Setup: sourcecode mcp init")
|
|
2661
|
+
raise typer.Exit(code=0)
|
|
2662
|
+
|
|
2663
|
+
typer.echo("Remove sourcecode MCP integration from:")
|
|
2664
|
+
typer.echo("")
|
|
2665
|
+
for a in installed:
|
|
2666
|
+
typer.echo(f" {a.client.name} {a.client.config_path}")
|
|
2667
|
+
bak = backup.latest(a.client.config_path)
|
|
2668
|
+
if bak:
|
|
2669
|
+
typer.echo(f" Backup available: {bak}")
|
|
2670
|
+
typer.echo("")
|
|
2671
|
+
|
|
2672
|
+
if not yes:
|
|
2673
|
+
confirmed = typer.confirm("Proceed?", default=False)
|
|
2674
|
+
if not confirmed:
|
|
2675
|
+
typer.echo("Aborted.")
|
|
2676
|
+
raise typer.Exit(code=0)
|
|
2677
|
+
typer.echo("")
|
|
2678
|
+
|
|
2679
|
+
errors: list[str] = []
|
|
2680
|
+
for a in installed:
|
|
2681
|
+
try:
|
|
2682
|
+
bak = backup.create(a.client.config_path)
|
|
2683
|
+
typer.echo(f" ✓ Backup {bak}")
|
|
2684
|
+
config = applier.read_config(a.client.config_path)
|
|
2685
|
+
updated = applier.remove_entry(config)
|
|
2686
|
+
applier.write_config(a.client.config_path, updated)
|
|
2687
|
+
if not applier.validate(a.client.config_path):
|
|
2688
|
+
errors.append(f"{a.client.name}: JSON validation failed — restoring backup")
|
|
2689
|
+
backup.restore(bak, a.client.config_path)
|
|
2690
|
+
continue
|
|
2691
|
+
typer.echo(f" ✓ Updated {a.client.config_path}")
|
|
2692
|
+
except Exception as exc:
|
|
2693
|
+
errors.append(f"{a.client.name}: {exc}")
|
|
2694
|
+
|
|
2695
|
+
typer.echo("")
|
|
2696
|
+
|
|
2697
|
+
if errors:
|
|
2698
|
+
for err in errors:
|
|
2699
|
+
typer.echo(f" ✗ {err}", err=True)
|
|
2700
|
+
raise typer.Exit(code=1)
|
|
2701
|
+
|
|
2702
|
+
typer.echo("MCP integration removed.")
|
|
2703
|
+
typer.echo(" Re-add: sourcecode mcp init")
|
|
2704
|
+
|
|
2705
|
+
|
|
2435
2706
|
# ── Entry point ───────────────────────────────────────────────────────────────
|
|
2436
2707
|
|
|
2437
2708
|
def main_entry() -> None:
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""MCP client onboarding: detect, plan, apply, backup, remove."""
|