better-code-review-graph 3.17.2b2__tar.gz → 3.18.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.
- better_code_review_graph-3.18.0/.claude-plugin/plugin.json +71 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.github/workflows/cd.yml +6 -6
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.github/workflows/ci.yml +6 -6
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/AGENTS.md +54 -14
- better_code_review_graph-3.18.0/CHANGELOG.md +2382 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/CLAUDE.md +50 -16
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/Dockerfile +1 -1
- better_code_review_graph-3.18.0/PKG-INFO +392 -0
- better_code_review_graph-3.18.0/README.md +361 -0
- better_code_review_graph-3.18.0/hooks/hooks.json +25 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/migrations/versions/005_temporal_columns.py +104 -29
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/pyproject.toml +21 -14
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/renovate.json +8 -0
- better_code_review_graph-3.18.0/server.json +79 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/credential_state.py +34 -8
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/embeddings.py +175 -159
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/exporter.py +13 -2
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/federation.py +23 -13
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/graph.py +8 -1
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/incremental.py +36 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/parser.py +197 -127
- better_code_review_graph-3.18.0/src/better_code_review_graph/relay_schema.py +103 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/relay_setup.py +10 -6
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/security/semgrep_engine.py +6 -2
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/server.py +34 -10
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/summarizer.py +134 -94
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/temporal.py +21 -15
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/tools.py +156 -75
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_coverage_gaps.py +54 -139
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_credential_state.py +55 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_embeddings.py +320 -30
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_graph.py +49 -0
- better_code_review_graph-3.17.2b2/tests/test_heuristic_scanner.py → better_code_review_graph-3.18.0/tests/test_heuristic.py +38 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_incremental.py +19 -0
- better_code_review_graph-3.18.0/tests/test_multi_user_dispatch.py +278 -0
- better_code_review_graph-3.18.0/tests/test_per_sub_graph_db.py +135 -0
- better_code_review_graph-3.18.0/tests/test_relay_schema.py +50 -0
- better_code_review_graph-3.18.0/tests/test_security_injection.py +79 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_semgrep_engine.py +15 -4
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_server.py +53 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_summarizer.py +327 -153
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_temporal_migration.py +88 -24
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_tools_full.py +22 -9
- better_code_review_graph-3.18.0/tests/test_typescript_coverage_gaps.py +57 -0
- better_code_review_graph-3.18.0/uv.lock +2303 -0
- better_code_review_graph-3.17.2b2/.claude-plugin/plugin.json +0 -57
- better_code_review_graph-3.17.2b2/.github/best_practices.md +0 -25
- better_code_review_graph-3.17.2b2/CHANGELOG.md +0 -149
- better_code_review_graph-3.17.2b2/PKG-INFO +0 -310
- better_code_review_graph-3.17.2b2/README.md +0 -277
- better_code_review_graph-3.17.2b2/hooks/hooks.json +0 -25
- better_code_review_graph-3.17.2b2/hooks/session-start.sh +0 -22
- better_code_review_graph-3.17.2b2/server.json +0 -67
- better_code_review_graph-3.17.2b2/src/better_code_review_graph/relay_schema.py +0 -67
- better_code_review_graph-3.17.2b2/tests/test_relay_schema.py +0 -17
- better_code_review_graph-3.17.2b2/uv.lock +0 -2261
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.agents/skills/build-graph/SKILL.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.agents/skills/review-delta/SKILL.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.agents/skills/review-pr/SKILL.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.coderabbit.yaml +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.dockerignore +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.github/CODEOWNERS +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.github/rulesets/main.json +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.gitignore +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.infisical.json +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.pre-commit-config.yaml +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/BREAKING_CHANGES.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/CODE_OF_CONDUCT.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/CONTRIBUTING.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/LICENSE +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/SECURITY.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/alembic.ini +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/migrations/README +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/migrations/env.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/migrations/script.py.mako +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/migrations/versions/001_baseline.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/migrations/versions/002_summary_columns.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/migrations/versions/003_federation.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/migrations/versions/004_security_tags.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/migrations/versions/006_commits_table.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/rules/heuristic/cwe-22-path-traversal.yaml +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/rules/heuristic/cwe-78-shell-command-sink.yaml +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/rules/heuristic/cwe-89-sql-string-format.yaml +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/rules/heuristic/cwe-95-eval-on-input.yaml +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/rules/heuristic/hardcoded-secret.yaml +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/rules/semgrep/curated.yaml +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/scripts/enforce-commit.sh +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/scripts/preserve-diacritics.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/scripts/test_preserve_diacritics.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/semantic-release.toml +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/skills/refactor-check/SKILL.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/skills/review-delta/SKILL.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/skills/review-pr/SKILL.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/__init__.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/__main__.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/cli.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/docs/__init__.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/docs/config.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/docs/graph.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/docs/query.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/docs/recipes.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/docs/review.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/docs/security.md +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/py.typed +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/resolver/__init__.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/resolver/_types.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/resolver/fallback.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/resolver/go.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/resolver/java.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/resolver/python.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/resolver/rust.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/resolver/typescript.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/security/__init__.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/src/better_code_review_graph/security/heuristic.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/__init__.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/conftest.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/conftest_e2e.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/e2e_mcp_protocol_test.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/Sample.cs +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/SampleJava.java +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/caller_example.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/multi_call_example.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample.c +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample.cpp +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample.kt +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample.php +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample.rb +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample.sol +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample.swift +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample_go.go +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample_python.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample_rust.rs +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/sample_typescript.ts +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/fixtures/test_sample.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/integration/__init__.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/integration/test_multi_user_remote.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_alembic_baseline.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_as_of_diff.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_auto_resolve_ambiguity.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_bare_suffix_correctness.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_callers_not_found_reason.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_callers_of_coverage.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_cli.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_commits_migration.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_config_open_relay_registered.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_credential_state_stdio_no_fallback.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_dynamic_dispatch_hints.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_e2e.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_embedding_migration.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_embeddings_extra.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_export_graph_dispatch.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_export_graph_dispatch_path_traversal.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_exporter.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_federation.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_federation_migration.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_federation_smoke.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_full_live.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_g6_ux_status_accuracy.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_get_docs_section_error_path.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_get_review_context_no_diff.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_graph_batch_fetch.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_graph_extra.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_graph_get_edges_by_targets_coverage.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_graph_stats_error_coverage.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_handle_not_found_coverage.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_help_recipes.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_impact_payload_truncation.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_incremental_extra.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_kind_filter_optimization.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_kinds_error_path.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_list_graph_stats_coverage.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_list_kinds_coverage.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_live_mcp.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_lookup_node_directly.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_multi_user.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_multilang.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_oserror_coverage.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_parser.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_parser_extra.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_parser_source_text.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_path_resolution_fallback.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_payload_estimation.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_per_plugin_storage_migration.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_performance_n1.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_performance_n1_embeddings.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_phase_3_smoke.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_pre_2_0_backup.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_relay_setup.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_renamed_in_diff.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_renamed_in_diff_exception.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_repo_filter.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_repo_filter_batching.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_repo_id_persistence.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_resolve_search_candidates.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_resolver_dispatcher.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_resolver_fallback.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_resolver_go.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_resolver_java.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_resolver_python.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_resolver_rust.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_resolver_typescript.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_response_header.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_review_delta_line_shifts.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_review_languages_filter.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_reviewer_summary.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_search_edges_by_target_names.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_search_keyword_warning.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_security_path_traversal.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_security_scan_batching.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_security_tags_migration.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_security_tool.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_server_help_coverage.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_serverinfo_version.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_setup_tool.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_spot_check.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_sql_security.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_stdio_direct.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_summarize_graph_dispatch.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_summary_schema.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_temporal.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_tools.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_tools_build_error_coverage.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_tools_get_docs_section_coverage.py +0 -0
- {better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/tests/test_v17_coverage_gaps.py +0 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "better-code-review-graph",
|
|
3
|
+
"description": "Knowledge graph for token-efficient code reviews -- semantic search and call-graph resolution across your codebase.",
|
|
4
|
+
"version": "3.18.0",
|
|
5
|
+
"userConfig": {
|
|
6
|
+
"EMBEDDING_MODELS": {
|
|
7
|
+
"type": "string",
|
|
8
|
+
"title": "Embedding model chain (optional)",
|
|
9
|
+
"description": "CSV 'provider/model,provider/model' (order = litellm fallback); provider inferred from prefix. Empty = local ONNX (qwen3-embed). Example: jina_ai/jina-embeddings-v5-text-small,gemini/gemini-embedding-001",
|
|
10
|
+
"required": false
|
|
11
|
+
},
|
|
12
|
+
"SUMMARY_MODELS": {
|
|
13
|
+
"type": "string",
|
|
14
|
+
"title": "Summarizer model chain (optional)",
|
|
15
|
+
"description": "CSV 'provider/model,...' for the graph summarize action; provider inferred from prefix. Empty = summaries disabled. Chat-completion providers only (gemini/openai). Example: gemini/gemini-2.5-flash,openai/gpt-4o-mini",
|
|
16
|
+
"required": false
|
|
17
|
+
},
|
|
18
|
+
"JINA_AI_API_KEY": {
|
|
19
|
+
"type": "string",
|
|
20
|
+
"title": "Jina AI API key (optional)",
|
|
21
|
+
"description": "Enables jina_ai/ embedding models referenced in EMBEDDING_MODELS. Without any cloud key the server uses local ONNX. https://jina.ai/api-dashboard/",
|
|
22
|
+
"sensitive": true,
|
|
23
|
+
"required": false
|
|
24
|
+
},
|
|
25
|
+
"GEMINI_API_KEY": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"title": "Gemini API key (optional)",
|
|
28
|
+
"description": "Enables gemini/ models referenced in EMBEDDING_MODELS / SUMMARY_MODELS. Free tier available. https://aistudio.google.com/apikey",
|
|
29
|
+
"sensitive": true,
|
|
30
|
+
"required": false
|
|
31
|
+
},
|
|
32
|
+
"OPENAI_API_KEY": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"title": "OpenAI API key (optional)",
|
|
35
|
+
"description": "Enables openai/ models referenced in EMBEDDING_MODELS / SUMMARY_MODELS. https://platform.openai.com/api-keys",
|
|
36
|
+
"sensitive": true,
|
|
37
|
+
"required": false
|
|
38
|
+
},
|
|
39
|
+
"COHERE_API_KEY": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"title": "Cohere API key (optional)",
|
|
42
|
+
"description": "Enables cohere/ embedding models referenced in EMBEDDING_MODELS. https://dashboard.cohere.com/api-keys",
|
|
43
|
+
"sensitive": true,
|
|
44
|
+
"required": false
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
"author": {
|
|
48
|
+
"name": "n24q02m",
|
|
49
|
+
"url": "https://github.com/n24q02m"
|
|
50
|
+
},
|
|
51
|
+
"homepage": "https://github.com/n24q02m/better-code-review-graph",
|
|
52
|
+
"mcpServers": {
|
|
53
|
+
"better-code-review-graph": {
|
|
54
|
+
"command": "uvx",
|
|
55
|
+
"args": [
|
|
56
|
+
"--python",
|
|
57
|
+
"3.13",
|
|
58
|
+
"better-code-review-graph"
|
|
59
|
+
],
|
|
60
|
+
"env": {
|
|
61
|
+
"MCP_TRANSPORT": "stdio",
|
|
62
|
+
"EMBEDDING_MODELS": "${user_config.EMBEDDING_MODELS}",
|
|
63
|
+
"SUMMARY_MODELS": "${user_config.SUMMARY_MODELS}",
|
|
64
|
+
"JINA_AI_API_KEY": "${user_config.JINA_AI_API_KEY}",
|
|
65
|
+
"GEMINI_API_KEY": "${user_config.GEMINI_API_KEY}",
|
|
66
|
+
"OPENAI_API_KEY": "${user_config.OPENAI_API_KEY}",
|
|
67
|
+
"COHERE_API_KEY": "${user_config.COHERE_API_KEY}"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
{better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.github/workflows/cd.yml
RENAMED
|
@@ -47,7 +47,7 @@ jobs:
|
|
|
47
47
|
app-id: ${{ vars.CI_APP_ID }}
|
|
48
48
|
private-key: ${{ secrets.CI_APP_KEY }}
|
|
49
49
|
|
|
50
|
-
- uses: actions/checkout@
|
|
50
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
51
51
|
with:
|
|
52
52
|
token: ${{ steps.app-token.outputs.token }}
|
|
53
53
|
fetch-depth: 0
|
|
@@ -77,10 +77,10 @@ jobs:
|
|
|
77
77
|
with:
|
|
78
78
|
egress-policy: audit
|
|
79
79
|
|
|
80
|
-
- uses: actions/checkout@
|
|
80
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
81
81
|
with:
|
|
82
82
|
ref: ${{ needs.release.outputs.tag }}
|
|
83
|
-
- uses: astral-sh/setup-uv@
|
|
83
|
+
- uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
84
84
|
- run: uv build
|
|
85
85
|
- name: Publish to PyPI
|
|
86
86
|
run: uv publish
|
|
@@ -107,7 +107,7 @@ jobs:
|
|
|
107
107
|
with:
|
|
108
108
|
egress-policy: audit
|
|
109
109
|
|
|
110
|
-
- uses: actions/checkout@
|
|
110
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
111
111
|
with:
|
|
112
112
|
ref: ${{ needs.release.outputs.tag }}
|
|
113
113
|
- uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4
|
|
@@ -187,7 +187,7 @@ jobs:
|
|
|
187
187
|
$(echo "$DIGESTS" | xargs -I{} echo "${IMAGE}@{}")
|
|
188
188
|
done
|
|
189
189
|
|
|
190
|
-
- uses: actions/checkout@
|
|
190
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
191
191
|
with:
|
|
192
192
|
sparse-checkout: README.md
|
|
193
193
|
- uses: peter-evans/dockerhub-description@1b9a80c056b620d92cedb9d9b5a223409c68ddfa # v5
|
|
@@ -210,7 +210,7 @@ jobs:
|
|
|
210
210
|
with:
|
|
211
211
|
egress-policy: audit
|
|
212
212
|
|
|
213
|
-
- uses: actions/checkout@
|
|
213
|
+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
214
214
|
with:
|
|
215
215
|
ref: ${{ needs.release.outputs.tag }}
|
|
216
216
|
|
{better_code_review_graph-3.17.2b2 → better_code_review_graph-3.18.0}/.github/workflows/ci.yml
RENAMED
|
@@ -36,13 +36,13 @@ jobs:
|
|
|
36
36
|
egress-policy: audit
|
|
37
37
|
|
|
38
38
|
- name: Checkout code
|
|
39
|
-
uses: actions/checkout@
|
|
39
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
40
40
|
|
|
41
41
|
- name: Install uv
|
|
42
|
-
uses: astral-sh/setup-uv@
|
|
42
|
+
uses: astral-sh/setup-uv@fac544c07dec837d0ccb6301d7b5580bf5edae39 # v8.2.0
|
|
43
43
|
|
|
44
44
|
- name: Setup Python 3.13
|
|
45
|
-
uses: actions/setup-python@
|
|
45
|
+
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
46
46
|
with:
|
|
47
47
|
python-version: "3.13"
|
|
48
48
|
|
|
@@ -85,7 +85,7 @@ jobs:
|
|
|
85
85
|
egress-policy: audit
|
|
86
86
|
|
|
87
87
|
- name: Checkout code
|
|
88
|
-
uses: actions/checkout@
|
|
88
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
89
89
|
|
|
90
90
|
- name: Initialize CodeQL
|
|
91
91
|
uses: github/codeql-action/init@dd903d2e4f5405488e5ef1422510ee31c8b32357 # v3
|
|
@@ -107,7 +107,7 @@ jobs:
|
|
|
107
107
|
egress-policy: audit
|
|
108
108
|
|
|
109
109
|
- name: Checkout code
|
|
110
|
-
uses: actions/checkout@
|
|
110
|
+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7
|
|
111
111
|
|
|
112
112
|
- name: Dependency Review
|
|
113
113
|
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0
|
|
@@ -197,7 +197,7 @@ jobs:
|
|
|
197
197
|
SMTP_CREDENTIAL: ${{ secrets.SMTP_CREDENTIAL }}
|
|
198
198
|
|
|
199
199
|
- name: Send email notification
|
|
200
|
-
uses: dawidd6/action-send-mail@
|
|
200
|
+
uses: dawidd6/action-send-mail@94de994a9f6fffee200243214e17002e2920bb59 # v18
|
|
201
201
|
with:
|
|
202
202
|
server_address: smtp.gmail.com
|
|
203
203
|
server_port: 587
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# better-code-review-graph
|
|
2
2
|
|
|
3
3
|
Fork of code-review-graph with fixed multi-word search, qualified call resolution,
|
|
4
|
-
dual-mode embedding (ONNX local + cloud
|
|
4
|
+
dual-mode embedding (ONNX local + cloud chain via `EMBEDDING_MODELS`), and output pagination.
|
|
5
5
|
See `AGENTS.md` va `README.md` de hieu architecture va configuration.
|
|
6
6
|
|
|
7
7
|
## Cau truc
|
|
@@ -9,10 +9,10 @@ See `AGENTS.md` va `README.md` de hieu architecture va configuration.
|
|
|
9
9
|
- `src/better_code_review_graph/` -- Package chinh (src layout)
|
|
10
10
|
- `server.py` -- FastMCP server, 7 tools: graph + query + review (3 main) + config + security + help + config__open_relay (mcp-core relay helper)
|
|
11
11
|
- `tools.py` -- MCP tool implementations (build, query, impact, review, search, embed, stats, docs, large functions)
|
|
12
|
-
- `parser.py` -- Tree-sitter parsing (
|
|
12
|
+
- `parser.py` -- Tree-sitter parsing (14 langs) + call target resolution
|
|
13
13
|
- `graph.py` -- SQLite GraphStore, search, impact radius, NetworkX cache
|
|
14
14
|
- `incremental.py` -- Git integration, file watching, incremental updates
|
|
15
|
-
- `embeddings.py` -- Dual-mode embedding: ONNX local (qwen3-embed) + cloud (
|
|
15
|
+
- `embeddings.py` -- Dual-mode embedding: ONNX local (qwen3-embed) + cloud chain (`EMBEDDING_MODELS`) via litellm passthrough (`mcp_core.llm`)
|
|
16
16
|
- `docs/` -- Help tool documentation (graph.md, query.md, review.md, config.md)
|
|
17
17
|
- `cli.py` -- CLI: starts MCP server (pure entry point)
|
|
18
18
|
- `__init__.py` -- Version export
|
|
@@ -57,21 +57,61 @@ Source files --> Tree-sitter parser --> SQLite graph (nodes + edges)
|
|
|
57
57
|
- **Parser** (parser.py): Tree-sitter extracts nodes (File, Class, Function, Type, Test) and edges (CALLS, IMPORTS_FROM, INHERITS, IMPLEMENTS, CONTAINS, TESTED_BY, DEPENDS_ON). Resolves same-file bare call targets to qualified names.
|
|
58
58
|
- **Graph** (graph.py): SQLite with WAL mode. Multi-word AND-logic search. GraphNode/GraphEdge dataclasses.
|
|
59
59
|
- **Incremental** (incremental.py): Git diff detection, file hash tracking, re-parses only changed files.
|
|
60
|
-
- **Embeddings** (embeddings.py): Dual-mode -- local ONNX (qwen3-embed, default, zero-config) or cloud
|
|
60
|
+
- **Embeddings** (embeddings.py): Dual-mode -- local ONNX (qwen3-embed, default, zero-config) or cloud via the `EMBEDDING_MODELS` chain (litellm passthrough, `mcp_core.llm`; order = fallback, empty = local). Fixed 768-dim storage.
|
|
61
61
|
- **Tools** (tools.py): Implementation layer for all graph operations. Output pagination via max_results.
|
|
62
|
-
- **Server** (server.py): 7 tools — graph (build/update/stats/embed/export/summarize), query (query/search/impact/large_functions), review, config, security, help, config__open_relay (mcp-core relay helper). Returns JSON strings.
|
|
62
|
+
- **Server** (server.py): 7 tools — graph (build/update/stats/embed/export/summarize), query (query/search/impact/large_functions/spot_check/renamed_in_diff/diff), review, config, security, help, config__open_relay (mcp-core relay helper). Returns JSON strings.
|
|
63
63
|
|
|
64
64
|
## Embedding backends
|
|
65
65
|
|
|
66
|
+
Embedding (cloud backend) + the LLM summarizer both dispatch through
|
|
67
|
+
`mcp_core.llm` (litellm passthrough, `n24q02m-mcp-core[llm]`). No native
|
|
68
|
+
provider SDKs are imported directly.
|
|
69
|
+
|
|
70
|
+
Per-task model chains, CSV `provider/model,provider/model`, order = litellm fallback. Provider is inferred from the model prefix.
|
|
71
|
+
|
|
72
|
+
- `EMBEDDING_MODELS` -- chain embedding. Empty = local ONNX (qwen3-embed).
|
|
66
73
|
- **Local (default)**: `qwen3-embed` ONNX -- zero-config, ~570MB download on first use, 768-dim MRL truncation
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
74
|
+
- API key follows the litellm convention `<PROVIDER>_API_KEY`. The 6 providers the server suggests:
|
|
75
|
+
|
|
76
|
+
| model prefix | key env var | get it at |
|
|
77
|
+
|---|---|---|
|
|
78
|
+
| `gemini/` | `GEMINI_API_KEY` | aistudio.google.com/apikey |
|
|
79
|
+
| `openai/` (or bare) | `OPENAI_API_KEY` | platform.openai.com |
|
|
80
|
+
| `jina_ai/` | `JINA_AI_API_KEY` | jina.ai/api-key |
|
|
81
|
+
| `cohere/` | `COHERE_API_KEY` | dashboard.cohere.com |
|
|
82
|
+
| `xai/` | `XAI_API_KEY` | console.x.ai |
|
|
83
|
+
| `anthropic/` | `ANTHROPIC_API_KEY` | console.anthropic.com |
|
|
84
|
+
|
|
85
|
+
For any other litellm provider (used via env passthrough), see https://docs.litellm.ai/docs/providers/<provider> for its `<PROVIDER>_API_KEY` name.
|
|
86
|
+
- Custom endpoint (SSRF-guarded): `EMBEDDING_API_BASE` -- custom OpenAI-compatible base URL for cloud embedding (optional)
|
|
87
|
+
- `DISABLE_LOCAL_EMBED` -- skip the local ONNX download; embedding is `unavailable` unless a cloud chain is configured (`resolve_backend` 3-way: cloud / local / unavailable)
|
|
88
|
+
- Fixed 768-dim storage keeps the table schema valid across providers. Switching embedding MODEL changes the vector space; embeddings are tagged per provider (`embeddings.provider` column) and `EmbeddingStore.search` restricts the cosine scan to the active provider, so a provider switch just re-embeds rather than mixing incomparable vectors.
|
|
89
|
+
- Deprecated (honored one release with a warning): singular `EMBEDDING_MODEL` + `EMBEDDING_BACKEND` (backend is now inferred from whether the chain is empty). The old "Jina > Gemini > OpenAI > Cohere" auto-detect router is gone.
|
|
90
|
+
|
|
91
|
+
### Manual config example
|
|
92
|
+
|
|
93
|
+
```json
|
|
94
|
+
{
|
|
95
|
+
"mcpServers": {
|
|
96
|
+
"crg": {
|
|
97
|
+
"command": "uvx", "args": ["better-code-review-graph"],
|
|
98
|
+
"env": {
|
|
99
|
+
"EMBEDDING_MODELS": "jina_ai/jina-embeddings-v5-text-small,gemini/gemini-embedding-001",
|
|
100
|
+
"SUMMARY_MODELS": "gemini/gemini-2.5-flash",
|
|
101
|
+
"JINA_AI_API_KEY": "jina_xxx",
|
|
102
|
+
"GEMINI_API_KEY": "AIza_xxx"
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## LLM summarizer (graph `summarize` action)
|
|
110
|
+
|
|
111
|
+
- `SUMMARY_MODELS` -- ordered summarizer model chain (CSV `provider/model,...`, order = litellm fallback). Empty = summaries disabled. Provider is inferred from the model prefix and must expose a chat-completion API (Jina/Cohere do not).
|
|
112
|
+
- Dispatches through `mcp_core.llm.completion`.
|
|
113
|
+
- `LLM_API_BASE` -- custom OpenAI-compatible base URL for the summarizer (SSRF-guarded, optional)
|
|
114
|
+
- Deprecated (honored one release with a warning): singular `SUMMARY_MODEL` -- folded into `SUMMARY_MODELS`.
|
|
75
115
|
|
|
76
116
|
## Pytest
|
|
77
117
|
|
|
@@ -95,7 +135,7 @@ Source files --> Tree-sitter parser --> SQLite graph (nodes + edges)
|
|
|
95
135
|
|
|
96
136
|
## Luu y quan trong
|
|
97
137
|
|
|
98
|
-
- Lazy imports cho heavy deps (tree-sitter, qwen3-embed,
|
|
138
|
+
- Lazy imports cho heavy deps (tree-sitter, qwen3-embed, litellm via `mcp_core.llm`, numpy) -- tranh startup cost
|
|
99
139
|
- MCP tools return error strings (`return "Error: ..."`) -- KHONG raise exceptions
|
|
100
140
|
- GraphStore.upsert_edge takes EdgeInfo (fields: source, target), GraphEdge uses source_qualified/target_qualified
|
|
101
141
|
- `_make_qualified()` builds qualified names as `file_path::name` or `file_path::parent.name`
|