cg-code-graph 0.21.1__tar.gz → 0.22.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.21.1/cg_code_graph.egg-info → cg_code_graph-0.22.0}/PKG-INFO +4 -2
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/README.md +3 -1
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/__init__.py +1 -1
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/cli.py +67 -24
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/coverage.py +47 -10
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/external.py +37 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/indexer.py +17 -1
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/link.py +14 -1
- cg_code_graph-0.22.0/cg_code_graph/mcp_graphs.py +438 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/mcp_install.py +234 -14
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/mcp_server.py +331 -56
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/platforms.py +32 -3
- cg_code_graph-0.22.0/cg_code_graph/plugins/laravel/massassign.py +286 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/laravel/plugin.py +142 -20
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/laravel/values.py +2 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/swift/plugin.py +55 -14
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/query.py +407 -39
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/routes.py +5 -4
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0/cg_code_graph.egg-info}/PKG-INFO +4 -2
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph.egg-info/SOURCES.txt +18 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph.egg-info/entry_points.txt +1 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/pyproject.toml +1 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_affected.py +3 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_bridges.py +3 -1
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_coverage.py +4 -4
- cg_code_graph-0.22.0/tests/test_db_connections.py +280 -0
- cg_code_graph-0.22.0/tests/test_issue_192.py +60 -0
- cg_code_graph-0.22.0/tests/test_issue_202.py +79 -0
- cg_code_graph-0.22.0/tests/test_issue_203.py +52 -0
- cg_code_graph-0.22.0/tests/test_issue_205.py +36 -0
- cg_code_graph-0.22.0/tests/test_issue_206.py +32 -0
- cg_code_graph-0.22.0/tests/test_issue_207.py +58 -0
- cg_code_graph-0.22.0/tests/test_issue_208.py +45 -0
- cg_code_graph-0.22.0/tests/test_issue_209.py +42 -0
- cg_code_graph-0.22.0/tests/test_issue_210.py +51 -0
- cg_code_graph-0.22.0/tests/test_issue_211.py +45 -0
- cg_code_graph-0.22.0/tests/test_issue_211_used_at.py +71 -0
- cg_code_graph-0.22.0/tests/test_listing_files.py +45 -0
- cg_code_graph-0.22.0/tests/test_mass_assignment.py +164 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_mcp_install.py +11 -8
- cg_code_graph-0.22.0/tests/test_mcp_multi_graph.py +282 -0
- cg_code_graph-0.22.0/tests/test_readers_writers_specs.py +211 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_routes_search_explain.py +3 -2
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/LICENSE +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/MANIFEST.in +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/__main__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/affected.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/agent_rules.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/agents.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/aitools.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/android_ipc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/apple_ipc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/apps.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/blindspots.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/bridges.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/brokers.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/concepts.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/config.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/cache.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/detect.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/env.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/extractors.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/fsutil.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/generated.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/model.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/paths.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/redact.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/store.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/core/syntax_errors.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/dart_isolates.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/doctor.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/explore.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/graphql.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/guard_facts.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/hooks.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/insecure_transport.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/jobs.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/lint_async.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/local_ipc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/local_sockets.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/parity.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/parity_structure.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/payload.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plans.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/platform_scan.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/astro/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/astro/content.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/astro/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/cfamily/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/cfamily/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/cfamily/syntax.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/dart/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/dart/bridges.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/dart/extractor/bin/extract.dart +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/dart/extractor/pubspec.lock +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/dart/extractor/pubspec.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/dart/http.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/dart/models.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/dart/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/dart/program.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/django/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/django/extras.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/django/models.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/django/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/django/schemas.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/django/shapes.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/django/urls.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/express/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/express/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/flutter/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/flutter/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/java/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/java/exact.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/java/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/jvm/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/jvm/interop.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/jvm/spring.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/kotlin/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/kotlin/exact.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/kotlin/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/kotlin/reparse.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/laravel/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/laravel/broadcast.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/laravel/tests.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/native/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/native/gates.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/native/runner.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/native/scipread.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/native/ts.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/nest/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/nest/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/nextjs/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/nextjs/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/nuxt/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/nuxt/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/php/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/php/external.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/php/extractor/composer.json +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/php/extractor/composer.lock +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/php/extractor/extract.php +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/php/gating.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/php/http_client.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/php/inline_guards.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/php/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/php/strings.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/aitools.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/external.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/fields.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/refs.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/roots.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/socketio.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/subproc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/tests.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/python/values.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/pyweb/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/pyweb/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/pyweb/values.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/rust/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/rust/cargo.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/rust/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/rust/syntax.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/scip/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/scip/importer.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/scip/scip.proto +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/scip/scip_pb2.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/stubs/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/stubs/plugins.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/swift/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/swift/baseurl.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/swift/exact.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/swift/indexstore.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/swift/packages.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/ts/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/ts/baseurl.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/ts/extractor/extract.mjs +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/ts/extractor/fw.mjs +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/ts/extractor/package-lock.json +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/ts/extractor/package.json +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/ts/extractor/rr.mjs +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/ts/nav.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/ts/plugin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/ts/react_router.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/tsweb/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/tsweb/common.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/plugins/tsweb/data.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/c_cpp.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/common.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/dart.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/django-ninja.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/django.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/djangorestframework.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/express.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/java.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/kotlin.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/laravel.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/nest.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/nextjs.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/nuxt.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/php.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/python.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/react-router.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/rust.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/spring.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/swift.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/presets/typescript.yaml +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/process_runs.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/protocols/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/protocols/builtin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/protocols/matchers.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/protocols/view.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/realtime.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/realtime_events.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/realtime_native.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/realtime_ws.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/roundtrip.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/rpc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/sdk_systems.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/sockets.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/ssrf_input.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/starters.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/surface.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/tests_index.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/udp_apps.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/__init__.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/graph.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/server.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/static/app.css +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/static/app.js +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/static/index.html +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/static/layered.js +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/static/vendor/VERSIONS.txt +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/static/vendor/cose-base.js +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/static/vendor/cytoscape-fcose.js +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/static/vendor/cytoscape.min.js +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/static/vendor/layout-base.js +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/tools/package-lock.json +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/tools/package.json +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/viz/tools/shoot.mjs +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/watch.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/webhook_subs.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/webhooks.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph/xcode.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph.egg-info/dependency_links.txt +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph.egg-info/requires.txt +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/cg_code_graph.egg-info/top_level.txt +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/setup.cfg +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_agents_install.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_agents_md.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_ai_tools.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_android_ipc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_apple_ipc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_astro.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_astro_content.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_astro_server.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_bridges_pigeon_monorepo.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_brokers.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_cache_clean.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_cache_invalidation.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_cache_migration.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_channels_tests.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_cli_output.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_completeness.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_config_extras.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_coverage_ts_hint.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_dart_isolates.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_dispatch_interfaces.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_django_flutter.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_docs_languages.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_docs_links.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_echo_ref.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_echo_wrapper.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_elysia.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_enum_constants.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_env.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_explore.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_external.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_fp_batch.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_gating.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_generated.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_graphql.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_hooks.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_impact_overrides.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_index_isolation.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_inherited_overrides.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_inline_guards.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_java.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_java_exact.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_jobs.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_js_refs.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_js_runtime.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_kotlin.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_kotlin_binding.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_kotlin_exact.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_kotlin_fields.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_kotlin_mixed.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_kotlin_nav_consts.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_kotlin_props.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_laravel_determinism.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_laravel_resources.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_lint_async.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_local_ipc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_local_sockets.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_mcp.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_mcp_index.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_native_cfamily.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_native_concurrency.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_native_rust.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_nuxt_import_dirs.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_nuxt_rootsrc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_packaging.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_parity.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_parity_structure.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_php_http.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_php_props.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_plain_js.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_plans.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_platform_gaps.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_platform_type_variants.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_platforms.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_platforms_apple.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_presets_config.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_process_ipc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_process_runs.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_protocols.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_app_tests_module.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_collection_chains.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_compat.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_entry_refs.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_fields.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_infer_cycles.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_roots.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_subprocess_tests.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_tests.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_web_hosts.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_web_routes.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_python_web_routes_more.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_react_router.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_realtime.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_realtime_native.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_redact_salt.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_request_keys.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_roundtrip.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_route_tables.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_rpc.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_scip_health.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_sdk_external.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_sdk_external_infra.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_sdk_external_mail.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_snippet.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_sockets.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_spring.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_ssrf.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_starters_budget.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_surface.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_surface_transport.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_binding.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_exact.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_facts.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_fields.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_modules.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_more.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_nav_values.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_parse_errors.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_props.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_sdk.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_testing.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_swift_values.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_tests_scope.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_ts_fields.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_ts_fields_js_vue.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_ts_file_specs.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_ts_frameworks.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_ts_node_http.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_ts_nuxt.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_ts_src_tsconfig.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_unguarded.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_values.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_viz.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_vue_nav.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_watch.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_webhooks.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_webhooks_152.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_webhooks_152b.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_websockets.py +0 -0
- {cg_code_graph-0.21.1 → cg_code_graph-0.22.0}/tests/test_workspace_link.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cg-code-graph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.22.0
|
|
4
4
|
Summary: cg: a code graph of routes, calls, data access and platform boundaries for agents and humans (CLI + MCP server)
|
|
5
5
|
Author: cyberchronos00
|
|
6
6
|
License-Expression: MIT
|
|
@@ -33,6 +33,8 @@ Dynamic: license-file
|
|
|
33
33
|
|
|
34
34
|
For you and your AI agent (CLI + MCP). No LLM in the graph.
|
|
35
35
|
|
|
36
|
+
<!-- mcp-name: io.github.cyberchronos00/cg-code-graph -->
|
|
37
|
+
|
|
36
38
|
[](https://pypi.org/project/cg-code-graph/) [](https://pepy.tech/project/cg-code-graph) [](https://pypi.org/project/cg-code-graph/) [](https://github.com/cyberchronos00/code-graph/blob/main/LICENSE) [](https://code-graph.cyberchronos00.workers.dev/)
|
|
37
39
|
|
|
38
40
|
[Docs](https://code-graph.cyberchronos00.workers.dev/) · [Quick start](https://code-graph.cyberchronos00.workers.dev/docs/quickstart) · [CLI](https://code-graph.cyberchronos00.workers.dev/docs/cli) · [MCP](https://code-graph.cyberchronos00.workers.dev/docs/mcp) · [Changelog](https://github.com/cyberchronos00/code-graph/blob/main/CHANGELOG.md)
|
|
@@ -91,7 +93,7 @@ Go and others: import a SCIP index with `cg index --scip FILE`. Run `cg doctor`
|
|
|
91
93
|
- Across repos: `cg link` matches client HTTP calls (frontends and Laravel / Guzzle backends) to server routes, and checks request keys (Laravel FormRequest, Elysia schemas, Nuxt / TypeScript bodies).
|
|
92
94
|
- Route guards: `cg routes --writes --unguarded` lists routes that write with no auth guard. Laravel checks inside the action count as inline guards unless `--strict`.
|
|
93
95
|
- Security views: `cg surface` lists the inbound / outbound attack surface and findings (hardcoded credentials, plaintext protocols, unverified webhooks, unguarded handlers, listeners on all interfaces, disabled TLS / SSH verification, plaintext gRPC, exposed IPC, outbound URLs built from request input) as text, JSON or SARIF, with `--fail-on` for CI.
|
|
94
|
-
- MCP server (`cg-mcp`) so agents query the graph instead of grepping.
|
|
96
|
+
- MCP server (`cg-mcp`) so agents query the graph instead of grepping. One server can serve many graphs (`graphs` plus an optional `graph` argument); a single `--db` stays one graph. See [MCP](https://code-graph.cyberchronos00.workers.dev/docs/mcp).
|
|
95
97
|
- Visual view (`cg serve`) and plan checks (`cg plan check`) for planned changes.
|
|
96
98
|
|
|
97
99
|
## Docs
|
|
@@ -6,6 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
For you and your AI agent (CLI + MCP). No LLM in the graph.
|
|
8
8
|
|
|
9
|
+
<!-- mcp-name: io.github.cyberchronos00/cg-code-graph -->
|
|
10
|
+
|
|
9
11
|
[](https://pypi.org/project/cg-code-graph/) [](https://pepy.tech/project/cg-code-graph) [](https://pypi.org/project/cg-code-graph/) [](https://github.com/cyberchronos00/code-graph/blob/main/LICENSE) [](https://code-graph.cyberchronos00.workers.dev/)
|
|
10
12
|
|
|
11
13
|
[Docs](https://code-graph.cyberchronos00.workers.dev/) · [Quick start](https://code-graph.cyberchronos00.workers.dev/docs/quickstart) · [CLI](https://code-graph.cyberchronos00.workers.dev/docs/cli) · [MCP](https://code-graph.cyberchronos00.workers.dev/docs/mcp) · [Changelog](https://github.com/cyberchronos00/code-graph/blob/main/CHANGELOG.md)
|
|
@@ -64,7 +66,7 @@ Go and others: import a SCIP index with `cg index --scip FILE`. Run `cg doctor`
|
|
|
64
66
|
- Across repos: `cg link` matches client HTTP calls (frontends and Laravel / Guzzle backends) to server routes, and checks request keys (Laravel FormRequest, Elysia schemas, Nuxt / TypeScript bodies).
|
|
65
67
|
- Route guards: `cg routes --writes --unguarded` lists routes that write with no auth guard. Laravel checks inside the action count as inline guards unless `--strict`.
|
|
66
68
|
- Security views: `cg surface` lists the inbound / outbound attack surface and findings (hardcoded credentials, plaintext protocols, unverified webhooks, unguarded handlers, listeners on all interfaces, disabled TLS / SSH verification, plaintext gRPC, exposed IPC, outbound URLs built from request input) as text, JSON or SARIF, with `--fail-on` for CI.
|
|
67
|
-
- MCP server (`cg-mcp`) so agents query the graph instead of grepping.
|
|
69
|
+
- MCP server (`cg-mcp`) so agents query the graph instead of grepping. One server can serve many graphs (`graphs` plus an optional `graph` argument); a single `--db` stays one graph. See [MCP](https://code-graph.cyberchronos00.workers.dev/docs/mcp).
|
|
68
70
|
- Visual view (`cg serve`) and plan checks (`cg plan check`) for planned changes.
|
|
69
71
|
|
|
70
72
|
## Docs
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""code-graph: deterministic code knowledge graph (beta)."""
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.22.0"
|
|
@@ -73,6 +73,27 @@ def _add_install_parser(sub, uninstall: bool):
|
|
|
73
73
|
p.add_argument("--uninstall", action="store_true", help="remove the entry instead of writing it")
|
|
74
74
|
p.add_argument("--dry-run", action="store_true", help="print the exact changes and write nothing")
|
|
75
75
|
p.add_argument("--yes", action="store_true", help="skip the confirmation prompt")
|
|
76
|
+
if not uninstall:
|
|
77
|
+
p.add_argument("--registry", action="store_true",
|
|
78
|
+
help="global single entry: cg-mcp with no --db; graphs come from the registry")
|
|
79
|
+
p.add_argument("--migrate", action="store_true",
|
|
80
|
+
help="fold per-repo cg-* host entries into the graph registry (dry run unless --apply)")
|
|
81
|
+
p.add_argument("--apply", action="store_true", help="with --migrate, write the registry and the host config")
|
|
82
|
+
p.add_argument("--graphs", help="registry file for --migrate (default: ~/.config/cg/graphs.toml)")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def _impact_labels(rows: list[dict], name_of, group_of) -> list[str]:
|
|
86
|
+
"""Display names for one impact listing. Same-name rows in one group gain a file suffix."""
|
|
87
|
+
from collections import defaultdict
|
|
88
|
+
groups = defaultdict(list)
|
|
89
|
+
for i, row in enumerate(rows):
|
|
90
|
+
groups[group_of(row)].append(i)
|
|
91
|
+
labels = [name_of(row) for row in rows]
|
|
92
|
+
for idxs in groups.values():
|
|
93
|
+
named = Q.disambiguated([labels[i] for i in idxs], [rows[i].get("file") for i in idxs])
|
|
94
|
+
for i, lab in zip(idxs, named):
|
|
95
|
+
labels[i] = lab
|
|
96
|
+
return labels
|
|
76
97
|
|
|
77
98
|
|
|
78
99
|
def main(argv=None):
|
|
@@ -321,8 +342,8 @@ def main(argv=None):
|
|
|
321
342
|
p.add_argument("--quiet", action="store_true", help="pass --quiet to each refresh")
|
|
322
343
|
helps = {"reaches": "everything that depends on the targets, grouped by entry classification",
|
|
323
344
|
"siblings": "code related to a symbol: class hierarchy, the same method in sibling classes, shared resources, co-callers",
|
|
324
|
-
"writers": "code that writes a table
|
|
325
|
-
"readers": "code that reads a stored property `Type.prop`
|
|
345
|
+
"writers": "code that writes a table, a column (`table.column`) or a stored property `Type.prop`",
|
|
346
|
+
"readers": "code that reads a table, a column (`table.column`) or a stored property `Type.prop`",
|
|
326
347
|
"impact": "callers of a method up to their entry points (reverse walk), overrides listed apart",
|
|
327
348
|
"stats": "node / edge counts of a graph DB",
|
|
328
349
|
"node": "one node's details and its incoming / outgoing edges",
|
|
@@ -342,6 +363,9 @@ def main(argv=None):
|
|
|
342
363
|
p.add_argument("--no-paths", action="store_true")
|
|
343
364
|
p.add_argument("--max-depth", type=int, default=30)
|
|
344
365
|
p.add_argument("--gate", default="auto", help="gate scenario for live/gated split (default: the one indexed; 'none' to disable)")
|
|
366
|
+
if name in ("reaches", "writers", "readers"):
|
|
367
|
+
p.add_argument("--connection", help="only the table / column edges that go to this database connection "
|
|
368
|
+
"(a dynamic name by its pattern, e.g. 'legacy_{store.id}'; docs/cli.md)")
|
|
345
369
|
if name in ("reaches", "impact", "downstream"):
|
|
346
370
|
p.add_argument("--platform", help="only code built for this target (windows, linux, macos, ios, android, web; see docs/platforms.md)")
|
|
347
371
|
if name == "impact":
|
|
@@ -489,9 +513,14 @@ def main(argv=None):
|
|
|
489
513
|
mcp_file=a.mcp_file, dry_run=a.dry_run, assume_yes=a.yes)
|
|
490
514
|
if a.cmd in ("install", "uninstall"):
|
|
491
515
|
from .mcp_install import run as run_install
|
|
516
|
+
registry = bool(getattr(a, "registry", False))
|
|
517
|
+
migrate = bool(getattr(a, "migrate", False))
|
|
518
|
+
if (registry or migrate) and not a.project:
|
|
519
|
+
a.glob = True
|
|
492
520
|
return run_install(a.host, scope="global" if a.glob else "project", root=a.dir, db=a.db,
|
|
493
521
|
tools=a.tools, portable=a.portable, remove=a.cmd == "uninstall" or a.uninstall,
|
|
494
|
-
dry_run=a.dry_run, assume_yes=a.yes
|
|
522
|
+
dry_run=a.dry_run, assume_yes=a.yes, registry=registry, migrate=migrate,
|
|
523
|
+
apply=bool(getattr(a, "apply", False)), graphs=getattr(a, "graphs", None))
|
|
495
524
|
if a.cmd == "hooks":
|
|
496
525
|
from . import hooks as HK
|
|
497
526
|
return HK.run(a.action, root=a.dir, db=a.db, dry_run=a.dry_run, assume_yes=a.yes)
|
|
@@ -646,7 +675,7 @@ def main(argv=None):
|
|
|
646
675
|
return
|
|
647
676
|
if a.cmd == "reaches":
|
|
648
677
|
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,
|
|
649
|
-
platform=a.platform)
|
|
678
|
+
platform=a.platform, connection=a.connection)
|
|
650
679
|
res["completeness"] = _completeness(st, [x for t in res["targets"].values() for x in t] + [i["id"] for i in res["items"]])
|
|
651
680
|
print(json.dumps(res, indent=1, default=str) if a.json else Q.render_reaches(res, show_paths=not a.no_paths))
|
|
652
681
|
_note(res["completeness"], a.json)
|
|
@@ -658,26 +687,35 @@ def main(argv=None):
|
|
|
658
687
|
if res.get("platform"):
|
|
659
688
|
from .platforms import render_filter
|
|
660
689
|
print(render_filter(res["platform"]))
|
|
661
|
-
|
|
662
|
-
|
|
690
|
+
dropped = res["platform"].get("targets_not_built") or []
|
|
691
|
+
if dropped and res["targets"]:
|
|
692
|
+
print(f"not built for {a.platform}: {', '.join(dropped[:6])}")
|
|
693
|
+
if dropped and not res["targets"]:
|
|
694
|
+
msg = f"{a.spec} is not built for {a.platform}: nothing calls it there"
|
|
695
|
+
if Q.divergence_lists(st, a.platform, dropped):
|
|
696
|
+
msg += (f" (`cg platforms divergence --target {a.platform}` lists references to it that would not build)")
|
|
697
|
+
print(msg); return
|
|
663
698
|
print(f"targets: {res['targets'][:5]}")
|
|
664
699
|
if not res["targets"]:
|
|
665
700
|
print(f"no method matches {a.spec!r}; try `search` with part of the name"); return
|
|
666
|
-
|
|
667
|
-
print(f"
|
|
668
|
-
f"{a.platform}` lists references to it that would not build)"); return
|
|
701
|
+
for d in res.get("default_arguments") or []:
|
|
702
|
+
print(f"via default argument: {d['src']} @ {d['file']}:{d['line']}")
|
|
669
703
|
for line in Q.override_lines(res):
|
|
670
704
|
print(line)
|
|
705
|
+
if res.get("connections"):
|
|
706
|
+
print(Q.connections_line(res["connections"]))
|
|
671
707
|
if not res["callers"] and not res["entry_points"]:
|
|
672
708
|
print(Q.explain_no_callers(st, a.spec, res["targets"], a.min_confidence)); return
|
|
673
709
|
print(f"callers (transitive): {len(res['callers'])}")
|
|
674
|
-
|
|
710
|
+
caller_names = _impact_labels(res["callers"], lambda c: c.get("fqn") or c["id"], lambda c: c.get("module") or c.get("kind"))
|
|
711
|
+
for c, nm in zip(res["callers"], caller_names):
|
|
675
712
|
loc = f" @ {c['file']}:{c['line']}" if Q.NATIVE_FILE_RE.search(c.get("file") or "") else ""
|
|
676
|
-
print(f" d={c['depth']} [{c['module'] or c['kind']}] {
|
|
713
|
+
print(f" d={c['depth']} [{c['module'] or c['kind']}] {nm}{loc}{Q.caller_label(c)}")
|
|
677
714
|
print(f"entry points: {len(res['entry_points'])}")
|
|
678
|
-
|
|
715
|
+
entry_names = _impact_labels(res["entry_points"], lambda e: e["name"], lambda e: e.get("entry_kind"))
|
|
716
|
+
for e, nm0 in zip(res["entry_points"], entry_names):
|
|
679
717
|
native = Q.NATIVE_FILE_RE.search(e.get("file") or "")
|
|
680
|
-
nm = f"{e.get('fqn') or e['name']} @ {e['file']}:{e['line']}" if native else
|
|
718
|
+
nm = f"{e.get('fqn') or e['name']} @ {e['file']}:{e['line']}" if native else nm0
|
|
681
719
|
print(f" {e['entry_kind']:16} {nm} conf={e['path_confidence']}{Q.CANDIDATE_LABEL if e.get('candidate') else ''}"
|
|
682
720
|
f"{Q.generated_label(e)}{Q.platform_label(e)}")
|
|
683
721
|
if not a.no_paths:
|
|
@@ -702,17 +740,14 @@ def main(argv=None):
|
|
|
702
740
|
res = RT.roundtrip(st, a.spec, include_tests=a.tests)
|
|
703
741
|
print(RT.to_json(res) if a.json else RT.render(res))
|
|
704
742
|
elif a.cmd in ("writers", "readers"):
|
|
705
|
-
|
|
743
|
+
groups = Q.access(st, a.spec, a.cmd, a.connection)
|
|
744
|
+
rows = [r for g in groups for r in g["rows"]]
|
|
706
745
|
if a.json:
|
|
707
746
|
print(json.dumps(rows, indent=1)); return
|
|
708
747
|
if not rows:
|
|
709
|
-
print(Q.explain_no_writers(st, a.spec, a.cmd))
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
ex = {k: v for k, v in (r.get("attrs") or {}).items() if k in ("receiver", "accessor", "storage")}
|
|
713
|
-
extra = (" " + " ".join(f"{k}={v}" for k, v in ex.items())) if ex else ""
|
|
714
|
-
kind = f"{r['kind']}({r['attrs']['orig']})" if r.get("test") else r['kind']
|
|
715
|
-
print(f"[{r['module']}] {r['fqn']} {kind} {r['dst']} @{r['file']}:{r['line']} ({r['confidence']}){extra} entries: {ek}")
|
|
748
|
+
print(Q.explain_no_connection(st, a.spec, a.connection, a.cmd) if a.connection else Q.explain_no_writers(st, a.spec, a.cmd))
|
|
749
|
+
return
|
|
750
|
+
print("\n".join(Q.render_access(groups)))
|
|
716
751
|
verb = "write" if a.cmd == "writers" else "read"
|
|
717
752
|
nt = sum(1 for r in rows if r.get("test"))
|
|
718
753
|
print(f"{len(rows)} {verb} edges, {len({r['src'] for r in rows})} {a.cmd}" + (f" ({nt} from test code)" if nt else ""))
|
|
@@ -773,6 +808,14 @@ def node_doc(st, nid: str) -> dict:
|
|
|
773
808
|
return {"node": n, "out": edges("src", "dst"), "in": edges("dst", "src")}
|
|
774
809
|
|
|
775
810
|
|
|
811
|
+
def _mass_note(e: dict) -> str:
|
|
812
|
+
"""` via update(validated()) keys from UpdateBookRequest::rules ∩ Book::$fillable` for a mass-assignment column write (#177)."""
|
|
813
|
+
at = e.get("attrs") or {}
|
|
814
|
+
if e["kind"] != "WRITES_COLUMN" or not at.get("mass_assignment"):
|
|
815
|
+
return ""
|
|
816
|
+
return f" via {at.get('via')}" + (f" keys from {' ∩ '.join(at['keys_from'])}" if at.get("keys_from") else "")
|
|
817
|
+
|
|
818
|
+
|
|
776
819
|
def render_node(d: dict) -> str:
|
|
777
820
|
"""`cg node` text: the node's location, kind and attrs, then its edges; the same edge from one site (one row per
|
|
778
821
|
gate scenario or accessor) is listed once with a count."""
|
|
@@ -801,10 +844,10 @@ def render_node(d: dict) -> str:
|
|
|
801
844
|
out.append(f" {'outgoing' if key == 'out' else 'incoming'} ({len(es)}):" if es else f" {'outgoing' if key == 'out' else 'incoming'}: none")
|
|
802
845
|
seen: dict = {}
|
|
803
846
|
for e in es:
|
|
804
|
-
k = (e["kind"], e[other], e["file"], e["line"], e["confidence"])
|
|
847
|
+
k = (e["kind"], e[other], e["file"], e["line"], e["confidence"], _mass_note(e))
|
|
805
848
|
seen[k] = seen.get(k, 0) + 1
|
|
806
|
-
for (kind, o, f, line, conf), c in seen.items():
|
|
807
|
-
out.append(f" {arrow} {kind} {o} @{f}:{line} {conf}" + (f" ×{c}" if c > 1 else ""))
|
|
849
|
+
for (kind, o, f, line, conf, note), c in seen.items():
|
|
850
|
+
out.append(f" {arrow} {kind} {o} @{f}:{line} {conf}{note}" + (f" ×{c}" if c > 1 else ""))
|
|
808
851
|
return "\n".join(out)
|
|
809
852
|
|
|
810
853
|
|
|
@@ -233,9 +233,20 @@ def file_completeness(discovered: list[str], report: dict) -> dict:
|
|
|
233
233
|
for b in BUCKETS:
|
|
234
234
|
res[b] = len(out[b])
|
|
235
235
|
res["paths"] = {b: v[:MAX_PATHS] for b, v in out.items() if v}
|
|
236
|
+
if out["excluded"]:
|
|
237
|
+
res["exclude_reasons"] = {f: _exclude_reason(f) for f in out["excluded"]}
|
|
236
238
|
return res
|
|
237
239
|
|
|
238
240
|
|
|
241
|
+
def _exclude_reason(path: str) -> str:
|
|
242
|
+
"""Why a discovered file was left out of the graph: tool config, a test file, or a `.cg.yaml` exclude."""
|
|
243
|
+
if _TOOL_FILE.search(path):
|
|
244
|
+
return "tool config"
|
|
245
|
+
if _TEST_NAME.search(path):
|
|
246
|
+
return "test file"
|
|
247
|
+
return ".cg.yaml exclude"
|
|
248
|
+
|
|
249
|
+
|
|
239
250
|
def missing_files(e: dict) -> int:
|
|
240
251
|
"""Discovered files of a language entry that are not in the graph for a reason other than a deliberate exclusion."""
|
|
241
252
|
return sum(e.get(b, 0) for b in ("parse_failed", "skipped_oversize", "unmapped"))
|
|
@@ -308,6 +319,8 @@ def compute(root: str | Path, plugins: dict, scip_imported: bool = False, report
|
|
|
308
319
|
status, reason = _status(lang, st)
|
|
309
320
|
e = {"language": lang, "files": n, "status": status,
|
|
310
321
|
"by_ext": {x: files[x] for x in exts if files[x]}}
|
|
322
|
+
if lang == "typescript" and not any(x in e["by_ext"] for x in (".ts", ".tsx", ".mts", ".cts")):
|
|
323
|
+
e["label"] = "javascript"
|
|
311
324
|
if reason:
|
|
312
325
|
e["reason"] = reason
|
|
313
326
|
if status in ("skipped", "heuristic", "not_indexed"):
|
|
@@ -495,16 +508,22 @@ def blind_spots(cov: dict | None) -> list[dict]:
|
|
|
495
508
|
return list((cov or {}).get("blind_spots") or [])
|
|
496
509
|
|
|
497
510
|
|
|
511
|
+
def _shown_lang(e: dict) -> str:
|
|
512
|
+
"""Display name. A TypeScript-plugin entry with no .ts/.tsx/.mts/.cts files reads as javascript; JSON keeps `language`."""
|
|
513
|
+
return e.get("label") or e["language"]
|
|
514
|
+
|
|
515
|
+
|
|
498
516
|
def _entry_text(e: dict) -> str:
|
|
499
517
|
"""'php 18 exact' / 'python 4 discovered, 2 indexed (exact parser): 1 parse failed, 1 unmapped' /
|
|
500
|
-
'
|
|
518
|
+
'javascript 12 discovered, 2 indexed (exact parser): 9 unmapped, 1 excluded'."""
|
|
501
519
|
pe = e.get("parsed_with_errors")
|
|
502
520
|
errs = f", {pe} parsed with syntax errors" if pe else ""
|
|
521
|
+
name = _shown_lang(e)
|
|
503
522
|
if e.get("files_complete") is False:
|
|
504
|
-
parts = [f"{e[b]} {BUCKET_SHORT[b]}" for b in
|
|
505
|
-
return (f"{
|
|
523
|
+
parts = [f"{e[b]} {BUCKET_SHORT[b]}" for b in BUCKETS if e.get(b)]
|
|
524
|
+
return (f"{name} {e['files']} discovered, {e['indexed']} indexed ({e['status'].replace('_', ' ')} parser)"
|
|
506
525
|
+ (": " + ", ".join(parts) if parts else "") + errs)
|
|
507
|
-
return f"{
|
|
526
|
+
return f"{name} {e['files']} {e['status'].replace('_', ' ')}{errs}"
|
|
508
527
|
|
|
509
528
|
|
|
510
529
|
def realtime_unresolved_lines(e: dict, indent: str = " ") -> list[str]:
|
|
@@ -579,11 +598,16 @@ def _paths_lines(e: dict, all_files: bool, indent: str = " ") -> list[str]:
|
|
|
579
598
|
out = []
|
|
580
599
|
for b in BUCKETS:
|
|
581
600
|
ps = (e.get("paths") or {}).get(b) or []
|
|
582
|
-
if not ps
|
|
601
|
+
if not ps:
|
|
583
602
|
continue
|
|
584
603
|
show = ps if all_files else ps[:SHOW_PATHS]
|
|
585
604
|
more = e.get(b, len(ps)) - len(show)
|
|
586
|
-
|
|
605
|
+
if b == "excluded":
|
|
606
|
+
reasons = e.get("exclude_reasons") or {}
|
|
607
|
+
body = ", ".join(f"{p} ({reasons.get(p) or _exclude_reason(p)})" for p in show)
|
|
608
|
+
else:
|
|
609
|
+
body = ", ".join(show)
|
|
610
|
+
out.append(f"{indent}{BUCKET_SHORT[b]}: " + body + (f" … +{more} more (--all-files)" if more > 0 else ""))
|
|
587
611
|
return out
|
|
588
612
|
|
|
589
613
|
|
|
@@ -720,11 +744,12 @@ def render(covs: dict[str, dict | None], all_files: bool = False) -> str:
|
|
|
720
744
|
for e in gaps(cov):
|
|
721
745
|
any_gap = True
|
|
722
746
|
exts = ", ".join(f"{k} {v}" for k, v in sorted(e["by_ext"].items()))
|
|
747
|
+
shown = _shown_lang(e)
|
|
723
748
|
if e.get("files_complete") is False:
|
|
724
749
|
parts = [f"{e[b]} {BUCKET_SHORT[b]}" for b in BUCKETS if e.get(b)]
|
|
725
|
-
line = f" {
|
|
750
|
+
line = f" {shown}: {e['files']} files ({exts}) {e['indexed']} indexed, " + ", ".join(parts)
|
|
726
751
|
else:
|
|
727
|
-
line = f" {
|
|
752
|
+
line = f" {shown}: {e['files']} files ({exts}) {e['status'].replace('_', ' ')}"
|
|
728
753
|
if e.get("reason"):
|
|
729
754
|
line += f": {e['reason']}"
|
|
730
755
|
out.append(line)
|
|
@@ -795,7 +820,7 @@ def note(covs: dict[str, dict | None]) -> str:
|
|
|
795
820
|
for e in gaps(c):
|
|
796
821
|
what = (f"{e['indexed']} of {e['files']} files indexed" if e.get("files_complete") is False
|
|
797
822
|
else f"{e['files']} files, {e['status'].replace('_', ' ')}")
|
|
798
|
-
bad.append(f"{e
|
|
823
|
+
bad.append(f"{_shown_lang(e)} ({what}{', ' + r if len(covs) > 1 else ''})")
|
|
799
824
|
bs = [b for c in covs.values() for b in blind_spots(c)]
|
|
800
825
|
bs_txt = f"; blind spots: {_bs_count(bs)} (see coverage)" if bs else ""
|
|
801
826
|
nerr = sum(e.get("syntax_error_files", 0) for c in covs.values() for e in (c or {}).get("languages", []))
|
|
@@ -956,6 +981,18 @@ def completeness_for(store, node_ids=None, categories=("route", "handler"), whol
|
|
|
956
981
|
categories=categories, ids=set(node_ids), files=sc["files"], **kw)
|
|
957
982
|
|
|
958
983
|
|
|
984
|
+
def _unsupported_text(uns: dict) -> str:
|
|
985
|
+
"""`unsupported: sh 3`. A single-repo DB drops a `shop/sh` prefix; a combined graph keeps `api/sh`."""
|
|
986
|
+
keys = list(uns)
|
|
987
|
+
prefixes = {k.partition("/")[0] for k in keys if "/" in k}
|
|
988
|
+
drop = len(prefixes) <= 1
|
|
989
|
+
parts = []
|
|
990
|
+
for k, v in sorted(uns.items()):
|
|
991
|
+
label = k.partition("/")[2] if drop and "/" in k else k
|
|
992
|
+
parts.append(f"{label} {v}")
|
|
993
|
+
return "unsupported: " + ", ".join(parts)
|
|
994
|
+
|
|
995
|
+
|
|
959
996
|
def possibly_more(comp: dict) -> str:
|
|
960
997
|
"""'1 unmodelled route registration, 2 Python files not indexed' for an incomplete answer, '' when complete."""
|
|
961
998
|
if comp.get("complete"):
|
|
@@ -990,7 +1027,7 @@ def possibly_more(comp: dict) -> str:
|
|
|
990
1027
|
parts.append(f"{len(se)} file{'s' if len(se) != 1 else ''} with syntax errors ({x['file']}{pos}"
|
|
991
1028
|
+ (f" +{len(se) - 1}" if len(se) > 1 else "") + ")")
|
|
992
1029
|
if comp.get("unsupported"):
|
|
993
|
-
parts.append(
|
|
1030
|
+
parts.append(_unsupported_text(comp["unsupported"]))
|
|
994
1031
|
if comp.get("recorded") is False:
|
|
995
1032
|
parts.append("coverage not recorded")
|
|
996
1033
|
return ", ".join(parts)
|
|
@@ -292,8 +292,35 @@ def read_spring_datasources(root: Path) -> list:
|
|
|
292
292
|
out.append(fact)
|
|
293
293
|
return out
|
|
294
294
|
|
|
295
|
+
|
|
296
|
+
CONNECTION_EDGE_KINDS = ("READS_TABLE", "WRITES_TABLE", "READS_COLUMN", "WRITES_COLUMN", "MENTIONS_COLUMN")
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def table_connections(builder) -> int:
|
|
300
|
+
"""`attrs.connections` of a table node: `{connection: edge count}` over its table / column edges that carry
|
|
301
|
+
`attrs.connection` (most used first). One table name used on several connections stays one node. Not tied to an ORM:
|
|
302
|
+
a plugin only has to set `attrs.connection` on its table / column edges."""
|
|
303
|
+
counts: dict[str, dict[str, int]] = {}
|
|
304
|
+
for e in builder.edges.values():
|
|
305
|
+
conn = (e.attrs or {}).get("connection")
|
|
306
|
+
if e.kind not in CONNECTION_EDGE_KINDS or not conn:
|
|
307
|
+
continue
|
|
308
|
+
key = e.dst.split(":", 1)[1]
|
|
309
|
+
tid = f"table:{key}" if e.dst.startswith("table:") else f"table:{key.rsplit('.', 1)[0]}"
|
|
310
|
+
counts.setdefault(tid, {})
|
|
311
|
+
counts[tid][conn] = counts[tid].get(conn, 0) + 1
|
|
312
|
+
n = 0
|
|
313
|
+
for tid, c in counts.items():
|
|
314
|
+
node = builder.nodes.get(tid)
|
|
315
|
+
if node is not None:
|
|
316
|
+
node.attrs["connections"] = dict(sorted(c.items(), key=lambda kv: (-kv[1], kv[0])))
|
|
317
|
+
n += 1
|
|
318
|
+
return n
|
|
319
|
+
|
|
320
|
+
|
|
295
321
|
def attach(builder, root: Path) -> dict:
|
|
296
322
|
root = Path(root)
|
|
323
|
+
table_connections(builder)
|
|
297
324
|
envs = {n.id[len("env:"):]: n for n in builder.nodes.values() if n.kind == "env"}
|
|
298
325
|
conns = [n for n in builder.nodes.values() if n.kind == "connection"]
|
|
299
326
|
# Spring datasources before the empty-check so a repo with only application*.properties still indexes (#41)
|
|
@@ -646,6 +673,16 @@ def attach(builder, root: Path) -> dict:
|
|
|
646
673
|
(builder.nodes[nid].attrs or {}).get("confidence") or "resolved",
|
|
647
674
|
op="table", via="laravel connection")
|
|
648
675
|
st["tables"] = st.get("tables", 0) + 1
|
|
676
|
+
# a table used on several connections: one CONNECTS_TO per connection that maps to a system, not only the first
|
|
677
|
+
for n in builder.nodes.values():
|
|
678
|
+
if n.kind != "table":
|
|
679
|
+
continue
|
|
680
|
+
for cname in (n.attrs or {}).get("connections") or {}:
|
|
681
|
+
nid = conn_ext.get(f"connection:{cname}")
|
|
682
|
+
if nid:
|
|
683
|
+
builder.add_edge(n.id, nid, "CONNECTS_TO", n.file, n.line,
|
|
684
|
+
(builder.nodes[nid].attrs or {}).get("confidence") or "resolved",
|
|
685
|
+
op="table", via=f"connection {cname}")
|
|
649
686
|
|
|
650
687
|
# ---- ORM tables without a datasource block: attach to the sole SQL system of the project (#41 step 2)
|
|
651
688
|
# Immich (Kysely + DB_URL), Nest TypeORM (@Entity + DATABASE_URL) when no DataSource fact named them.
|
|
@@ -28,6 +28,19 @@ from .plugins.flutter.plugin import FlutterPlugin
|
|
|
28
28
|
from .plugins.nest.plugin import NestPlugin
|
|
29
29
|
from .plugins.nextjs.plugin import NextPlugin
|
|
30
30
|
from .plugins.express.plugin import ExpressPlugin
|
|
31
|
+
import subprocess
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _git_head(root) -> str | None:
|
|
35
|
+
"""Commit indexed for this root, when it is a git work tree."""
|
|
36
|
+
try:
|
|
37
|
+
proc = subprocess.run(["git", "-C", str(root), "rev-parse", "HEAD"],
|
|
38
|
+
capture_output=True, text=True, timeout=8)
|
|
39
|
+
except (OSError, subprocess.TimeoutExpired):
|
|
40
|
+
return None
|
|
41
|
+
if proc.returncode != 0:
|
|
42
|
+
return None
|
|
43
|
+
return (proc.stdout or "").strip() or None
|
|
31
44
|
from .plugins.astro.plugin import AstroPlugin
|
|
32
45
|
from .plugins.kotlin.plugin import KotlinPlugin
|
|
33
46
|
from .plugins.java.plugin import JavaPlugin
|
|
@@ -464,6 +477,9 @@ def index_project(root: str | Path, db_path: str | Path, name: str | None = None
|
|
|
464
477
|
stats["nodes"] = len(builder.nodes)
|
|
465
478
|
stats["edges"] = len(builder.edges)
|
|
466
479
|
stats["index_seconds"] = round(time.time() - t0, 2)
|
|
467
|
-
|
|
480
|
+
head = _git_head(project.root)
|
|
481
|
+
extra = {"commit": head} if head else {}
|
|
482
|
+
store.set_meta(project=project.name, root=str(project.root), stats=stats,
|
|
483
|
+
indexed_at=time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime()), **extra)
|
|
468
484
|
store.db.close()
|
|
469
485
|
return stats
|
|
@@ -497,10 +497,23 @@ def link_many(repos: list[tuple[str, str, str]], out_db: str, *, allow: dict | N
|
|
|
497
497
|
for name, path, _role in repos:
|
|
498
498
|
got = for_graph(GraphStore(path))
|
|
499
499
|
cov.update({name: next(iter(got.values()))} if len(got) == 1 else got)
|
|
500
|
+
commits = {}
|
|
501
|
+
for name, path, _role in repos:
|
|
502
|
+
try:
|
|
503
|
+
member_st = GraphStore(path)
|
|
504
|
+
try:
|
|
505
|
+
member = member_st.meta()
|
|
506
|
+
finally:
|
|
507
|
+
member_st.db.close()
|
|
508
|
+
except Exception:
|
|
509
|
+
member = {}
|
|
510
|
+
if member.get("commit"):
|
|
511
|
+
commits[name] = member["commit"]
|
|
500
512
|
store.set_meta(project="+".join(names), stats=stats, repos=names, coverage=cov,
|
|
501
513
|
sources={name: str(Path(path).resolve()) for name, path, _role in repos},
|
|
502
514
|
repo_roles={name: role for name, _path, role in repos}, link_clients=clients, link_allow=allow,
|
|
503
|
-
indexed_at=time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime())
|
|
515
|
+
indexed_at=time.strftime("%Y-%m-%d %H:%M:%S UTC", time.gmtime()),
|
|
516
|
+
**({"commit": commits} if commits else {}))
|
|
504
517
|
db.close()
|
|
505
518
|
return {"stats": stats, "results": results, "payload_issues": issues, "uncalled_routes": uncalled,
|
|
506
519
|
"webhook_subscriptions": subscriptions, "external_callbacks": callbacks}
|