cg-code-graph 0.22.0__tar.gz → 0.23.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.
- {cg_code_graph-0.22.0/cg_code_graph.egg-info → cg_code_graph-0.23.0}/PKG-INFO +1 -1
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/__init__.py +1 -1
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/cli.py +24 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/link.py +70 -3
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/mcp_graphs.py +53 -10
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/mcp_server.py +72 -9
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/query.py +231 -5
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0/cg_code_graph.egg-info}/PKG-INFO +1 -1
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph.egg-info/SOURCES.txt +3 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_dart_isolates.py +15 -0
- cg_code_graph-0.23.0/tests/test_dead_wrappers.py +39 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_django_flutter.py +4 -1
- cg_code_graph-0.23.0/tests/test_link_origin.py +39 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_mcp_multi_graph.py +67 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_php_http.py +2 -1
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_process_runs.py +18 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_realtime_native.py +18 -0
- cg_code_graph-0.23.0/tests/test_route_specs.py +71 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift.py +11 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/LICENSE +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/MANIFEST.in +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/README.md +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/__main__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/affected.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/agent_rules.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/agents.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/aitools.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/android_ipc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/apple_ipc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/apps.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/blindspots.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/bridges.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/brokers.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/concepts.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/config.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/cache.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/detect.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/env.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/extractors.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/fsutil.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/generated.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/model.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/paths.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/redact.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/store.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/core/syntax_errors.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/coverage.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/dart_isolates.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/doctor.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/explore.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/external.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/graphql.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/guard_facts.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/hooks.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/indexer.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/insecure_transport.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/jobs.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/lint_async.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/local_ipc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/local_sockets.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/mcp_install.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/parity.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/parity_structure.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/payload.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plans.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/platform_scan.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/platforms.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/astro/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/astro/content.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/astro/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/cfamily/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/cfamily/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/cfamily/syntax.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/dart/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/dart/bridges.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/dart/extractor/bin/extract.dart +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/dart/extractor/pubspec.lock +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/dart/extractor/pubspec.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/dart/http.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/dart/models.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/dart/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/dart/program.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/django/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/django/extras.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/django/models.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/django/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/django/schemas.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/django/shapes.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/django/urls.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/express/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/express/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/flutter/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/flutter/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/java/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/java/exact.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/java/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/jvm/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/jvm/interop.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/jvm/spring.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/kotlin/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/kotlin/exact.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/kotlin/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/kotlin/reparse.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/laravel/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/laravel/broadcast.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/laravel/massassign.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/laravel/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/laravel/tests.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/laravel/values.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/native/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/native/gates.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/native/runner.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/native/scipread.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/native/ts.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/nest/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/nest/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/nextjs/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/nextjs/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/nuxt/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/nuxt/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/php/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/php/external.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/php/extractor/composer.json +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/php/extractor/composer.lock +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/php/extractor/extract.php +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/php/gating.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/php/http_client.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/php/inline_guards.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/php/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/php/strings.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/aitools.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/external.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/fields.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/refs.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/roots.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/socketio.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/subproc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/tests.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/python/values.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/pyweb/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/pyweb/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/pyweb/values.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/rust/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/rust/cargo.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/rust/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/rust/syntax.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/scip/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/scip/importer.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/scip/scip.proto +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/scip/scip_pb2.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/stubs/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/stubs/plugins.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/swift/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/swift/baseurl.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/swift/exact.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/swift/indexstore.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/swift/packages.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/swift/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/ts/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/ts/baseurl.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/ts/extractor/extract.mjs +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/ts/extractor/fw.mjs +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/ts/extractor/package-lock.json +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/ts/extractor/package.json +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/ts/extractor/rr.mjs +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/ts/nav.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/ts/plugin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/ts/react_router.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/tsweb/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/tsweb/common.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/plugins/tsweb/data.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/c_cpp.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/common.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/dart.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/django-ninja.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/django.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/djangorestframework.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/express.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/java.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/kotlin.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/laravel.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/nest.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/nextjs.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/nuxt.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/php.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/python.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/react-router.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/rust.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/spring.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/swift.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/presets/typescript.yaml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/process_runs.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/protocols/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/protocols/builtin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/protocols/matchers.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/protocols/view.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/realtime.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/realtime_events.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/realtime_native.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/realtime_ws.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/roundtrip.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/routes.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/rpc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/sdk_systems.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/sockets.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/ssrf_input.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/starters.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/surface.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/tests_index.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/udp_apps.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/__init__.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/graph.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/server.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/static/app.css +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/static/app.js +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/static/index.html +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/static/layered.js +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/static/vendor/VERSIONS.txt +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/static/vendor/cose-base.js +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/static/vendor/cytoscape-fcose.js +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/static/vendor/cytoscape.min.js +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/static/vendor/layout-base.js +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/tools/package-lock.json +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/tools/package.json +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/viz/tools/shoot.mjs +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/watch.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/webhook_subs.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/webhooks.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph/xcode.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph.egg-info/dependency_links.txt +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph.egg-info/entry_points.txt +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph.egg-info/requires.txt +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/cg_code_graph.egg-info/top_level.txt +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/pyproject.toml +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/setup.cfg +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_affected.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_agents_install.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_agents_md.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_ai_tools.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_android_ipc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_apple_ipc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_astro.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_astro_content.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_astro_server.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_bridges.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_bridges_pigeon_monorepo.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_brokers.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_cache_clean.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_cache_invalidation.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_cache_migration.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_channels_tests.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_cli_output.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_completeness.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_config_extras.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_coverage.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_coverage_ts_hint.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_db_connections.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_dispatch_interfaces.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_docs_languages.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_docs_links.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_echo_ref.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_echo_wrapper.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_elysia.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_enum_constants.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_env.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_explore.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_external.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_fp_batch.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_gating.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_generated.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_graphql.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_hooks.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_impact_overrides.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_index_isolation.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_inherited_overrides.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_inline_guards.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_192.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_202.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_203.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_205.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_206.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_207.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_208.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_209.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_210.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_211.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_issue_211_used_at.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_java.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_java_exact.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_jobs.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_js_refs.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_js_runtime.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_kotlin.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_kotlin_binding.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_kotlin_exact.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_kotlin_fields.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_kotlin_mixed.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_kotlin_nav_consts.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_kotlin_props.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_laravel_determinism.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_laravel_resources.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_lint_async.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_listing_files.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_local_ipc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_local_sockets.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_mass_assignment.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_mcp.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_mcp_index.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_mcp_install.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_native_cfamily.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_native_concurrency.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_native_rust.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_nuxt_import_dirs.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_nuxt_rootsrc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_packaging.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_parity.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_parity_structure.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_php_props.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_plain_js.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_plans.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_platform_gaps.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_platform_type_variants.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_platforms.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_platforms_apple.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_presets_config.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_process_ipc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_protocols.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_app_tests_module.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_collection_chains.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_compat.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_entry_refs.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_fields.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_infer_cycles.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_roots.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_subprocess_tests.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_tests.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_web_hosts.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_web_routes.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_python_web_routes_more.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_react_router.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_readers_writers_specs.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_realtime.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_redact_salt.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_request_keys.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_roundtrip.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_route_tables.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_routes_search_explain.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_rpc.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_scip_health.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_sdk_external.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_sdk_external_infra.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_sdk_external_mail.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_snippet.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_sockets.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_spring.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_ssrf.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_starters_budget.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_surface.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_surface_transport.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_binding.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_exact.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_facts.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_fields.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_modules.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_more.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_nav_values.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_parse_errors.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_props.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_sdk.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_testing.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_swift_values.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_tests_scope.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_ts_fields.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_ts_fields_js_vue.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_ts_file_specs.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_ts_frameworks.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_ts_node_http.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_ts_nuxt.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_ts_src_tsconfig.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_unguarded.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_values.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_viz.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_vue_nav.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_watch.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_webhooks.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_webhooks_152.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_webhooks_152b.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_websockets.py +0 -0
- {cg_code_graph-0.22.0 → cg_code_graph-0.23.0}/tests/test_workspace_link.py +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""code-graph: deterministic code knowledge graph (beta)."""
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.23.0"
|
|
@@ -636,6 +636,8 @@ def main(argv=None):
|
|
|
636
636
|
print(json.dumps(res, indent=1, default=str) if a.json else render_protocols(res, max_items=a.max_items))
|
|
637
637
|
return
|
|
638
638
|
if a.cmd == "tests":
|
|
639
|
+
if _unknown_route(st, a.spec, a.json):
|
|
640
|
+
return
|
|
639
641
|
res = Q.tests_covering(st, a.spec, min_conf=a.min_confidence, near_depth=a.max_depth or None,
|
|
640
642
|
unit_only=a.unit_only, exclude_roots=a.exclude_root, through_roots=a.through_roots)
|
|
641
643
|
res["completeness"] = _completeness(st, res.get("targets"))
|
|
@@ -674,12 +676,17 @@ def main(argv=None):
|
|
|
674
676
|
print(json.dumps(res, indent=1, default=str) if a.json else Q.render_search(res))
|
|
675
677
|
return
|
|
676
678
|
if a.cmd == "reaches":
|
|
679
|
+
for spec in a.specs:
|
|
680
|
+
if _unknown_route(st, spec, a.json):
|
|
681
|
+
return
|
|
677
682
|
res = Q.reaches(st, a.specs, min_conf=a.min_confidence, max_depth=a.max_depth, gate=None if a.gate == "none" else a.gate,
|
|
678
683
|
platform=a.platform, connection=a.connection)
|
|
679
684
|
res["completeness"] = _completeness(st, [x for t in res["targets"].values() for x in t] + [i["id"] for i in res["items"]])
|
|
680
685
|
print(json.dumps(res, indent=1, default=str) if a.json else Q.render_reaches(res, show_paths=not a.no_paths))
|
|
681
686
|
_note(res["completeness"], a.json)
|
|
682
687
|
elif a.cmd == "impact":
|
|
688
|
+
if _unknown_route(st, a.spec, a.json):
|
|
689
|
+
return
|
|
683
690
|
res = Q.impact(st, a.spec, min_conf=a.min_confidence, platform=a.platform)
|
|
684
691
|
if a.json:
|
|
685
692
|
res["completeness"] = _completeness(st, list(res["targets"]) + [c["id"] for c in res["callers"]])
|
|
@@ -755,6 +762,8 @@ def main(argv=None):
|
|
|
755
762
|
res = Q.siblings(st, a.spec)
|
|
756
763
|
print(json.dumps(res, indent=1, default=str) if a.json else Q.render_siblings(st, a.spec, res))
|
|
757
764
|
elif a.cmd == "node":
|
|
765
|
+
if _unknown_route(st, a.spec, a.json):
|
|
766
|
+
return
|
|
758
767
|
ids = list(dict.fromkeys(Q.resolve_targets(st, a.spec)))[:20]
|
|
759
768
|
docs = [node_doc(st, nid) for nid in ids]
|
|
760
769
|
if a.json:
|
|
@@ -774,10 +783,14 @@ def main(argv=None):
|
|
|
774
783
|
if not p:
|
|
775
784
|
raise SystemExit(1) # scripts can tell "no path" apart from a path
|
|
776
785
|
elif a.cmd == "downstream":
|
|
786
|
+
if _unknown_route(st, a.spec, a.json):
|
|
787
|
+
return
|
|
777
788
|
res = Q.downstream(st, a.spec, min_conf=a.min_confidence, max_depth=a.max_depth, gate=None if a.gate == "none" else a.gate,
|
|
778
789
|
platform=a.platform)
|
|
779
790
|
print(json.dumps(res, indent=1, default=str) if a.json else Q.render_downstream(res, show_paths=not a.no_paths))
|
|
780
791
|
elif a.cmd == "api-calls":
|
|
792
|
+
if _unknown_route(st, a.spec, a.json):
|
|
793
|
+
return
|
|
781
794
|
rows = Q.api_calls(st, a.spec)
|
|
782
795
|
print(json.dumps(rows, indent=1, default=str) if a.json else Q.render_api_calls(rows))
|
|
783
796
|
if not a.json:
|
|
@@ -789,6 +802,17 @@ def main(argv=None):
|
|
|
789
802
|
doc = stats_doc(st)
|
|
790
803
|
print(json.dumps(doc, indent=1, default=str) if a.json else render_stats(st, doc))
|
|
791
804
|
|
|
805
|
+
def _unknown_route(st, spec: str, as_json: bool) -> bool:
|
|
806
|
+
miss = Q.route_failure(st, spec)
|
|
807
|
+
if not miss:
|
|
808
|
+
return False
|
|
809
|
+
if as_json:
|
|
810
|
+
print(json.dumps({"error": miss["error"], "spec": miss["spec"], "suggestions": miss["suggestions"]}))
|
|
811
|
+
else:
|
|
812
|
+
print(miss["text"])
|
|
813
|
+
raise SystemExit(1)
|
|
814
|
+
|
|
815
|
+
|
|
792
816
|
def node_doc(st, nid: str) -> dict:
|
|
793
817
|
"""One node with its attrs parsed and its outgoing / incoming edges (`cg node --json`, #75)."""
|
|
794
818
|
n = dict(st.node(nid))
|
|
@@ -101,20 +101,67 @@ def _method_ok(cm: str, rm: str) -> bool:
|
|
|
101
101
|
return cm in rms or "ANY" in rms or (cm == "HEAD" and "GET" in rms)
|
|
102
102
|
|
|
103
103
|
|
|
104
|
+
_BASE_SEG = re.compile(r"^(api|v\d+)$", re.I)
|
|
105
|
+
|
|
106
|
+
|
|
104
107
|
def suffix_candidates(path: str, routes: list[dict]):
|
|
105
|
-
"""
|
|
108
|
+
"""Align the client path with the end of a route only when the dropped prefix is a base path (`api`, `v1`)."""
|
|
106
109
|
cs = _segs(path)
|
|
107
110
|
out = []
|
|
108
111
|
for r in routes:
|
|
109
112
|
us = _segs(r["uri"])
|
|
110
113
|
if len(us) <= len(cs):
|
|
111
114
|
continue
|
|
115
|
+
dropped = us[:len(us) - len(cs)]
|
|
116
|
+
if any(not _BASE_SEG.match(seg) for seg in dropped):
|
|
117
|
+
continue
|
|
112
118
|
ok, info = match_path("/" + "/".join(cs), "/" + "/".join(us[len(us) - len(cs):]))
|
|
113
119
|
if ok and info["lit"] > 0:
|
|
114
120
|
out.append((r, "suffix", info))
|
|
115
121
|
return out
|
|
116
122
|
|
|
117
123
|
|
|
124
|
+
def known_origin_text(attrs: dict) -> str | None:
|
|
125
|
+
"""Env placeholder or literal base URL, when the client recorded one."""
|
|
126
|
+
kind = attrs.get("origin_kind")
|
|
127
|
+
origin = attrs.get("origin") or ""
|
|
128
|
+
base = attrs.get("base") or {}
|
|
129
|
+
if not isinstance(base, dict):
|
|
130
|
+
base = {}
|
|
131
|
+
parts = [origin, base.get("placeholder") or "", base.get("value") or ""]
|
|
132
|
+
text = " ".join(p for p in parts if isinstance(p, str) and p)
|
|
133
|
+
if kind == "env" or (isinstance(origin, str) and origin.startswith("{env.")):
|
|
134
|
+
return text or None
|
|
135
|
+
if kind == "other" or "://" in text:
|
|
136
|
+
return text or None
|
|
137
|
+
return None
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
_GENERIC_ORIGIN = {"env", "base", "url", "api", "app", "http", "https", "host", "origin", "endpoint", "service", "internal"}
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def repos_for_origin(text: str, servers: list[str]) -> list[str] | None:
|
|
144
|
+
"""Server names named by the origin.
|
|
145
|
+
|
|
146
|
+
``None`` when the origin is a generic API base (``API_BASE_URL``) and does not name a repo:
|
|
147
|
+
matching stays as it was. ``[]`` when it names a service that is not one of ``servers``.
|
|
148
|
+
"""
|
|
149
|
+
low = text.lower()
|
|
150
|
+
hits = []
|
|
151
|
+
for name in servers:
|
|
152
|
+
token = name.lower()
|
|
153
|
+
if len(token) < 3:
|
|
154
|
+
continue
|
|
155
|
+
if re.search(rf"(^|[^a-z0-9]){re.escape(token)}([^a-z0-9]|$)", low):
|
|
156
|
+
hits.append(name)
|
|
157
|
+
if hits:
|
|
158
|
+
return hits
|
|
159
|
+
tokens = [t for t in re.findall(r"[a-z][a-z0-9]+", low) if t not in _GENERIC_ORIGIN]
|
|
160
|
+
if not tokens:
|
|
161
|
+
return None
|
|
162
|
+
return []
|
|
163
|
+
|
|
164
|
+
|
|
118
165
|
def match_endpoint(method: str, path: str, routes: list[dict], origin_kind: str = "api", origin: str | None = None,
|
|
119
166
|
base_prefix: str | None = None) -> dict:
|
|
120
167
|
"""base_prefix: path part of a configured base URL already folded into `path` (http node attrs.base); when the
|
|
@@ -388,7 +435,15 @@ def link_many(repos: list[tuple[str, str, str]], out_db: str, *, allow: dict | N
|
|
|
388
435
|
targets = [s for s in server_names if (s != client or folded_self) and (client not in allow or s in allow[client])]
|
|
389
436
|
pool = [rt for s in targets for rt in by_server[s]]
|
|
390
437
|
bp = base_path((a.get("base") or {}).get("value") or "") if a.get("base") else None
|
|
438
|
+
origin_text = known_origin_text(a)
|
|
439
|
+
owners = repos_for_origin(origin_text, targets) if origin_text else None
|
|
440
|
+
if owners is not None and len(owners) == 1:
|
|
441
|
+
pool = [rt for rt in pool if rt["server"] == owners[0]]
|
|
391
442
|
res = match_endpoint(a["method"], a["path"], pool, a.get("origin_kind", "api"), a.get("origin"), base_prefix=bp or None)
|
|
443
|
+
if origin_text and owners == [] and not res.get("matched") and a.get("origin_kind") != "other":
|
|
444
|
+
reason = res.get("reason") or ""
|
|
445
|
+
if reason.startswith(("no backend route", "not a backend URL")) or "suffix" in reason:
|
|
446
|
+
res["reason"] = "external (other origin)"
|
|
392
447
|
res.update({"endpoint": ep_id, "method": a["method"], "calls": calls_by_ep.get(ep_id, []),
|
|
393
448
|
"_client": client, "_servers": targets})
|
|
394
449
|
results.append(res)
|
|
@@ -448,13 +503,20 @@ def link_many(repos: list[tuple[str, str, str]], out_db: str, *, allow: dict | N
|
|
|
448
503
|
for sc in scen[:1]:
|
|
449
504
|
db.executemany("INSERT INTO node_entry_live VALUES (?,?,?,?,?)", [(sc, *r) for r in tag_entries_rows(nodes, edges, prop, skip_gate=sc)])
|
|
450
505
|
db.commit()
|
|
506
|
+
# call sites whose wrapper no entry point reaches are matched, but not live
|
|
507
|
+
live_ids = {r[0] for r in db.execute("SELECT DISTINCT node_id FROM node_entry WHERE entry_kind != 'test'")}
|
|
508
|
+
for r in results:
|
|
509
|
+
for c in r["calls"]:
|
|
510
|
+
c["live"] = c.get("src") in live_ids
|
|
511
|
+
if r["matched"] and r["calls"] and not any(c.get("live") for c in r["calls"]):
|
|
512
|
+
r["no_live_caller"] = True
|
|
451
513
|
# ---- stats: per call site and per distinct endpoint
|
|
452
514
|
n_ep = len(results)
|
|
453
515
|
m_ep = sum(1 for r in results if r["matched"])
|
|
454
516
|
site_match = {}
|
|
455
517
|
for r in results:
|
|
456
518
|
for c in r["calls"]:
|
|
457
|
-
site_match[c["at"]] = site_match.get(c["at"], False) or bool(r["matched"])
|
|
519
|
+
site_match[c["at"]] = site_match.get(c["at"], False) or (bool(r["matched"]) and c.get("live", True))
|
|
458
520
|
sites = list(site_match)
|
|
459
521
|
m_sites = sum(1 for v in site_match.values() if v)
|
|
460
522
|
conf_ct = defaultdict(int)
|
|
@@ -476,7 +538,7 @@ def link_many(repos: list[tuple[str, str, str]], out_db: str, *, allow: dict | N
|
|
|
476
538
|
for r in eps:
|
|
477
539
|
hit = any(rmap[m["route"]]["server"] == server for m in r["matched"])
|
|
478
540
|
for c in r["calls"]:
|
|
479
|
-
sm[c["at"]] = sm.get(c["at"], False) or hit
|
|
541
|
+
sm[c["at"]] = sm.get(c["at"], False) or (hit and c.get("live", True))
|
|
480
542
|
pair_stats.append({"client": client, "server": server, "endpoints": len(eps),
|
|
481
543
|
"endpoints_matched": sum(1 for r in eps if any(rmap[m["route"]]["server"] == server for m in r["matched"])),
|
|
482
544
|
"call_sites": len(sm), "call_sites_matched": sum(1 for v in sm.values() if v)})
|
|
@@ -667,6 +729,11 @@ def write_match_report(res: dict, out_prefix: str) -> None:
|
|
|
667
729
|
at = ", ".join(sorted({c["at"] for c in r["calls"]})[:3])
|
|
668
730
|
extra = f" closest={r['closest']}" if r.get("closest") else (f" near={r['near']}" if r.get("near") else "")
|
|
669
731
|
L.append(f"- `{r['endpoint']}` - {r['reason']}{extra} - at {at}")
|
|
732
|
+
dead = [r for r in res["results"] if r.get("no_live_caller")]
|
|
733
|
+
if dead:
|
|
734
|
+
L += ["", "## Matched, no live caller", ""]
|
|
735
|
+
for r in dead:
|
|
736
|
+
L.append(f"- `{r['endpoint']}` — matched, no live caller")
|
|
670
737
|
L += ["", "## Ambiguous / heuristic matches", ""]
|
|
671
738
|
for r in res["results"]:
|
|
672
739
|
if r["matched"] and (len(r["matched"]) > 1 or any(m["confidence"] == "heuristic" for m in r["matched"])):
|
|
@@ -68,7 +68,7 @@ def git_head(root: Path) -> str | None:
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
def _valid_name(name: str) -> bool:
|
|
71
|
-
return bool(name) and all(c.isalnum() or c in "_
|
|
71
|
+
return bool(name) and all(c.isalnum() or c in "_.-+" for c in name) # `app+api`: a combined graph
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
def parse_db_arg(text: str) -> tuple[str, Path]:
|
|
@@ -318,9 +318,58 @@ def _superset(hits: list[GraphEntry]) -> GraphEntry | None:
|
|
|
318
318
|
return strict[0] if len(strict) == 1 else None
|
|
319
319
|
|
|
320
320
|
|
|
321
|
+
def _deepest_repo(hits: list[GraphEntry], texts: list[str]) -> Path | None:
|
|
322
|
+
"""The repo containing the path: the deepest matching root, when that root is unique."""
|
|
323
|
+
containing: list[Path] = []
|
|
324
|
+
for entry in hits:
|
|
325
|
+
for root in entry.roots:
|
|
326
|
+
if not any(_under(root, text) for text in texts):
|
|
327
|
+
continue
|
|
328
|
+
try:
|
|
329
|
+
containing.append(root.expanduser().resolve())
|
|
330
|
+
except OSError:
|
|
331
|
+
containing.append(root)
|
|
332
|
+
if not containing:
|
|
333
|
+
return None
|
|
334
|
+
deepest: list[Path] = []
|
|
335
|
+
for root in containing:
|
|
336
|
+
if any(other != root and _under(root, str(other)) for other in containing):
|
|
337
|
+
continue
|
|
338
|
+
deepest.append(root)
|
|
339
|
+
unique = set(deepest)
|
|
340
|
+
if len(unique) != 1:
|
|
341
|
+
return None
|
|
342
|
+
return next(iter(unique))
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
def _own_graph(hits: list[GraphEntry], texts: list[str]) -> GraphEntry | None:
|
|
346
|
+
"""The one match whose roots are exactly the repo that contains the path."""
|
|
347
|
+
repo = _deepest_repo(hits, texts)
|
|
348
|
+
if repo is None:
|
|
349
|
+
return None
|
|
350
|
+
own = [entry for entry in hits if _root_set(entry) == {repo}]
|
|
351
|
+
return own[0] if len(own) == 1 else None
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def _pick(registry: Registry, hits: list[GraphEntry], texts: list[str]) -> GraphEntry:
|
|
355
|
+
"""Superset, then the graph that is only that repo, then the configured default."""
|
|
356
|
+
chosen = _superset(hits)
|
|
357
|
+
if chosen is not None:
|
|
358
|
+
return chosen
|
|
359
|
+
chosen = _own_graph(hits, texts)
|
|
360
|
+
if chosen is not None:
|
|
361
|
+
return chosen
|
|
362
|
+
if registry.default:
|
|
363
|
+
by = registry.by_name()
|
|
364
|
+
default = by.get(registry.default)
|
|
365
|
+
if default is not None and default in hits:
|
|
366
|
+
return default
|
|
367
|
+
raise _choice_error(hits)
|
|
368
|
+
|
|
369
|
+
|
|
321
370
|
def resolve(registry: Registry, *, graph: str | None, paths: list[str],
|
|
322
371
|
cwd: Path | None = None, mcp_roots: list[str] | None = None) -> GraphEntry:
|
|
323
|
-
"""Pick a graph. Several matches
|
|
372
|
+
"""Pick a graph. Several matches use a superset, then a single-repo graph, then the default."""
|
|
324
373
|
by = registry.by_name()
|
|
325
374
|
if graph:
|
|
326
375
|
if graph not in by:
|
|
@@ -330,10 +379,7 @@ def resolve(registry: Registry, *, graph: str | None, paths: list[str],
|
|
|
330
379
|
if len(path_hits) == 1:
|
|
331
380
|
return path_hits[0]
|
|
332
381
|
if len(path_hits) > 1:
|
|
333
|
-
|
|
334
|
-
if chosen is not None:
|
|
335
|
-
return chosen
|
|
336
|
-
raise _choice_error(path_hits)
|
|
382
|
+
return _pick(registry, path_hits, paths)
|
|
337
383
|
places: list[str] = []
|
|
338
384
|
if mcp_roots:
|
|
339
385
|
places.extend(mcp_roots)
|
|
@@ -342,10 +388,7 @@ def resolve(registry: Registry, *, graph: str | None, paths: list[str],
|
|
|
342
388
|
if len(loc_hits) == 1:
|
|
343
389
|
return loc_hits[0]
|
|
344
390
|
if len(loc_hits) > 1:
|
|
345
|
-
|
|
346
|
-
if chosen is not None:
|
|
347
|
-
return chosen
|
|
348
|
-
raise _choice_error(loc_hits)
|
|
391
|
+
return _pick(registry, loc_hits, places)
|
|
349
392
|
if registry.default and registry.default in by:
|
|
350
393
|
return by[registry.default]
|
|
351
394
|
if len(registry.entries) == 1:
|
|
@@ -302,6 +302,11 @@ def _run_call(fn, args, kwargs) -> tuple[str, dict]:
|
|
|
302
302
|
return str(ex), {"complete": False, "recorded": False, "languages": {}}
|
|
303
303
|
_CALL.set({"graph_entry": entry, "graph_name": entry.name, "db": str(Path(entry.db).resolve())})
|
|
304
304
|
named = entry.name
|
|
305
|
+
if entry.tools and str(entry.tools).strip():
|
|
306
|
+
allowed = set(selected_tool_names(entry.tools, warn=False))
|
|
307
|
+
if fn.__name__ not in allowed:
|
|
308
|
+
return (f"tool {fn.__name__} is not allowed for graph {entry.name}",
|
|
309
|
+
{"complete": False, "recorded": False, "languages": {}})
|
|
305
310
|
token, ptoken, xtoken = _SCOPE.set(None), _PF.set(None), _EXTRA.set(None)
|
|
306
311
|
try:
|
|
307
312
|
try:
|
|
@@ -315,7 +320,7 @@ def _run_call(fn, args, kwargs) -> tuple[str, dict]:
|
|
|
315
320
|
_SCOPE.reset(token)
|
|
316
321
|
_PF.reset(ptoken)
|
|
317
322
|
_EXTRA.reset(xtoken)
|
|
318
|
-
if named and isinstance(txt, str) and not txt.startswith(("ambiguous graph:", "unknown graph ")):
|
|
323
|
+
if named and isinstance(txt, str) and not txt.startswith(("ambiguous graph:", "unknown graph ", "tool ")):
|
|
319
324
|
txt = f"graph {named}\n" + txt
|
|
320
325
|
comp = _completeness(scope)
|
|
321
326
|
if pf:
|
|
@@ -481,6 +486,9 @@ def reaches(targets: list[str], min_confidence: str = "heuristic", group_by: str
|
|
|
481
486
|
if pf and res["platform"].get("targets_not_built"):
|
|
482
487
|
pline.append(f"not built for {pf}: {', '.join(short(t) for t in res['platform']['targets_not_built'][:6])}")
|
|
483
488
|
if missing and len(missing) == len(res["targets"]):
|
|
489
|
+
route_lines = [Q.route_failure(st, s)["text"] for s in missing if Q.route_failure(st, s)]
|
|
490
|
+
if route_lines and len(route_lines) == len(missing):
|
|
491
|
+
return "\n".join(route_lines)
|
|
484
492
|
return "\n".join(pline + [f"targets: {tl}"]) + f"\nno node matches {', '.join(map(repr, missing))}; try search() with part of the name (spec forms are listed in the server instructions)"
|
|
485
493
|
if not items and connection:
|
|
486
494
|
return "\n".join(pline + [f"targets: {tl}", f"no dependents recorded for {', '.join(res['targets'])} on connection {connection!r} "
|
|
@@ -558,6 +566,9 @@ def impact(method: str, min_confidence: str = "heuristic", max_items: int = 60,
|
|
|
558
566
|
if Q.divergence_lists(st, pf, dropped):
|
|
559
567
|
msg += f"; platform_divergence(target='{pf}') lists references to it that would not build"
|
|
560
568
|
return "\n".join(pline + [msg])
|
|
569
|
+
miss = Q.route_failure(st, method)
|
|
570
|
+
if miss:
|
|
571
|
+
return miss["text"]
|
|
561
572
|
return f"no method matches {method!r}; try search() with part of the name"
|
|
562
573
|
_scope(list(r["targets"]) + [c["id"] for c in r["callers"]])
|
|
563
574
|
if pf and set(r["platform"]["targets_not_built"]) == set(r["targets"]):
|
|
@@ -996,7 +1007,11 @@ def tests_covering(target: str, min_confidence: str = "heuristic", paths: bool =
|
|
|
996
1007
|
classes, exclude_roots symbols; through_roots=true keeps them). UI / snapshot / screenshot tests (XCUITest,
|
|
997
1008
|
Compose UI / Espresso, Playwright / Cypress, *UITests / androidTest folders) are listed apart, or left out
|
|
998
1009
|
with unit_only=true. The summary line counts what was left out and why."""
|
|
999
|
-
|
|
1010
|
+
st = _st()
|
|
1011
|
+
miss = Q.route_failure(st, target)
|
|
1012
|
+
if miss:
|
|
1013
|
+
return miss["text"]
|
|
1014
|
+
res = Q.tests_covering(st, target, min_conf=min_confidence, near_depth=max_depth or None, unit_only=unit_only,
|
|
1000
1015
|
exclude_roots=exclude_roots, through_roots=through_roots)
|
|
1001
1016
|
_scope(res.get("targets") or [])
|
|
1002
1017
|
return Q.render_tests_covering(res, show_paths=paths)
|
|
@@ -1239,6 +1254,9 @@ def downstream(target: str, max_per_kind: int = 25, paths: bool = True, min_conf
|
|
|
1239
1254
|
pf, pline = _platform(st, platform)
|
|
1240
1255
|
r = Q.downstream(st, target, min_conf=min_confidence, platform=pf)
|
|
1241
1256
|
if not r["targets"]:
|
|
1257
|
+
miss = Q.route_failure(st, target)
|
|
1258
|
+
if miss:
|
|
1259
|
+
return miss["text"]
|
|
1242
1260
|
return f"no node matches {target!r}; try search()"
|
|
1243
1261
|
out = pline + [f"targets: {', '.join(short(t) for t in r['targets'][:4])} | reached {r['reached']} nodes | gate={r.get('gate')}"]
|
|
1244
1262
|
if not r["sinks"]:
|
|
@@ -1328,8 +1346,14 @@ def api_calls(filter: str = "all", max_items: int = 60) -> str:
|
|
|
1328
1346
|
"""Frontend HTTP calls (method + path template) with call sites, request keys and the matched backend
|
|
1329
1347
|
route + controller (combined graph). filter: all | unmatched | any substring (endpoint, route, caller, file) |
|
|
1330
1348
|
a `*` glob (`GET /v1/*/orders*`, `*/staff/*`, `*useOrders*`) on the endpoint, its path, route, controller,
|
|
1331
|
-
caller or call-site file.
|
|
1349
|
+
caller or call-site file. `route:VERB /path` is an exact route match (verb case-insensitive; `:id`, `{id}` and
|
|
1350
|
+
`{order}` match one param segment). `route:POST /payments/*` or `route:* /payments` widens it. An unknown
|
|
1351
|
+
route returns `no such route` and the nearest routes. A call site with no entry point is marked
|
|
1352
|
+
`(no live caller)` and `filter='dead'` lists matched endpoints with no live call site."""
|
|
1332
1353
|
st = _st()
|
|
1354
|
+
miss = Q.route_failure(st, filter)
|
|
1355
|
+
if miss:
|
|
1356
|
+
return miss["text"]
|
|
1333
1357
|
rows = Q.api_calls(st, filter)
|
|
1334
1358
|
gaps = defaultdict(list)
|
|
1335
1359
|
for g in Q.forwarding_gaps(st):
|
|
@@ -1618,12 +1642,12 @@ def _tool_names() -> list[str]:
|
|
|
1618
1642
|
return [t.name for t in server._tool_manager.list_tools()]
|
|
1619
1643
|
|
|
1620
1644
|
|
|
1621
|
-
def
|
|
1622
|
-
"""
|
|
1645
|
+
def selected_tool_names(spec: str, *, warn: bool = True) -> list[str]:
|
|
1646
|
+
"""Names selected by a tool spec, in server order. Does not change the listed set.
|
|
1623
1647
|
|
|
1624
1648
|
Items are comma- or space-separated. `all` is every tool, `core` is the reading set,
|
|
1625
1649
|
a name or fnmatch glob adds tools, and a leading `-` removes them (`all,-plan_*`).
|
|
1626
|
-
Unknown names are warned once on stderr and ignored.
|
|
1650
|
+
Unknown names are warned once on stderr and ignored.
|
|
1627
1651
|
"""
|
|
1628
1652
|
import fnmatch
|
|
1629
1653
|
names = _tool_names()
|
|
@@ -1652,18 +1676,52 @@ def apply_tool_allowlist(spec: str) -> list[str]:
|
|
|
1652
1676
|
selected -= matched
|
|
1653
1677
|
else:
|
|
1654
1678
|
selected |= matched
|
|
1655
|
-
if unknown:
|
|
1679
|
+
if warn and unknown:
|
|
1656
1680
|
print("cg-mcp: CG_MCP_TOOLS: unknown name(s): " + ", ".join(unknown), file=sys.stderr)
|
|
1657
|
-
|
|
1681
|
+
return [n for n in names if n in selected]
|
|
1682
|
+
|
|
1683
|
+
|
|
1684
|
+
def registry_tool_spec(registry) -> str | None:
|
|
1685
|
+
"""Union of per-graph allowlists. ``None`` means at least one graph lists every tool."""
|
|
1686
|
+
specs = [e.tools for e in registry.entries if e.tools and str(e.tools).strip()]
|
|
1687
|
+
if len(specs) != len(registry.entries):
|
|
1688
|
+
return None
|
|
1689
|
+
names: list[str] = []
|
|
1690
|
+
seen: set[str] = set()
|
|
1691
|
+
for spec in specs:
|
|
1692
|
+
for name in selected_tool_names(spec, warn=False):
|
|
1693
|
+
if name not in seen:
|
|
1694
|
+
seen.add(name)
|
|
1695
|
+
names.append(name)
|
|
1696
|
+
return ",".join(names) if names else None
|
|
1697
|
+
|
|
1698
|
+
|
|
1699
|
+
def apply_tool_allowlist(spec: str) -> list[str]:
|
|
1700
|
+
"""Keep only the tools selected by spec and return their names.
|
|
1701
|
+
|
|
1702
|
+
An empty selection exits 2.
|
|
1703
|
+
"""
|
|
1704
|
+
kept = selected_tool_names(spec)
|
|
1658
1705
|
if not kept:
|
|
1659
1706
|
print("cg-mcp: CG_MCP_TOOLS selects no tools", file=sys.stderr)
|
|
1660
1707
|
raise SystemExit(2)
|
|
1661
|
-
|
|
1708
|
+
selected = set(kept)
|
|
1709
|
+
for name in _tool_names():
|
|
1662
1710
|
if name not in selected:
|
|
1663
1711
|
server.remove_tool(name)
|
|
1664
1712
|
return kept
|
|
1665
1713
|
|
|
1666
1714
|
|
|
1715
|
+
def apply_registry_tools(registry, server_tools: str | None = None) -> list[str] | None:
|
|
1716
|
+
"""List one fixed set: ``server_tools`` when given, otherwise the union of per-graph allowlists."""
|
|
1717
|
+
if server_tools:
|
|
1718
|
+
return apply_tool_allowlist(server_tools)
|
|
1719
|
+
spec = registry_tool_spec(registry)
|
|
1720
|
+
if spec is None:
|
|
1721
|
+
return None
|
|
1722
|
+
return apply_tool_allowlist(spec)
|
|
1723
|
+
|
|
1724
|
+
|
|
1667
1725
|
def expose_graph_argument() -> None:
|
|
1668
1726
|
"""Add optional `graph` to every tool schema. Single-`--db` mode leaves the schemas unchanged."""
|
|
1669
1727
|
if STATE.get("graph_arg"):
|
|
@@ -1700,6 +1758,8 @@ def configure(*, dbs: list[str] | None = None, db_dir: str | None = None, graphs
|
|
|
1700
1758
|
STATE["registry"] = reg
|
|
1701
1759
|
STATE["db"] = str(Path(reg.entries[0].db).resolve())
|
|
1702
1760
|
expose_graph_argument()
|
|
1761
|
+
if not STATE.get("server_tools"):
|
|
1762
|
+
apply_registry_tools(reg)
|
|
1703
1763
|
|
|
1704
1764
|
|
|
1705
1765
|
def _install_roots_hook() -> None:
|
|
@@ -1771,8 +1831,11 @@ def main(argv=None):
|
|
|
1771
1831
|
STATE["registry"] = reg
|
|
1772
1832
|
STATE["db"] = str(Path(reg.entries[0].db).resolve())
|
|
1773
1833
|
expose_graph_argument()
|
|
1834
|
+
STATE["server_tools"] = a.tools or None
|
|
1774
1835
|
if a.tools:
|
|
1775
1836
|
apply_tool_allowlist(a.tools)
|
|
1837
|
+
elif STATE.get("multi"):
|
|
1838
|
+
apply_registry_tools(STATE["registry"])
|
|
1776
1839
|
server.run("stdio")
|
|
1777
1840
|
|
|
1778
1841
|
|