attocode-code-intel 0.1.1__tar.gz → 0.1.3__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.
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/PKG-INFO +1 -1
- attocode_code_intel-0.1.3/evals/results/2026-10-11-agent-r4-stage0.md +186 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/pyproject.toml +1 -1
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/__init__.py +1 -1
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/ast_service.py +3 -3
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/codebase_context.py +40 -16
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/cross_references.py +27 -13
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/index_store.py +1 -1
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/providers/db_provider.py +6 -1
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/full_indexer.py +17 -6
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/incremental.py +7 -1
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/test_ranking.py +71 -1
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/composite_tools.py +38 -2
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_focused_inspection.py +50 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_navigation_evidence.py +36 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/.gitignore +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/LICENSE +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/README.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/README.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/broad_candidate_audit.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/broad_query_cases.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/broad_query_external_cases.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/broad_query_final_holdout.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/client_comparison.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/client_responses.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/daily.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/external_benchmarks.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/external_study.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/graded_blind_pack.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/localize_study.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/locbench_title_pack.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/onboarding_study.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/pilot.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/quality_scoring.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/quality_tasks.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/release_gate.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/responses.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-09-05-macos.json +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-04-broad-query-ranking.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-04-decision-reranker-trial.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-04-systemone-http-local-trial.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-05-broad-candidate-audit.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-05-source-view-transfer.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-08-blind-graded-rerank.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-08-locbench-560.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-09-locbench-560-first-stage.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-10-agent-pilot.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-10-agent-r3.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/2026-10-10-matrix-r1.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/results/README.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/source_view_transfer.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/study.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/study_clients.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/study_events.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/study_tasks.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/token_overhead.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/understanding_scoring.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/understanding_study.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/warm_cache.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/evals/workflows.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/GUIDELINES.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/errors/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/architecture_drift.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/ast_chunker.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/blob_oid.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/cache_manifest.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/cas.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/code_analyzer.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/codebase_ast.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/cross_mode.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/embedding_rotation.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/embeddings.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/frecency.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/fuzzy.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/hierarchical_explorer.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/hydration.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/index_repair.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/memory_store.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/module_resolution.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/query_constraints.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/query_history.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/reranker.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/semantic_search.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/syntax_evidence.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/systemone_ranker.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/temporal_coupling.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/trigram_index.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/trigram_regex.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/ts_parser.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/context/vector_store.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/feature_flags/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/lsp/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/lsp/client.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/mcp/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/mcp/client.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/custom_rules.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/dataflow.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/dependency_audit.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/matcher.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/patterns.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/security/scanner.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/utilities/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/utilities/ignore.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/integrations/utilities/token_estimate.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/tricks/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/tricks/recursive_context.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/types/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/types/events.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_internal/types/severity.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/_shared.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/analysis_coverage.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/access.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/app.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/api_keys.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/context.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/jwt.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/oauth.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/auth/passwords.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/deps.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/knowledge_bridge.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/mcp_transport.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/middleware.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/models.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/providers/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/providers/local_provider.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/providers/remote_provider.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/repository_source.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/_pin_helper.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/activity.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/adr.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/analysis.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/api_keys.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/auth.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/branches.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/cross_repo_search.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/embeddings.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/files.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/files_v2.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/gc.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/git_v2.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/graph.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/graph_viz.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/health.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/history.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/jobs.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/learning.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/lsp.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/notify.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/operations.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/orgs.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/preferences.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/presence.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/projects.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/repos.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/search.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/snapshots.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/webhooks.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/routes/websocket.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/static/graph.html +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/api/utils.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/artifacts/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/artifacts/hashing.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/artifacts/provenance.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/artifacts/retrieval_pin.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/audit.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/bug_finder.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/bundle.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/catalog.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/change_review.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/cli.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/community.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/confidence/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/confidence/jev.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/confidence/llm.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/confidence/redact.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/confidence/settings.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/config.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/crypto.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/db/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/db/base.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/db/engine.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/db/models.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/entrypoint.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/focused_evidence.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/freshness.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/gateway.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/git/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/git/credentials.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/git/manager.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/git/models.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/git/storage.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/graph_query_parser.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/helpers.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/debouncer.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/delta_indexer.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/parser.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/summarizer.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/installer.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/knowledge.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/local_knowledge.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/alembic.ini +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/env.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/script.py.mako +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/001_initial_schema.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/002_branch_version_and_embeddings.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/003_embedding_uniqueness_and_cascade.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/004_audit_events.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/005_user_preferences.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/006_google_oauth.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/007_pgvector_embeddings.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/008_symbol_references.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/009_webhook_secret_encryption.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/010_add_commits_table.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/011_commit_changed_files.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/012_branch_merged_at.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/013_revoked_tokens.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/014_blame_hunks.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/015_commit_file_stats.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/016_embedding_provenance_columns.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/017_provenance_table.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/018_repo_snapshots.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/019_symref_caller.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/migrations/versions/020_shared_knowledge.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/onboarding.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/output.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/precision.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/presence.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/probe.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/project_dir.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/pubsub.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/query_ranking.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/readiness.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/redis.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/reference_pages.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/remote.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/repo_ranker.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/request_context.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/ci.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/combinators.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/enricher.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/evolution.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/executor.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/filters/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/filters/pipeline.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/formatter.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/hygiene.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/importers/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/importers/semgrep.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/loader.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/marketplace.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/metavar.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/model.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/_license_templates/Apache-2.0.txt +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/_license_templates/MIT.txt +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/LICENSE +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/NOTICE +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/PORTING.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B105-hardcoded-password.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B303-weak-md5.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B304-weak-des.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B307-use-of-eval.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B324-weak-sha1.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B501-no-cert-validation.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B602-shell-true.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/bandit-python/rules/B608-sqli.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/LICENSE +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/NOTICE +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/PORTING.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/eqeqeq.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-eval.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-implied-eval.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-new-func.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-throw-literal.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-var.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/eslint-typescript/rules/no-with.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/LICENSE +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/NOTICE +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/PORTING.md +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G101-hardcoded-credentials.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G102-bind-all-interfaces.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G103-unsafe-block.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G201-sql-format.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G304-file-inclusion.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G401-weak-cipher.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G402-tls-min-version.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/community/gosec-go/rules/G501-md5-import.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/cpp/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/cpp/rules/security.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/cpp/rules/structural.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/csharp/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/csharp/rules/security.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/csharp/rules/structural.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/rules/performance.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/rules/security.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/rules/structural.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/taint/sanitizers.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/taint/sinks.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/go/taint/sources.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/java/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/java/rules/correctness.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/java/rules/structural.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/java/taint/sinks.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/java/taint/sources.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/kotlin/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/kotlin/rules/correctness.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/kotlin/rules/structural.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/php/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/php/rules/security.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/php/rules/structural.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/python/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/python/rules/performance.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/python/rules/structural.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/ruby/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/ruby/rules/security.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/ruby/rules/structural.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/rust/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/rust/rules/correctness.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/rust/rules/structural.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/typescript/manifest.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/typescript/rules/performance.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/examples/typescript/rules/structural.yaml +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/packs/pack_loader.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/plugins/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/plugins/plugin_loader.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/profiling.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/registry.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/sarif.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/synthesis.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/rules/testing.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/server.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/service.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/sharing.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/branch_overlay.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/content_store.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/dependency_store.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/diff_engine.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/embedding_store.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/provenance_store.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/security_scanner_db.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/storage/symbol_store.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/structural_evidence.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/symbol_inspection.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/symbol_links.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/telemetry.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/testing/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/testing/fixtures.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/testing/helpers.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/testing/mocks.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/adr_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/analysis_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/cross_mode_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/dead_code_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/distill_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/frecency_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/fuzzy_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/history_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/learning_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/lsp_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/maintenance_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/navigation_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/overlay_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/pin_store.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/pin_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/query_constraints_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/query_history_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/readiness_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/rule_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/search_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/snapshot_tools.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/workers/__init__.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/workers/job_utils.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/workers/jobs.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/workers/run.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/workers/settings.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_cold_discovery.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_compact_inspection.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_daily_workflows.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_doctor.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_edit_restart.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_external_study.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_index_reuse.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_language_capabilities.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_local_reranker.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_localize_study.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_onboarding_study.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_pilot.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_precision_protocol.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_product.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_quality_evaluation.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_query_ranking.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_ranking_intent.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_remote.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_structural_evidence.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_study.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_systemone_ranker.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_token_overhead.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_understanding_evaluation.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_walk_order.py +0 -0
- {attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/tests/test_warm_cache.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: attocode-code-intel
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.3
|
|
4
4
|
Summary: Local code search and navigation for coding agents and people
|
|
5
5
|
Project-URL: Homepage, https://github.com/eren23/attocode
|
|
6
6
|
Project-URL: Repository, https://github.com/eren23/attocode
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# Agent study R4, Stage 0: tests for a change
|
|
2
|
+
|
|
3
|
+
**Status: The rule for Stage 1 is not met, so no agent runs. On 123 dev
|
|
4
|
+
tasks, `suggest_tests` of code intel 0.1.1 had a test Recall@5 of 0.469.
|
|
5
|
+
A file-name grep had 0.477 (Δ -0.008, range -0.117 to +0.101).** In 19
|
|
6
|
+
tasks, `suggest_tests` failed with `RuntimeError: dictionary changed size
|
|
7
|
+
during iteration`. #161 fixes this race. With the fix, the 19 tasks ran,
|
|
8
|
+
and Recall@5 was 0.545 against 0.477 (Δ +0.068, range -0.020 to +0.158).
|
|
9
|
+
That is also below the rule. By the rule, the next work is better test
|
|
10
|
+
ranking, not agent runs.
|
|
11
|
+
|
|
12
|
+
**Update after the ranking change (#164): the holdout check also does not
|
|
13
|
+
meet the rule.** On the 56 holdout tasks, `suggest_tests` had Recall@5
|
|
14
|
+
0.640 and the name grep 0.586 (Δ +0.054, range -0.047 to +0.167). On the
|
|
15
|
+
dev tasks, which we used to make the change, Δ was +0.213. Thus no agent
|
|
16
|
+
runs. The section [After the ranking change](#after-the-ranking-change)
|
|
17
|
+
gives the details.
|
|
18
|
+
|
|
19
|
+
R4 follows the R3 rule: after the localization studies, test a review
|
|
20
|
+
task. The [R3 results](2026-10-10-agent-r3.md) give the background.
|
|
21
|
+
|
|
22
|
+
## Rules
|
|
23
|
+
|
|
24
|
+
We wrote these rules before Stage 0 ran, and the user approved them on
|
|
25
|
+
2026-10-11. The design file is `studies/r4-design.md` in the evals store
|
|
26
|
+
(sha256 `17b80ae0…`). We did not change it after results existed.
|
|
27
|
+
|
|
28
|
+
- **Question.** When an agent reviews a change, does code intel help it
|
|
29
|
+
name the existing tests that check the change?
|
|
30
|
+
- **Tasks.** R1 core-mix tasks whose `test_patch` changes 1 to 5 test
|
|
31
|
+
files that exist at the base commit. These files are the gold set. The
|
|
32
|
+
change is the `patch`, applied to the base commit and not committed.
|
|
33
|
+
- **Stage 0 arms.** Each arm gets the changed files of the patch.
|
|
34
|
+
- `product`: the first 10 paths of `suggest_tests(files=changed)`, code
|
|
35
|
+
intel 0.1.1 from PyPI.
|
|
36
|
+
- `name`: the test files whose file name contains the stem of a changed
|
|
37
|
+
file, in path order.
|
|
38
|
+
- **Metric.** Test Recall@5: the share of gold files in the first 5 paths.
|
|
39
|
+
Also Hit@5: at least one gold file in the first 5.
|
|
40
|
+
- **Rule.** Go to Stage 1 (agent runs) only if `product` Recall@5 on dev
|
|
41
|
+
is 0.10 or more above `name`. Also, the 95% range from a repository
|
|
42
|
+
bootstrap must be above 0. If not, improve test ranking first.
|
|
43
|
+
- **Failures.** A task where `suggest_tests` fails keeps an empty
|
|
44
|
+
`product` list. Thus a failure counts against the product.
|
|
45
|
+
|
|
46
|
+
The design file gives 121 repositories for the 179 core-mix tasks. The
|
|
47
|
+
correct count is 100. The dev split has 123 tasks from 78 repositories.
|
|
48
|
+
|
|
49
|
+
## Setup
|
|
50
|
+
|
|
51
|
+
- A RunPod CPU pod, 12 workers, one repository group for each worker.
|
|
52
|
+
- For each task: a blobless clone at the base commit, `git clean`, then
|
|
53
|
+
`git apply` of the patch. The `product` arm polls `suggest_tests` every
|
|
54
|
+
5 seconds until the index phase is `ready`, for at most 900 seconds.
|
|
55
|
+
- Two tasks failed in the first pass because `git clone` failed. We
|
|
56
|
+
removed their rows and ran them again. One task (dubbo-3317) failed
|
|
57
|
+
because its patch does not apply at the base commit. It stays in the
|
|
58
|
+
results as a failure.
|
|
59
|
+
- The fix view ran the 19 failed tasks again with the #161 branch. All
|
|
60
|
+
other rows are the same as in the primary view.
|
|
61
|
+
|
|
62
|
+
The pod ran for about 1.3 hours and cost about USD 1.15.
|
|
63
|
+
|
|
64
|
+
## Results
|
|
65
|
+
|
|
66
|
+
| View | Tasks | Failed | `product` R@5 | `name` R@5 | Δ | Range of Δ (95%) | `product` Hit@5 | `name` Hit@5 | Rule met |
|
|
67
|
+
|---|---:|---:|---:|---:|---:|---|---:|---:|---|
|
|
68
|
+
| Primary (0.1.1) | 123 | 20 | 0.469 | 0.477 | -0.008 | -0.117 to +0.101 | 0.496 | 0.512 | No |
|
|
69
|
+
| Fix view (#161) | 123 | 1 | 0.545 | 0.477 | +0.068 | -0.020 to +0.158 | 0.577 | 0.512 | No |
|
|
70
|
+
|
|
71
|
+
The range comes from 10,000 repository bootstrap draws. In the primary
|
|
72
|
+
view, `product` was higher on 18 tasks and `name` on 17. In the fix view,
|
|
73
|
+
the counts are 22 and 10.
|
|
74
|
+
|
|
75
|
+
**Reading.** The primary view is the result of the study. Its Δ is near 0
|
|
76
|
+
and its range includes 0. The fix view shows the product as it will ship
|
|
77
|
+
in the next release. Its Δ is positive, but it is below 0.10, and its
|
|
78
|
+
range includes 0. The race fix does not change the decision.
|
|
79
|
+
|
|
80
|
+
## Where each arm finds the tests
|
|
81
|
+
|
|
82
|
+
These counts use the fix view and the 122 tasks that ran. They are leads
|
|
83
|
+
for the ranking work, not results of the rule.
|
|
84
|
+
|
|
85
|
+
| Language of the change | Tasks | `product` R@5 | `name` R@5 | Empty `product` list |
|
|
86
|
+
|---|---:|---:|---:|---:|
|
|
87
|
+
| Python | 67 | 0.59 | 0.50 | 11 |
|
|
88
|
+
| JavaScript/TypeScript | 23 | 0.78 | 0.61 | 3 |
|
|
89
|
+
| Java | 12 | 0.31 | 0.51 | 6 |
|
|
90
|
+
| Go | 6 | 0.83 | 0.67 | 0 |
|
|
91
|
+
| Rust | 6 | 0.17 | 0.00 | 1 |
|
|
92
|
+
| C# | 5 | 0.00 | 0.20 | 5 |
|
|
93
|
+
| C/C++ | 3 | 0.00 | 0.00 | 3 |
|
|
94
|
+
| No code file | 1 | 0.00 | 0.00 | 1 |
|
|
95
|
+
|
|
96
|
+
- Both arms had a Hit@5 on 53 tasks. Only `product` had one on 18 tasks,
|
|
97
|
+
and only `name` on 10. Neither arm had one on 41 tasks.
|
|
98
|
+
- `suggest_tests` gave an empty list on 30 tasks. On 3 more tasks, a gold
|
|
99
|
+
file was at rank 6 to 10 and not in the first 5.
|
|
100
|
+
- **Python test folders.** All 7 matplotlib tasks got an empty list. For
|
|
101
|
+
example, the change is `lib/matplotlib/figure.py`, and the gold test is
|
|
102
|
+
`lib/matplotlib/tests/test_figure.py`. The name rules do not look in a
|
|
103
|
+
`tests/` folder next to the source file. The imports do not link either,
|
|
104
|
+
because the resolver does not know the `lib/` source root. Prefect
|
|
105
|
+
(`<package>/tests/test_worker.py`) and pylint (`unittest_misc.py`) are
|
|
106
|
+
similar.
|
|
107
|
+
- **Java.** The name rule maps only `src/main/` to `src/test/` with the
|
|
108
|
+
same package. Gold tests in another package (dubbo `version/VersionTest`)
|
|
109
|
+
or in another module (javaparser `javaparser-core-testing`) are not
|
|
110
|
+
found.
|
|
111
|
+
- **C# and C/C++.** `suggest_tests` has no name rule for these languages,
|
|
112
|
+
so it found no test in 8 tasks.
|
|
113
|
+
- **Neither arm.** Many of the 41 tasks have gold tests whose name does
|
|
114
|
+
not contain a changed stem. For example, a change to `figure.py` has the
|
|
115
|
+
gold test `test_constrainedlayout.py`. Only import or reference evidence
|
|
116
|
+
can find these.
|
|
117
|
+
- **The `name` arm.** Its list also holds files that are not tests, such
|
|
118
|
+
as baseline images below `tests/`. These files fill some of its first 5
|
|
119
|
+
places.
|
|
120
|
+
|
|
121
|
+
## What this does not show
|
|
122
|
+
|
|
123
|
+
- The gold set holds the tests that the developers changed. Other
|
|
124
|
+
existing tests can also check the change. Recall is thus a lower bound,
|
|
125
|
+
and the study does not measure precision.
|
|
126
|
+
- The `name` arm is a strong baseline for this gold set. Developers often
|
|
127
|
+
change the test file that has the name of the source file.
|
|
128
|
+
- Stage 0 measures the tool output only. It does not show how an agent
|
|
129
|
+
uses that output.
|
|
130
|
+
- We now know the dev tasks. A ranking change that we tune on them needs
|
|
131
|
+
a check on tasks that we did not look at.
|
|
132
|
+
|
|
133
|
+
## After the ranking change
|
|
134
|
+
|
|
135
|
+
The user approved these steps on 2026-10-11 (`studies/r4-addendum.md` in
|
|
136
|
+
the evals store). Because we used the dev results to make the change, the
|
|
137
|
+
holdout tasks decide. Each holdout task ran once, with the final version.
|
|
138
|
+
|
|
139
|
+
- **Change.** PR #164 at commit `381ece4`. `suggest_tests` finds tests by
|
|
140
|
+
name in the whole repository, and any folder that holds a top-level
|
|
141
|
+
Python package is an import root.
|
|
142
|
+
- **Setup.** The same script, arms and metric, on a new RunPod CPU pod
|
|
143
|
+
(128 CPUs). Dev and holdout ran at the same time, with 12 workers each.
|
|
144
|
+
The pod ran for about 0.5 hours and cost about USD 0.45.
|
|
145
|
+
- **Two record-only fields.** `product_detail` holds the priority of each
|
|
146
|
+
candidate. `name_v011` is the name grep with the test detector of 0.1.1.
|
|
147
|
+
The `name` arm uses the detector of the installed version, and #164 adds
|
|
148
|
+
.NET, C# and C/C++ test names to it.
|
|
149
|
+
|
|
150
|
+
| Set | Tasks | Failed | `product` R@5 | `name` R@5 | Δ | Range of Δ (95%) | `product` Hit@5 | `name` Hit@5 | Higher / lower | Rule met |
|
|
151
|
+
|---|---:|---:|---:|---:|---:|---|---:|---:|---:|---|
|
|
152
|
+
| Dev (tuning) | 123 | 1 | 0.694 | 0.481 | +0.213 | +0.139 to +0.286 | 0.740 | 0.520 | 33 / 1 | Yes |
|
|
153
|
+
| Holdout (decides) | 56 | 1 | 0.640 | 0.586 | +0.054 | -0.047 to +0.167 | 0.696 | 0.625 | 6 / 3 | No |
|
|
154
|
+
|
|
155
|
+
With the 0.1.1 detector, the name grep had 0.477 on dev and 0.580 on the
|
|
156
|
+
holdout. The Δ changes by less than 0.01. Each set has one task whose
|
|
157
|
+
patch does not apply at the base commit (dubbo-3317 and dubbo-4678).
|
|
158
|
+
|
|
159
|
+
**Reading.** On dev, `suggest_tests` improved on 21 tasks against the fix
|
|
160
|
+
view, and no task got worse. All 7 matplotlib tasks had no test before.
|
|
161
|
+
After the change, their Recall@5 is 0.50. On the holdout, the gain is
|
|
162
|
+
small, and the range includes 0. By the rule, this is no evidence that
|
|
163
|
+
the product names the tests for a change better than a file-name grep.
|
|
164
|
+
The name grep is strong on the holdout. Both arms had a Hit@5 on 33 of
|
|
165
|
+
55 tasks, because the developers changed the test that has the name of
|
|
166
|
+
the source file.
|
|
167
|
+
|
|
168
|
+
**Holdout misses.** These are leads only. The holdout tasks cannot check
|
|
169
|
+
a fix for them.
|
|
170
|
+
|
|
171
|
+
- `suggest_tests` found no test on 8 tasks.
|
|
172
|
+
- In coreutils, the changed file is `src/uu/cp/src/cp.rs`. The name
|
|
173
|
+
finder skips names with fewer than 3 letters, so it did not find
|
|
174
|
+
`tests/by-util/test_cp.rs`.
|
|
175
|
+
- In grommet and decap-cms, the gold set holds a Jest snapshot file
|
|
176
|
+
(`.snap`). `suggest_tests` gives only test source files, and the name
|
|
177
|
+
grep also gives data files.
|
|
178
|
+
|
|
179
|
+
## Next
|
|
180
|
+
|
|
181
|
+
1. Merge #164 as a product change. Its claims are the numbers above, not
|
|
182
|
+
a measured gain on new tasks.
|
|
183
|
+
2. No R4 agent runs. This also gives no new evidence for the cut of the
|
|
184
|
+
daily tool list.
|
|
185
|
+
3. Any new test-ranking study needs new tasks, because we know the results
|
|
186
|
+
of all 179 tasks now.
|
|
@@ -892,10 +892,10 @@ class ASTService:
|
|
|
892
892
|
"""Return all symbols defined in *path*."""
|
|
893
893
|
self._ensure_initialized()
|
|
894
894
|
rel = self._to_rel(path)
|
|
895
|
-
qnames = self._index.file_symbols.get(rel, set())
|
|
896
895
|
result: list[SymbolLocation] = []
|
|
897
|
-
|
|
898
|
-
|
|
896
|
+
with self._index._lock: # Background hydration adds to these sets.
|
|
897
|
+
for qn in self._index.file_symbols.get(rel, set()):
|
|
898
|
+
result.extend(self._index.definitions.get(qn, []))
|
|
899
899
|
return result
|
|
900
900
|
|
|
901
901
|
def find_symbol(self, name: str, *, include_shadowed: bool = False) -> list[SymbolLocation]:
|
|
@@ -366,28 +366,52 @@ def _build_file_index(
|
|
|
366
366
|
normalized = f.relative_path.replace(os.sep, "/")
|
|
367
367
|
file_index[normalized] = f.relative_path
|
|
368
368
|
|
|
369
|
-
# Detect source prefixes and add stripped alternate keys.
|
|
370
|
-
|
|
371
|
-
source_prefixes = set(_detect_source_prefixes(root_dir))
|
|
372
|
-
for normalized in file_index:
|
|
373
|
-
path = "/" + normalized
|
|
374
|
-
if normalized.endswith("/__init__.py") and "/src/" in path:
|
|
375
|
-
source_prefixes.add(path[1:path.index("/src/") + 5])
|
|
369
|
+
# Detect source prefixes and add stripped alternate keys.
|
|
370
|
+
source_prefixes = set(_detect_source_prefixes(root_dir)) | _python_import_roots(file_index)
|
|
376
371
|
if source_prefixes:
|
|
377
|
-
|
|
378
|
-
for normalized, rel_path in file_index.items():
|
|
379
|
-
for prefix in sorted(source_prefixes):
|
|
380
|
-
if normalized.startswith(prefix):
|
|
381
|
-
stripped = normalized[len(prefix):]
|
|
382
|
-
# Don't override direct matches
|
|
383
|
-
if stripped not in file_index:
|
|
384
|
-
extra[stripped] = rel_path
|
|
385
|
-
file_index.update(extra)
|
|
372
|
+
_add_root_keys(file_index, source_prefixes)
|
|
386
373
|
|
|
387
374
|
file_index.configure_javascript(root_dir)
|
|
388
375
|
return file_index
|
|
389
376
|
|
|
390
377
|
|
|
378
|
+
def _python_import_roots(paths) -> set[str]:
|
|
379
|
+
"""Folders that hold a top-level Python package, as ``lib/`` for ``lib/pkg/__init__.py``.
|
|
380
|
+
|
|
381
|
+
Such a folder is an import root: src/, packages/<name>/src/ of a monorepo,
|
|
382
|
+
lib/ of matplotlib or python/ of ray.
|
|
383
|
+
"""
|
|
384
|
+
roots: set[str] = set()
|
|
385
|
+
for path in paths:
|
|
386
|
+
package, _, name = path.rpartition("/")
|
|
387
|
+
parent = package.rpartition("/")[0]
|
|
388
|
+
if name == "__init__.py" and parent and parent + "/__init__.py" not in paths:
|
|
389
|
+
roots.add(parent + "/")
|
|
390
|
+
return roots
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def _add_root_keys(file_index: dict[str, str], roots: set[str]) -> None:
|
|
394
|
+
"""Add a key without the root prefix for each file below an import root."""
|
|
395
|
+
extra: dict[str, str] = {}
|
|
396
|
+
for normalized, rel_path in file_index.items():
|
|
397
|
+
parts = normalized.split("/")
|
|
398
|
+
# Shallow roots first, so a deeper root wins, as in sorted prefix order.
|
|
399
|
+
for depth in range(1, len(parts)):
|
|
400
|
+
prefix = "/".join(parts[:depth]) + "/"
|
|
401
|
+
stripped = normalized[len(prefix):]
|
|
402
|
+
# Don't override direct matches
|
|
403
|
+
if prefix in roots and stripped not in file_index:
|
|
404
|
+
extra[stripped] = rel_path
|
|
405
|
+
file_index.update(extra)
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
def python_module_index(paths) -> dict[str, str]:
|
|
409
|
+
"""Module-path keys for ``_resolve_python_import`` from repository paths alone."""
|
|
410
|
+
file_index = {path: path for path in paths}
|
|
411
|
+
_add_root_keys(file_index, _python_import_roots(file_index))
|
|
412
|
+
return file_index
|
|
413
|
+
|
|
414
|
+
|
|
391
415
|
def _resolve_python_import(module: str, source_file: str, file_index: dict[str, str]) -> str | None:
|
|
392
416
|
"""Resolve a Python import module name to a relative file path.
|
|
393
417
|
|
|
@@ -438,15 +438,17 @@ class CrossRefIndex:
|
|
|
438
438
|
|
|
439
439
|
def get_definitions(self, symbol_name: str, *, include_shadowed: bool = False) -> list[SymbolLocation]:
|
|
440
440
|
"""Look up definitions for a symbol (exact or suffix match)."""
|
|
441
|
-
#
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
441
|
+
# The lock keeps a background index writer from changing the dict during the scan.
|
|
442
|
+
with self._lock:
|
|
443
|
+
# Try exact qualified name first
|
|
444
|
+
if symbol_name in self.definitions and not include_shadowed:
|
|
445
|
+
return self.definitions[symbol_name]
|
|
446
|
+
# Try suffix match (e.g. "discover_files" matches "CodebaseContextManager.discover_files")
|
|
447
|
+
results: list[SymbolLocation] = []
|
|
448
|
+
for qname, locs in self.definitions.items():
|
|
449
|
+
if qname == symbol_name or qname.endswith(f".{symbol_name}"):
|
|
450
|
+
results.extend(locs)
|
|
451
|
+
return results
|
|
450
452
|
|
|
451
453
|
def search_definitions(
|
|
452
454
|
self,
|
|
@@ -455,7 +457,18 @@ class CrossRefIndex:
|
|
|
455
457
|
limit: int = 50,
|
|
456
458
|
kind_filter: str = "",
|
|
457
459
|
) -> list[tuple[SymbolLocation, float]]:
|
|
458
|
-
"""Multi-strategy symbol search returning (location, score) pairs.
|
|
460
|
+
"""Multi-strategy symbol search returning (location, score) pairs."""
|
|
461
|
+
with self._lock:
|
|
462
|
+
return self._search_definitions_locked(symbol_name, limit=limit, kind_filter=kind_filter)
|
|
463
|
+
|
|
464
|
+
def _search_definitions_locked(
|
|
465
|
+
self,
|
|
466
|
+
symbol_name: str,
|
|
467
|
+
*,
|
|
468
|
+
limit: int,
|
|
469
|
+
kind_filter: str,
|
|
470
|
+
) -> list[tuple[SymbolLocation, float]]:
|
|
471
|
+
"""Search the definitions. The caller holds the lock.
|
|
459
472
|
|
|
460
473
|
Search strategies (in priority order):
|
|
461
474
|
1. Exact qualified name match (score 1.0)
|
|
@@ -536,9 +549,10 @@ class CrossRefIndex:
|
|
|
536
549
|
# Include exact and qualified candidates; an exact key must not hide others.
|
|
537
550
|
# Suffix match (e.g. "clear" matches refs keyed as "MCPMetaTools.clear")
|
|
538
551
|
results: list[SymbolRef] = []
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
552
|
+
with self._lock:
|
|
553
|
+
for ref_name, refs in self.references.items():
|
|
554
|
+
if ref_name == symbol_name or ref_name.endswith(f".{symbol_name}"):
|
|
555
|
+
results.extend(refs)
|
|
542
556
|
return results
|
|
543
557
|
|
|
544
558
|
def get_dependents(self, file_path: str) -> set[str]:
|
|
@@ -23,7 +23,7 @@ logger = logging.getLogger(__name__)
|
|
|
23
23
|
SCHEMA_VERSION = "6"
|
|
24
24
|
# Bump the suffix when a change alters the saved graph edges, for example import resolution.
|
|
25
25
|
# Stores keep their tables, and the next start rebuilds the index once.
|
|
26
|
-
SNAPSHOT_KEY = "
|
|
26
|
+
SNAPSHOT_KEY = "structural_snapshot_v3"
|
|
27
27
|
SQLITE_BUSY_TIMEOUT_MS = 30_000
|
|
28
28
|
INDEX_INIT_LOCK_TIMEOUT_SECONDS = 30
|
|
29
29
|
|
|
@@ -340,6 +340,9 @@ class DbAnalysisProvider:
|
|
|
340
340
|
|
|
341
341
|
from sqlalchemy import select
|
|
342
342
|
|
|
343
|
+
from attocode_intel._internal.integrations.context.codebase_context import (
|
|
344
|
+
python_module_index,
|
|
345
|
+
)
|
|
343
346
|
from attocode_intel.db.models import FileContent
|
|
344
347
|
from attocode_intel.indexing.full_indexer import _resolve_import_path
|
|
345
348
|
from attocode_intel.indexing.parser import detect_language, extract_imports
|
|
@@ -347,6 +350,7 @@ class DbAnalysisProvider:
|
|
|
347
350
|
logger = logging.getLogger(__name__)
|
|
348
351
|
manifest = branch_ctx.manifest # path -> sha
|
|
349
352
|
known_paths = set(manifest.keys())
|
|
353
|
+
python_index = python_module_index(known_paths)
|
|
350
354
|
sha_to_path = {sha: path for path, sha in manifest.items()}
|
|
351
355
|
content_shas = list(set(manifest.values()))
|
|
352
356
|
|
|
@@ -378,7 +382,8 @@ class DbAnalysisProvider:
|
|
|
378
382
|
raw_content = content if isinstance(content, bytes) else content.encode("utf-8")
|
|
379
383
|
imports = extract_imports(raw_content, source_path, language)
|
|
380
384
|
for imp in imports:
|
|
381
|
-
target = _resolve_import_path(imp, source_path, known_paths, language
|
|
385
|
+
target = _resolve_import_path(imp, source_path, known_paths, language,
|
|
386
|
+
python_index=python_index)
|
|
382
387
|
if target and target != source_path:
|
|
383
388
|
edges.append({
|
|
384
389
|
"source": source_path,
|
{attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/full_indexer.py
RENAMED
|
@@ -69,18 +69,23 @@ def _resolve_import_path(
|
|
|
69
69
|
known_paths: set[str],
|
|
70
70
|
language: str | None,
|
|
71
71
|
aliases: dict[str, str] | None = None,
|
|
72
|
+
python_index: dict[str, str] | None = None,
|
|
72
73
|
) -> str | None:
|
|
73
74
|
"""Resolve an import string to a file path in the repo.
|
|
74
75
|
|
|
75
|
-
Returns the matching path or None if unresolvable.
|
|
76
|
+
Returns the matching path or None if unresolvable. For Python, pass
|
|
77
|
+
``python_index = python_module_index(known_paths)`` when resolving many imports.
|
|
76
78
|
"""
|
|
77
79
|
from pathlib import PurePosixPath
|
|
78
80
|
|
|
79
81
|
if language == "python":
|
|
80
|
-
#
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
# The resolver of the local index: relative imports and import roots such as src/ or lib/.
|
|
83
|
+
from attocode_intel._internal.integrations.context.codebase_context import (
|
|
84
|
+
_resolve_python_import,
|
|
85
|
+
python_module_index,
|
|
86
|
+
)
|
|
87
|
+
return _resolve_python_import(import_name, source_path, python_index or python_module_index(known_paths))
|
|
88
|
+
if language in ("javascript", "typescript"):
|
|
84
89
|
if import_name.startswith("."):
|
|
85
90
|
# Relative import — resolve against source dir
|
|
86
91
|
source_dir = str(PurePosixPath(source_path).parent)
|
|
@@ -249,8 +254,13 @@ class FullIndexer:
|
|
|
249
254
|
if overlay_updates:
|
|
250
255
|
await overlay.set_files_batch(branch_id, overlay_updates)
|
|
251
256
|
|
|
257
|
+
from attocode_intel._internal.integrations.context.codebase_context import (
|
|
258
|
+
python_module_index,
|
|
259
|
+
)
|
|
260
|
+
|
|
252
261
|
# Resolve path aliases from tsconfig/jsconfig
|
|
253
262
|
aliases = _load_path_aliases(known_paths, config_contents)
|
|
263
|
+
python_index = python_module_index(known_paths)
|
|
254
264
|
|
|
255
265
|
# Second pass: resolve imports to dependencies
|
|
256
266
|
self._progress({"phase": "resolving_dependencies", "total": len(deferred_deps), "current": 0})
|
|
@@ -260,7 +270,8 @@ class FullIndexer:
|
|
|
260
270
|
continue
|
|
261
271
|
deps: list[dict] = []
|
|
262
272
|
for imp in imports:
|
|
263
|
-
target_path = _resolve_import_path(imp, source_path, known_paths, language, aliases=aliases
|
|
273
|
+
target_path = _resolve_import_path(imp, source_path, known_paths, language, aliases=aliases,
|
|
274
|
+
python_index=python_index)
|
|
264
275
|
if target_path and target_path in path_to_sha:
|
|
265
276
|
deps.append({
|
|
266
277
|
"target_sha": path_to_sha[target_path],
|
{attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/indexing/incremental.py
RENAMED
|
@@ -159,9 +159,15 @@ class IncrementalPipeline:
|
|
|
159
159
|
for u_path, u_sha, _ in overlay_updates:
|
|
160
160
|
path_to_sha[u_path] = u_sha
|
|
161
161
|
|
|
162
|
+
python_index = None
|
|
163
|
+
if language == "python":
|
|
164
|
+
from attocode_intel._internal.integrations.context.codebase_context import (
|
|
165
|
+
python_module_index,
|
|
166
|
+
)
|
|
167
|
+
python_index = python_module_index(known_paths)
|
|
162
168
|
deps = []
|
|
163
169
|
for imp in imports:
|
|
164
|
-
target = _resolve_import_path(imp, path, known_paths, language)
|
|
170
|
+
target = _resolve_import_path(imp, path, known_paths, language, python_index=python_index)
|
|
165
171
|
if target and target in path_to_sha:
|
|
166
172
|
deps.append({
|
|
167
173
|
"target_sha": path_to_sha[target],
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"""Symbol-focused test evidence, reusing the parsed index instead of scanning file bodies."""
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
|
+
import re
|
|
4
5
|
from pathlib import PurePosixPath
|
|
5
6
|
|
|
6
7
|
from attocode_intel.focused_evidence import task_terms, terms
|
|
@@ -10,8 +11,77 @@ def is_test_path(path):
|
|
|
10
11
|
parts = PurePosixPath(path).parts
|
|
11
12
|
name = parts[-1] if parts else ""
|
|
12
13
|
return (any(p in {"test", "tests", "__tests__", "spec", "specs"} for p in parts)
|
|
14
|
+
# .NET test projects: UnitsNet.Tests/, Kavita.Services.Tests/
|
|
15
|
+
or any(p.endswith((".Tests", ".Test", ".UnitTests", ".IntegrationTests")) for p in parts[:-1])
|
|
13
16
|
or name.startswith("test_") or ".test." in name or ".spec." in name
|
|
14
|
-
or name.endswith(("_test.py", "_test.go", "Test.java", "Test.kt"
|
|
17
|
+
or name.endswith(("_test.py", "_test.go", "Test.java", "Test.kt", "Tests.java", "Tests.kt",
|
|
18
|
+
"Test.cs", "Tests.cs", "_test.c", "_test.cc", "_test.cpp", "_unittest.cc")))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
_TEST_PREFIX = re.compile(r"^(?:unit)?tests?[_-]|^Tests?(?=[A-Z])")
|
|
22
|
+
_TEST_SUFFIX = re.compile(r"(?:[_-](?:unit)?(?:tests?|spec)|Tests?|Spec)$")
|
|
23
|
+
# These names say little; the folder names the module (pkg/__init__.py, src/index.ts).
|
|
24
|
+
_GENERIC_STEMS = {"__init__", "index", "mod", "lib", "main"}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _plain(name):
|
|
28
|
+
return name.lower().replace("_", "").replace("-", "")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def file_subject(path):
|
|
32
|
+
"""The name that a test for this file would carry: lib/pkg/figure.py -> figure."""
|
|
33
|
+
p = PurePosixPath(path)
|
|
34
|
+
stem = p.name.split(".")[0]
|
|
35
|
+
if stem in _GENERIC_STEMS and p.parent.name:
|
|
36
|
+
stem = p.parent.name
|
|
37
|
+
return _plain(stem)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_subject(path):
|
|
41
|
+
"""The name that a test file is for: test_figure.py, FigureTest.java, figure.test.ts -> figure.
|
|
42
|
+
|
|
43
|
+
None when the name has no test affix: a fixture or generated file in a test folder.
|
|
44
|
+
"""
|
|
45
|
+
p = PurePosixPath(path)
|
|
46
|
+
stem = p.name.split(".")[0]
|
|
47
|
+
core = _TEST_SUFFIX.sub("", _TEST_PREFIX.sub("", stem))
|
|
48
|
+
if core == stem and ".test." not in p.name and ".spec." not in p.name and "__tests__" not in p.parts:
|
|
49
|
+
return None
|
|
50
|
+
return _plain(core)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def folder_overlap(path, other):
|
|
54
|
+
"""The number of folder names that two paths share, in any position."""
|
|
55
|
+
return len(set(PurePosixPath(path).parent.parts) & set(PurePosixPath(other).parent.parts))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def name_matched_tests(changed_file, test_paths, limit=10):
|
|
59
|
+
"""Test files named for ``changed_file``, best first, as (path, priority, reason).
|
|
60
|
+
|
|
61
|
+
Priority 1: the nearest tests whose name without the test affix is the file name, if
|
|
62
|
+
they share a folder name with it. Priority 3: the same name farther away. Priority 4: the test file name only
|
|
63
|
+
contains the file name, as a plain file-name search finds it. Nearest means the most
|
|
64
|
+
folder names in common, so src/test/java/org/x mirrors src/main/java/org/x.
|
|
65
|
+
"""
|
|
66
|
+
subject = file_subject(changed_file)
|
|
67
|
+
if len(subject) < 2:
|
|
68
|
+
return []
|
|
69
|
+
|
|
70
|
+
def shared(path):
|
|
71
|
+
return folder_overlap(path, changed_file)
|
|
72
|
+
|
|
73
|
+
exact = [path for path in test_paths if test_subject(path) == subject]
|
|
74
|
+
named = set(exact)
|
|
75
|
+
# A short name is part of too many file names: cp.rs gets test_cp.rs, not every *cp* file.
|
|
76
|
+
loose = [path for path in test_paths if len(subject) >= 3 and path not in named
|
|
77
|
+
and subject in _plain(PurePosixPath(path).name)]
|
|
78
|
+
exact.sort(key=lambda path: (-shared(path), len(path), path))
|
|
79
|
+
loose.sort(key=lambda path: (-shared(path), len(path), path))
|
|
80
|
+
nearest = shared(exact[0]) if exact else 0
|
|
81
|
+
rows = [(path, 1 if nearest and shared(path) == nearest else 3, f"Test file named for `{changed_file}`")
|
|
82
|
+
for path in exact]
|
|
83
|
+
rows += [(path, 4, f"Test file name contains `{PurePosixPath(changed_file).stem}`") for path in loose]
|
|
84
|
+
return rows[:limit]
|
|
15
85
|
|
|
16
86
|
|
|
17
87
|
def rank_symbol_tests(ast, suggestions, files, symbol_name, task_hint, distances,
|
{attocode_code_intel-0.1.1 → attocode_code_intel-0.1.3}/src/attocode_intel/tools/composite_tools.py
RENAMED
|
@@ -123,6 +123,30 @@ def _find_test_files_by_convention(file_path: str, project_dir: str) -> list[str
|
|
|
123
123
|
return existing
|
|
124
124
|
|
|
125
125
|
|
|
126
|
+
def _test_paths(project_dir: str) -> list[str]:
|
|
127
|
+
"""Tracked test source files. The index can leave out tests of a large repository."""
|
|
128
|
+
from pathlib import PurePosixPath
|
|
129
|
+
|
|
130
|
+
from attocode_intel._internal.integrations.context.codebase_context import EXTENSION_LANGUAGES
|
|
131
|
+
from attocode_intel.test_ranking import is_test_path
|
|
132
|
+
|
|
133
|
+
try:
|
|
134
|
+
listed = subprocess.run(
|
|
135
|
+
["git", "ls-files", "-z"],
|
|
136
|
+
cwd=project_dir, capture_output=True, text=True, timeout=30, check=True,
|
|
137
|
+
).stdout.split("\0")
|
|
138
|
+
except (OSError, subprocess.SubprocessError):
|
|
139
|
+
listed = []
|
|
140
|
+
if not any(listed): # Not a git repository, or nothing tracked yet.
|
|
141
|
+
try:
|
|
142
|
+
listed = [f.relative_path for f in _get_context_mgr()._files]
|
|
143
|
+
except Exception:
|
|
144
|
+
return []
|
|
145
|
+
data = {"data", "yaml", "json", "toml", "markdown", "html", "css", "scss"}
|
|
146
|
+
return [path for path in listed if path
|
|
147
|
+
and EXTENSION_LANGUAGES.get(PurePosixPath(path).suffix, "data") not in data and is_test_path(path)]
|
|
148
|
+
|
|
149
|
+
|
|
126
150
|
# ---------------------------------------------------------------------------
|
|
127
151
|
# Tools
|
|
128
152
|
# ---------------------------------------------------------------------------
|
|
@@ -429,6 +453,13 @@ def suggest_tests_data(files: list[str], *, symbol_name: str | None = None,
|
|
|
429
453
|
reason=f"Direct test file for `{f}`",
|
|
430
454
|
)
|
|
431
455
|
|
|
456
|
+
# Test files named for a changed file, anywhere in the repository.
|
|
457
|
+
from attocode_intel.test_ranking import folder_overlap, name_matched_tests
|
|
458
|
+
test_paths = _test_paths(project_dir)
|
|
459
|
+
for f in files:
|
|
460
|
+
for test_file, priority, reason in name_matched_tests(f, test_paths):
|
|
461
|
+
_add_suggestion(test_file, priority, reason)
|
|
462
|
+
|
|
432
463
|
# --- Priority 2: Import-based discovery ---
|
|
433
464
|
try:
|
|
434
465
|
ctx = _get_context_mgr()
|
|
@@ -558,10 +589,14 @@ def suggest_tests_data(files: list[str], *, symbol_name: str | None = None,
|
|
|
558
589
|
except (AttributeError, OSError) as exc:
|
|
559
590
|
logger.debug("Test reference ranking incomplete: %s", exc)
|
|
560
591
|
|
|
561
|
-
# Sort by evidence, then put repository tests before documentation examples.
|
|
592
|
+
# Sort by evidence, then put repository tests before documentation examples, then nearest first.
|
|
593
|
+
def nearness(path):
|
|
594
|
+
return max(folder_overlap(path, changed) for changed in files) if files else 0
|
|
595
|
+
|
|
562
596
|
sorted_suggestions = sorted(
|
|
563
597
|
suggestions.items(),
|
|
564
|
-
key=lambda kv: (kv[1]["priority"], kv[0] not in representatives, -symbol_hits.get(kv[0], 0),
|
|
598
|
+
key=lambda kv: (kv[1]["priority"], kv[0] not in representatives, -symbol_hits.get(kv[0], 0),
|
|
599
|
+
kv[0].startswith("docs"), -nearness(kv[0]), kv[0]),
|
|
565
600
|
)
|
|
566
601
|
|
|
567
602
|
return {"files": files, "candidates": [
|
|
@@ -598,6 +633,7 @@ def format_test_suggestions(data: dict) -> str:
|
|
|
598
633
|
1: "DIRECT",
|
|
599
634
|
2: "IMPORTS",
|
|
600
635
|
3: "INDIRECT",
|
|
636
|
+
4: "NAME",
|
|
601
637
|
}
|
|
602
638
|
|
|
603
639
|
lines = [
|