cg-code-graph 0.16.0__tar.gz → 0.18.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cg_code_graph-0.18.0/MANIFEST.in +8 -0
- {cg_code_graph-0.16.0/cg_code_graph.egg-info → cg_code_graph-0.18.0}/PKG-INFO +6 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/README.md +4 -2
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/__init__.py +1 -1
- cg_code_graph-0.18.0/cg_code_graph/__main__.py +4 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/agent_rules.py +3 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/agents.py +11 -31
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/bridges.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/cli.py +56 -24
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/config.py +3 -3
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/cache.py +123 -18
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/detect.py +33 -0
- cg_code_graph-0.18.0/cg_code_graph/core/env.py +84 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/extractors.py +9 -8
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/generated.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/model.py +3 -3
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/paths.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/plugin.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/syntax_errors.py +2 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/coverage.py +33 -21
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/doctor.py +126 -33
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/hooks.py +28 -6
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/indexer.py +14 -5
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/local_ipc.py +2 -2
- cg_code_graph-0.18.0/cg_code_graph/mcp_install.py +1049 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/mcp_server.py +66 -5
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/parity.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plans.py +2 -2
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/platform_scan.py +2 -2
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/platforms.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/cfamily/plugin.py +18 -17
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/dart/bridges.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/dart/extractor/bin/extract.dart +2 -2
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/dart/plugin.py +7 -6
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/django/plugin.py +2 -2
- cg_code_graph-0.18.0/cg_code_graph/plugins/java/exact.py +352 -0
- cg_code_graph-0.18.0/cg_code_graph/plugins/java/plugin.py +1005 -0
- cg_code_graph-0.18.0/cg_code_graph/plugins/jvm/__init__.py +1 -0
- cg_code_graph-0.18.0/cg_code_graph/plugins/jvm/interop.py +212 -0
- cg_code_graph-0.18.0/cg_code_graph/plugins/jvm/spring.py +959 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/kotlin/exact.py +240 -46
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/kotlin/plugin.py +56 -214
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/laravel/tests.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/native/runner.py +7 -7
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/nuxt/plugin.py +3 -3
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/php/plugin.py +3 -3
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/python/aitools.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/python/external.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/python/plugin.py +3 -3
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/python/tests.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/rust/cargo.py +4 -3
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/rust/plugin.py +16 -15
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/stubs/plugins.py +2 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/swift/baseurl.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/swift/exact.py +31 -20
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/swift/indexstore.py +3 -2
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/swift/plugin.py +2 -2
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/ts/extractor/extract.mjs +12 -12
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/ts/plugin.py +7 -6
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/tsweb/common.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/tsweb/data.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/__init__.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/c_cpp.yaml +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/common.yaml +2 -2
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/express.yaml +1 -1
- cg_code_graph-0.18.0/cg_code_graph/presets/java.yaml +5 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/kotlin.yaml +1 -3
- cg_code_graph-0.18.0/cg_code_graph/presets/spring.yaml +22 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/protocols/__init__.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/protocols/builtin.py +18 -18
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/protocols/matchers.py +3 -3
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/protocols/view.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/query.py +3 -3
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/realtime_events.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/realtime_native.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/routes.py +3 -3
- cg_code_graph-0.18.0/cg_code_graph/viz/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/graph.py +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/server.py +2 -2
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/static/app.js +1 -1
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/tools/shoot.mjs +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0/cg_code_graph.egg-info}/PKG-INFO +6 -3
- cg_code_graph-0.18.0/cg_code_graph.egg-info/SOURCES.txt +343 -0
- cg_code_graph-0.18.0/cg_code_graph.egg-info/entry_points.txt +3 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/cg_code_graph.egg-info/requires.txt +1 -0
- cg_code_graph-0.18.0/cg_code_graph.egg-info/top_level.txt +1 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/pyproject.toml +7 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_affected.py +7 -7
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_agents_install.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_agents_md.py +2 -2
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_ai_tools.py +9 -9
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_android_ipc.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_apple_ipc.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_astro.py +12 -12
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_astro_content.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_astro_server.py +7 -7
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_bridges.py +17 -17
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_bridges_pigeon_monorepo.py +7 -7
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_brokers.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_cache_clean.py +17 -16
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_cache_invalidation.py +15 -15
- cg_code_graph-0.18.0/tests/test_cache_migration.py +196 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_channels_tests.py +9 -9
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_cli_output.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_completeness.py +8 -8
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_config_extras.py +9 -9
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_coverage.py +10 -9
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_coverage_ts_hint.py +2 -2
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_dart_isolates.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_dispatch_interfaces.py +8 -8
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_django_flutter.py +5 -5
- cg_code_graph-0.18.0/tests/test_docs_languages.py +58 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_enum_constants.py +2 -2
- cg_code_graph-0.18.0/tests/test_env.py +66 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_explore.py +9 -9
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_external.py +12 -12
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_gating.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_generated.py +10 -10
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_graphql.py +5 -5
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_hooks.py +68 -9
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_impact_overrides.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_index_isolation.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_inherited_overrides.py +7 -7
- cg_code_graph-0.18.0/tests/test_java.py +225 -0
- cg_code_graph-0.18.0/tests/test_java_exact.py +308 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_jobs.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_js_refs.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_js_runtime.py +23 -23
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_kotlin.py +10 -10
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_kotlin_binding.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_kotlin_exact.py +19 -19
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_kotlin_fields.py +5 -5
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_kotlin_mixed.py +37 -34
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_kotlin_nav_consts.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_kotlin_props.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_laravel_determinism.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_laravel_resources.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_lint_async.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_local_ipc.py +2 -2
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_local_sockets.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_mcp_index.py +7 -7
- cg_code_graph-0.18.0/tests/test_mcp_install.py +400 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_native_cfamily.py +12 -12
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_native_concurrency.py +17 -17
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_native_rust.py +11 -11
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_nuxt_import_dirs.py +5 -5
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_nuxt_rootsrc.py +9 -9
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_packaging.py +29 -25
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_parity.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_parity_structure.py +2 -2
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_php_props.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_plain_js.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_plans.py +8 -8
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_platform_gaps.py +10 -10
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_platform_type_variants.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_platforms.py +13 -13
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_platforms_apple.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_presets_config.py +21 -21
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_process_ipc.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_protocols.py +13 -13
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_app_tests_module.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_collection_chains.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_compat.py +8 -7
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_entry_refs.py +9 -9
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_fields.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_infer_cycles.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_roots.py +10 -10
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_subprocess_tests.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_tests.py +5 -5
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_web_hosts.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_web_routes.py +2 -2
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_python_web_routes_more.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_realtime.py +5 -5
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_realtime_native.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_roundtrip.py +8 -8
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_route_tables.py +5 -5
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_routes_search_explain.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_rpc.py +2 -2
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_scip_health.py +8 -7
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_sdk_external.py +2 -2
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_snippet.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_sockets.py +5 -5
- cg_code_graph-0.18.0/tests/test_spring.py +159 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_starters_budget.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_binding.py +7 -7
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_exact.py +25 -25
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_facts.py +2 -2
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_fields.py +9 -9
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_modules.py +2 -2
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_more.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_nav_values.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_parse_errors.py +8 -8
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_props.py +8 -8
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_sdk.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_testing.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_swift_values.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_tests_scope.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_ts_fields.py +5 -5
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_ts_fields_js_vue.py +1 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_ts_file_specs.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_ts_frameworks.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_ts_nuxt.py +6 -6
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_ts_src_tsconfig.py +5 -5
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_values.py +3 -3
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_viz.py +7 -7
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_vue_nav.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_watch.py +9 -9
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_webhooks.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_websockets.py +4 -4
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_workspace_link.py +7 -7
- cg_code_graph-0.16.0/MANIFEST.in +0 -8
- cg_code_graph-0.16.0/cg_code_graph.egg-info/SOURCES.txt +0 -325
- cg_code_graph-0.16.0/cg_code_graph.egg-info/entry_points.txt +0 -3
- cg_code_graph-0.16.0/cg_code_graph.egg-info/top_level.txt +0 -1
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/LICENSE +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/affected.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/aitools.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/android_ipc.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/apple_ipc.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/apps.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/blindspots.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/brokers.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/concepts.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/fsutil.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/core/store.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/dart_isolates.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/explore.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/external.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/graphql.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/jobs.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/link.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/lint_async.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/local_sockets.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/parity_structure.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/payload.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/astro/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/astro/content.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/astro/plugin.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/cfamily/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/cfamily/syntax.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/dart/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/dart/extractor/pubspec.lock +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/dart/extractor/pubspec.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/dart/http.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/dart/models.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/dart/program.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/django/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/django/extras.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/django/models.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/django/schemas.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/django/shapes.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/django/urls.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/express/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/express/plugin.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/flutter/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/flutter/plugin.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/kotlin → cg_code_graph-0.18.0/cg_code_graph/plugins/java}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/laravel → cg_code_graph-0.18.0/cg_code_graph/plugins/kotlin}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/kotlin/reparse.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/native → cg_code_graph-0.18.0/cg_code_graph/plugins/laravel}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/laravel/broadcast.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/laravel/plugin.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/laravel/values.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/nest → cg_code_graph-0.18.0/cg_code_graph/plugins/native}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/native/gates.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/native/scipread.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/native/ts.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/nextjs → cg_code_graph-0.18.0/cg_code_graph/plugins/nest}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/nest/plugin.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/nuxt → cg_code_graph-0.18.0/cg_code_graph/plugins/nextjs}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/nextjs/plugin.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/php → cg_code_graph-0.18.0/cg_code_graph/plugins/nuxt}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/python → cg_code_graph-0.18.0/cg_code_graph/plugins/php}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/php/external.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/php/extractor/composer.json +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/php/extractor/composer.lock +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/php/extractor/extract.php +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/php/gating.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/php/strings.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/pyweb → cg_code_graph-0.18.0/cg_code_graph/plugins/python}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/python/fields.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/python/refs.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/python/roots.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/python/socketio.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/python/subproc.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/python/values.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/rust → cg_code_graph-0.18.0/cg_code_graph/plugins/pyweb}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/pyweb/plugin.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/pyweb/values.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/scip → cg_code_graph-0.18.0/cg_code_graph/plugins/rust}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/rust/syntax.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/stubs → cg_code_graph-0.18.0/cg_code_graph/plugins/scip}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/scip/importer.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/scip/scip.proto +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/scip/scip_pb2.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/swift → cg_code_graph-0.18.0/cg_code_graph/plugins/stubs}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/ts → cg_code_graph-0.18.0/cg_code_graph/plugins/swift}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/swift/packages.py +0 -0
- {cg_code_graph-0.16.0/codegraph/plugins/tsweb → cg_code_graph-0.18.0/cg_code_graph/plugins/ts}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/ts/baseurl.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/ts/extractor/fw.mjs +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/ts/extractor/package-lock.json +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/ts/extractor/package.json +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/plugins/ts/nav.py +0 -0
- {cg_code_graph-0.16.0/codegraph/viz → cg_code_graph-0.18.0/cg_code_graph/plugins/tsweb}/__init__.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/dart.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/django-ninja.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/django.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/djangorestframework.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/laravel.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/nest.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/nextjs.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/nuxt.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/php.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/python.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/rust.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/swift.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/presets/typescript.yaml +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/process_runs.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/realtime.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/realtime_ws.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/roundtrip.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/rpc.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/sdk_systems.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/sockets.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/starters.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/tests_index.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/udp_apps.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/static/app.css +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/static/index.html +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/static/layered.js +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/static/vendor/VERSIONS.txt +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/static/vendor/cose-base.js +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/static/vendor/cytoscape-fcose.js +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/static/vendor/cytoscape.min.js +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/static/vendor/layout-base.js +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/tools/package-lock.json +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/viz/tools/package.json +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/watch.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/webhooks.py +0 -0
- {cg_code_graph-0.16.0/codegraph → cg_code_graph-0.18.0/cg_code_graph}/xcode.py +0 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/cg_code_graph.egg-info/dependency_links.txt +0 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/setup.cfg +0 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_docs_links.py +0 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_mcp.py +0 -0
- {cg_code_graph-0.16.0 → cg_code_graph-0.18.0}/tests/test_process_runs.py +0 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
graft cg_code_graph
|
|
2
|
+
prune cg_code_graph/plugins/ts/extractor/node_modules
|
|
3
|
+
prune cg_code_graph/plugins/php/extractor/vendor
|
|
4
|
+
prune cg_code_graph/plugins/dart/extractor/.bin
|
|
5
|
+
prune cg_code_graph/plugins/dart/extractor/.dart_tool
|
|
6
|
+
prune cg_code_graph/viz/tools/node_modules
|
|
7
|
+
prune cg_code_graph/viz/tools/screenshots
|
|
8
|
+
global-exclude __pycache__ *.py[cod] *.db *.db-wal *.db-shm
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cg-code-graph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.18.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
|
|
@@ -17,6 +17,7 @@ Requires-Dist: tree-sitter-rust>=0.23
|
|
|
17
17
|
Requires-Dist: tree-sitter-c>=0.23
|
|
18
18
|
Requires-Dist: tree-sitter-cpp>=0.23
|
|
19
19
|
Requires-Dist: tree-sitter-kotlin>=1.0
|
|
20
|
+
Requires-Dist: tree-sitter-java>=0.23
|
|
20
21
|
Requires-Dist: tree-sitter-swift<0.7.4,>=0.6
|
|
21
22
|
Provides-Extra: dev
|
|
22
23
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
@@ -45,6 +46,7 @@ For you and your AI agent (CLI + MCP). No LLM in the graph.
|
|
|
45
46
|
```bash
|
|
46
47
|
pipx install cg-code-graph # or: uv tool install cg-code-graph
|
|
47
48
|
cg index . --db out/graph.db # prints starter queries for your repo
|
|
49
|
+
cg install --host cursor # or claude, codex, vscode, …: registers the MCP server
|
|
48
50
|
cg reaches table:orders --db out/graph.db # any table, connection or config key
|
|
49
51
|
```
|
|
50
52
|
|
|
@@ -75,11 +77,12 @@ dependents: 18 nodes (code: 6, entry points: 9, other: 3)
|
|
|
75
77
|
|   | Nuxt / Vue, NestJS, Next.js, Astro, Express, Fastify, Koa, Hono | exact (TypeScript compiler API) | [TS frameworks](https://code-graph.cyberchronos00.workers.dev/docs/ts-frameworks) |
|
|
76
78
|
|  | Laravel (routes and middleware, queues, broadcasting) | exact (nikic/php-parser; needs PHP 8.2+) | [PHP](https://code-graph.cyberchronos00.workers.dev/docs/php) |
|
|
77
79
|
|  | Flutter | exact (Dart analyzer; needs the Dart SDK) | [Platforms](https://code-graph.cyberchronos00.workers.dev/docs/platforms) |
|
|
78
|
-
|  | Android, Kotlin Multiplatform | heuristic; exact with scip-java (opt-in) | [Kotlin](https://code-graph.cyberchronos00.workers.dev/docs/kotlin) |
|
|
80
|
+
|  | Android, Kotlin Multiplatform, Spring | heuristic; exact with scip-java (opt-in) | [Kotlin](https://code-graph.cyberchronos00.workers.dev/docs/kotlin) |
|
|
81
|
+
|  | Spring (routes, guards, beans, tables, clients) | heuristic; exact with scip-java (opt-in) | [Java](https://code-graph.cyberchronos00.workers.dev/docs/java) |
|
|
79
82
|
|  | iOS / SwiftPM | heuristic; exact with the Swift index store (opt-in) | [Swift](https://code-graph.cyberchronos00.workers.dev/docs/swift) |
|
|
80
83
|
|    | crates / modules, entry points, FFI, `#[cfg]` / `#if` gates | heuristic; exact with rust-analyzer / scip-clang | [Rust, C and C++](https://code-graph.cyberchronos00.workers.dev/docs/native) |
|
|
81
84
|
|
|
82
|
-
Go
|
|
85
|
+
Go and others: import a SCIP index with `cg index --scip FILE`. Run `cg doctor` to see exact / heuristic per language on your machine.
|
|
83
86
|
|
|
84
87
|
## What you get
|
|
85
88
|
|
|
@@ -19,6 +19,7 @@ For you and your AI agent (CLI + MCP). No LLM in the graph.
|
|
|
19
19
|
```bash
|
|
20
20
|
pipx install cg-code-graph # or: uv tool install cg-code-graph
|
|
21
21
|
cg index . --db out/graph.db # prints starter queries for your repo
|
|
22
|
+
cg install --host cursor # or claude, codex, vscode, …: registers the MCP server
|
|
22
23
|
cg reaches table:orders --db out/graph.db # any table, connection or config key
|
|
23
24
|
```
|
|
24
25
|
|
|
@@ -49,11 +50,12 @@ dependents: 18 nodes (code: 6, entry points: 9, other: 3)
|
|
|
49
50
|
|   | Nuxt / Vue, NestJS, Next.js, Astro, Express, Fastify, Koa, Hono | exact (TypeScript compiler API) | [TS frameworks](https://code-graph.cyberchronos00.workers.dev/docs/ts-frameworks) |
|
|
50
51
|
|  | Laravel (routes and middleware, queues, broadcasting) | exact (nikic/php-parser; needs PHP 8.2+) | [PHP](https://code-graph.cyberchronos00.workers.dev/docs/php) |
|
|
51
52
|
|  | Flutter | exact (Dart analyzer; needs the Dart SDK) | [Platforms](https://code-graph.cyberchronos00.workers.dev/docs/platforms) |
|
|
52
|
-
|  | Android, Kotlin Multiplatform | heuristic; exact with scip-java (opt-in) | [Kotlin](https://code-graph.cyberchronos00.workers.dev/docs/kotlin) |
|
|
53
|
+
|  | Android, Kotlin Multiplatform, Spring | heuristic; exact with scip-java (opt-in) | [Kotlin](https://code-graph.cyberchronos00.workers.dev/docs/kotlin) |
|
|
54
|
+
|  | Spring (routes, guards, beans, tables, clients) | heuristic; exact with scip-java (opt-in) | [Java](https://code-graph.cyberchronos00.workers.dev/docs/java) |
|
|
53
55
|
|  | iOS / SwiftPM | heuristic; exact with the Swift index store (opt-in) | [Swift](https://code-graph.cyberchronos00.workers.dev/docs/swift) |
|
|
54
56
|
|    | crates / modules, entry points, FFI, `#[cfg]` / `#if` gates | heuristic; exact with rust-analyzer / scip-clang | [Rust, C and C++](https://code-graph.cyberchronos00.workers.dev/docs/native) |
|
|
55
57
|
|
|
56
|
-
Go
|
|
58
|
+
Go and others: import a SCIP index with `cg index --scip FILE`. Run `cg doctor` to see exact / heuristic per language on your machine.
|
|
57
59
|
|
|
58
60
|
## What you get
|
|
59
61
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""code-graph: deterministic code knowledge graph (beta)."""
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.18.0"
|
|
@@ -44,6 +44,8 @@ Pipe long output through `head` or `tail`:
|
|
|
44
44
|
cg impact <symbol> --db out/graph.db | head -n 40
|
|
45
45
|
While iterating, run one file: `pytest -q -x tests/test_x.py`.
|
|
46
46
|
Run the full suite once at the end: `pytest -q 2>&1 | tail -n 30`.
|
|
47
|
+
|
|
48
|
+
A new language or framework updates README's Supported languages table, its docs page, `docs-site/app/utils/docs-nav.ts`, and `docs-site/app/components/HomeStacks.vue` in the same change.
|
|
47
49
|
"""
|
|
48
50
|
|
|
49
51
|
|
|
@@ -53,7 +55,7 @@ def document() -> str:
|
|
|
53
55
|
|
|
54
56
|
|
|
55
57
|
def pin() -> str:
|
|
56
|
-
"""Published package floor: ``cg-code-graph>=MAJOR.MINOR`` from ``
|
|
58
|
+
"""Published package floor: ``cg-code-graph>=MAJOR.MINOR`` from ``cg_code_graph.__version__``."""
|
|
57
59
|
import re
|
|
58
60
|
|
|
59
61
|
from . import __version__
|
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
project's AGENTS.md / CLAUDE.md / Cursor rules. It only ever writes a clearly marked block and
|
|
3
3
|
never writes silently: every run previews the exact changes and asks before writing (--dry-run
|
|
4
4
|
previews without writing, --yes skips the prompt). Re-running replaces the block in place; remove
|
|
5
|
-
deletes it and restores the surrounding bytes. MCP changes
|
|
5
|
+
deletes it and restores the surrounding bytes. MCP changes affect only the `cg` server entry."""
|
|
6
6
|
from __future__ import annotations
|
|
7
7
|
|
|
8
8
|
import difflib
|
|
9
|
-
import json
|
|
10
9
|
import re
|
|
11
10
|
from pathlib import Path
|
|
12
11
|
|
|
@@ -62,33 +61,11 @@ def plan_text(path: Path, remove: bool, body: str | None = None) -> dict:
|
|
|
62
61
|
|
|
63
62
|
def plan_mcp(path: Path, remove: bool) -> dict:
|
|
64
63
|
"""Add / update / remove only the `cg` entry under mcpServers; every other entry and key is
|
|
65
|
-
kept.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
except ValueError as ex:
|
|
71
|
-
return {"path": str(path), "kind": "mcp", "action": "error", "old": old, "new": old,
|
|
72
|
-
"error": f"not valid JSON ({ex}); left unchanged"}
|
|
73
|
-
else:
|
|
74
|
-
data = {}
|
|
75
|
-
if not isinstance(data, dict):
|
|
76
|
-
return {"path": str(path), "kind": "mcp", "action": "error", "old": old, "new": old,
|
|
77
|
-
"error": "top level is not a JSON object; left unchanged"}
|
|
78
|
-
servers = data.get("mcpServers")
|
|
79
|
-
if not isinstance(servers, dict):
|
|
80
|
-
servers = {}
|
|
81
|
-
if remove:
|
|
82
|
-
if "cg" not in servers:
|
|
83
|
-
return {"path": str(path), "kind": "mcp", "action": "noop", "old": old, "new": old}
|
|
84
|
-
servers = {k: v for k, v in servers.items() if k != "cg"}
|
|
85
|
-
action = "remove"
|
|
86
|
-
else:
|
|
87
|
-
action = "update" if "cg" in servers else "insert"
|
|
88
|
-
servers = {**servers, "cg": MCP_ENTRY}
|
|
89
|
-
data = {**data, "mcpServers": servers}
|
|
90
|
-
new = json.dumps(data, indent=2) + "\n"
|
|
91
|
-
return {"path": str(path), "kind": "mcp", "action": action, "old": old, "new": new}
|
|
64
|
+
kept. The edit affects only that member's text. Returns action noop when there is nothing to
|
|
65
|
+
change, or error when the file is not JSON."""
|
|
66
|
+
from .mcp_install import plan_file
|
|
67
|
+
return plan_file(path, kind="json", path_keys=["mcpServers"], entry=None if remove else MCP_ENTRY,
|
|
68
|
+
remove=remove, delete_empty=False)
|
|
92
69
|
|
|
93
70
|
|
|
94
71
|
def preview(plan: dict) -> str:
|
|
@@ -96,8 +73,11 @@ def preview(plan: dict) -> str:
|
|
|
96
73
|
if plan["action"] == "noop" and plan.get("current"):
|
|
97
74
|
return f"{plan['path']}: no change (block up to date)"
|
|
98
75
|
if plan["action"] == "noop":
|
|
99
|
-
|
|
100
|
-
|
|
76
|
+
if plan["kind"] == "text":
|
|
77
|
+
return f"{plan['path']}: no change (block not present)"
|
|
78
|
+
if plan.get("registered"):
|
|
79
|
+
return f"{plan['path']}: no change (cg already registered)"
|
|
80
|
+
return f"{plan['path']}: no change (no cg entry)"
|
|
101
81
|
if plan["action"] == "error":
|
|
102
82
|
return f"{plan['path']}: {plan['error']}"
|
|
103
83
|
diff = difflib.unified_diff(plan["old"].splitlines(True), plan["new"].splitlines(True),
|
|
@@ -16,7 +16,7 @@ It is modelled with the protocol endpoint model of #31 (epic #29), so the bridge
|
|
|
16
16
|
(android/ ios/ macos/ directories, else Kotlin / Java = android, Swift / ObjC = ios), so `--platform ios`
|
|
17
17
|
drops the Android receivers and `impact` / `reaches` cross the bridge in both directions
|
|
18
18
|
|
|
19
|
-
The send side comes from the language plugins (TypeScript extractor facts,
|
|
19
|
+
The send side comes from the language plugins (TypeScript extractor facts, cg_code_graph/plugins/dart/bridges.py); the
|
|
20
20
|
receive side is a source-text pass over the native files run here, after the language plugins (Java and ObjC have no
|
|
21
21
|
language plugin: their receivers become stub method nodes with attrs.bridge_stub). `finalize` then records per
|
|
22
22
|
endpoint which platforms receive it and the checks: missing_on (sent, received on some mobile targets of the project
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
"""code-graph CLI.
|
|
2
2
|
|
|
3
|
-
python -m
|
|
4
|
-
python -m
|
|
5
|
-
python -m
|
|
6
|
-
python -m
|
|
7
|
-
python -m
|
|
8
|
-
python -m
|
|
9
|
-
python -m
|
|
10
|
-
python -m
|
|
11
|
-
python -m
|
|
12
|
-
python -m
|
|
13
|
-
python -m
|
|
14
|
-
python -m
|
|
15
|
-
python -m
|
|
16
|
-
python -m
|
|
17
|
-
python -m
|
|
18
|
-
python -m
|
|
19
|
-
python -m
|
|
20
|
-
python -m
|
|
21
|
-
python -m
|
|
22
|
-
python -m
|
|
3
|
+
python -m cg_code_graph.cli index <project_root> --db out/x.db [--scip index.scip] [--gates config/x.gates.json]
|
|
4
|
+
python -m cg_code_graph.cli reaches <spec>... --db out/x.db [--min-confidence resolved] [--json] [--no-paths]
|
|
5
|
+
python -m cg_code_graph.cli siblings <symbol> --db ...
|
|
6
|
+
python -m cg_code_graph.cli writers <table> --db ...
|
|
7
|
+
python -m cg_code_graph.cli impact <Class::method> --db ...
|
|
8
|
+
python -m cg_code_graph.cli stats --db ...
|
|
9
|
+
python -m cg_code_graph.cli detect <project_root>
|
|
10
|
+
python -m cg_code_graph.cli link --backend out/api.db --frontend out/web.db --db out/combined.db [--report out/x]
|
|
11
|
+
python -m cg_code_graph.cli downstream <spec> --db out/combined.db (forward: page -> ... -> routes/tables)
|
|
12
|
+
python -m cg_code_graph.cli api-calls <all|unmatched|substring|glob*> --db out/combined.db
|
|
13
|
+
python -m cg_code_graph.cli plan list|load|validate|check|baseline [<name>] --db out/combined.db [--verify] [--summary] [--json]
|
|
14
|
+
python -m cg_code_graph.cli routes --db ... [--writes [TABLE]] [--reaches SPEC...] [--missing NAME] [--unguarded]
|
|
15
|
+
python -m cg_code_graph.cli search <name> --db ... [--kind route]
|
|
16
|
+
python -m cg_code_graph.cli channels [PATTERN] --db ... (who can join, which events publish, which client code listens)
|
|
17
|
+
python -m cg_code_graph.cli tests <spec> --db ... (tests covering a symbol / route / table: direct + transitive)
|
|
18
|
+
python -m cg_code_graph.cli bridges [PATTERN] --db ... [--protocol capacitor] [--unmatched] (web / native bridge calls)
|
|
19
|
+
python -m cg_code_graph.cli external [PATTERN] --db ... [--protocol P] [--source S] [--tls-off] (databases, caches, brokers, mail ... and who reaches them)
|
|
20
|
+
python -m cg_code_graph.cli tools [PATTERN] --db ... [--framework F] [--agent A] [--unmatched] (LLM / MCP tools: handler, tables, agents, checks)
|
|
21
|
+
python -m cg_code_graph.cli protocols [PATTERN] --db ... [--protocol P] [--side send|receive] [--unmatched] [--listeners] (every protocol endpoint: senders, receivers, checks; listening sockets)
|
|
22
|
+
python -m cg_code_graph.cli platforms [summary|divergence] --db ... [--target ios] (platform-specific code, gaps between variants)
|
|
23
23
|
reaches / impact / downstream / path / routes / search take --platform TARGET: only code built for that target
|
|
24
24
|
spec forms: table.column | connection:<name> (glob *) | env:<KEY*> | config:<a.b> | Class.method or Class::method (either
|
|
25
25
|
separator, every language) | Class
|
|
@@ -54,6 +54,27 @@ def _parse_repo(spec: str) -> tuple[str, str, str]:
|
|
|
54
54
|
return name, rest, role
|
|
55
55
|
|
|
56
56
|
|
|
57
|
+
def _add_install_parser(sub, uninstall: bool):
|
|
58
|
+
from .mcp_install import HOSTS
|
|
59
|
+
name = "uninstall" if uninstall else "install"
|
|
60
|
+
help_ = ("remove the cg MCP server entry from a host config" if uninstall else
|
|
61
|
+
"register the cg MCP server (key cg) in a host config; previews and asks first")
|
|
62
|
+
p = sub.add_parser(name, help=help_)
|
|
63
|
+
p.add_argument("--host", action="append", choices=[*HOSTS, "all"],
|
|
64
|
+
help="MCP host (repeatable). Default: hosts already present for this scope")
|
|
65
|
+
g = p.add_mutually_exclusive_group()
|
|
66
|
+
g.add_argument("--project", action="store_true", help="project config (default)")
|
|
67
|
+
g.add_argument("--global", dest="glob", action="store_true", help="user / global config (needs --db)")
|
|
68
|
+
p.add_argument("--dir", default=".", help="project root (default: current directory)")
|
|
69
|
+
p.add_argument("--db", help="graph DB. Default for --project: <dir>/out/graph.db. Required for --global")
|
|
70
|
+
p.add_argument("--tools", help="tool allowlist written as --tools (CG_MCP_TOOLS grammar)")
|
|
71
|
+
p.add_argument("--portable", action="store_true",
|
|
72
|
+
help="write command cg-mcp and --db out/graph.db (for a config committed to git)")
|
|
73
|
+
p.add_argument("--uninstall", action="store_true", help="remove the entry instead of writing it")
|
|
74
|
+
p.add_argument("--dry-run", action="store_true", help="print the exact changes and write nothing")
|
|
75
|
+
p.add_argument("--yes", action="store_true", help="skip the confirmation prompt")
|
|
76
|
+
|
|
77
|
+
|
|
57
78
|
def main(argv=None):
|
|
58
79
|
from . import __version__
|
|
59
80
|
ap = argparse.ArgumentParser(prog="cg")
|
|
@@ -97,9 +118,9 @@ def main(argv=None):
|
|
|
97
118
|
p.add_argument("--dry-run", action="store_true", help="list what would be removed, delete nothing")
|
|
98
119
|
p.add_argument("--json", action="store_true")
|
|
99
120
|
p = sub.add_parser("setup", help="install the Node / PHP / Dart extractor dependencies (into the user cache; "
|
|
100
|
-
"otherwise done on the first index)")
|
|
121
|
+
"otherwise done on the first index). `java` prints the JDK 17+ / scip-java hint")
|
|
101
122
|
p.add_argument("languages", nargs="*", metavar="LANG",
|
|
102
|
-
help="typescript, php, dart (default:
|
|
123
|
+
help="typescript, php, dart, java (default: typescript, php, dart whose toolchain is installed)")
|
|
103
124
|
p.add_argument("--quiet", action="store_true")
|
|
104
125
|
p.add_argument("--prune", action="store_true",
|
|
105
126
|
help="remove extractor installs this version does not use (left by updates that changed a lock "
|
|
@@ -259,6 +280,8 @@ def main(argv=None):
|
|
|
259
280
|
p.add_argument("--mcp-file", help="MCP config path (default: <dir>/.cursor/mcp.json)")
|
|
260
281
|
p.add_argument("--dry-run", action="store_true", help="print the exact changes and write nothing")
|
|
261
282
|
p.add_argument("--yes", action="store_true", help="skip the confirmation prompt")
|
|
283
|
+
_add_install_parser(sub, uninstall=False)
|
|
284
|
+
_add_install_parser(sub, uninstall=True)
|
|
262
285
|
p = sub.add_parser("hooks", help="opt-in: git hooks that refresh the index in the background after commit, checkout and merge")
|
|
263
286
|
p.add_argument("action", choices=["install", "uninstall", "status"])
|
|
264
287
|
p.add_argument("--dir", default=".", help="project root (default: current directory)")
|
|
@@ -347,6 +370,10 @@ def main(argv=None):
|
|
|
347
370
|
except C.CacheError as ex:
|
|
348
371
|
print(f"cg clean: {ex}", file=sys.stderr)
|
|
349
372
|
return 2
|
|
373
|
+
old = C.legacy_root()
|
|
374
|
+
if old is not None:
|
|
375
|
+
print(f"note: the old cache {old} still exists ({C.human(C._size(old))}); "
|
|
376
|
+
"delete it when you no longer need it", file=sys.stderr)
|
|
350
377
|
errors = [] if a.dry_run else C.execute(pl)
|
|
351
378
|
if a.json:
|
|
352
379
|
print(json.dumps({"root": str(pl.root), "dry_run": a.dry_run, "bytes": pl.bytes, "projects": pl.projects,
|
|
@@ -381,9 +408,9 @@ def main(argv=None):
|
|
|
381
408
|
return 0
|
|
382
409
|
if a.cmd == "setup":
|
|
383
410
|
from .doctor import setup
|
|
384
|
-
bad = [x for x in a.languages if x not in ("typescript", "php", "dart")]
|
|
411
|
+
bad = [x for x in a.languages if x not in ("typescript", "php", "dart", "java")]
|
|
385
412
|
if bad:
|
|
386
|
-
print(f"cg setup: unknown language {bad[0]!r} (typescript, php, dart)", file=sys.stderr)
|
|
413
|
+
print(f"cg setup: unknown language {bad[0]!r} (typescript, php, dart, java)", file=sys.stderr)
|
|
387
414
|
return 2
|
|
388
415
|
return setup(a.languages or None, quiet=a.quiet)
|
|
389
416
|
if a.cmd == "coverage":
|
|
@@ -442,6 +469,11 @@ def main(argv=None):
|
|
|
442
469
|
from . import agents as AG
|
|
443
470
|
return AG.run(a.action, root=a.dir, targets=a.target, all_targets=a.all, mcp=a.mcp,
|
|
444
471
|
mcp_file=a.mcp_file, dry_run=a.dry_run, assume_yes=a.yes)
|
|
472
|
+
if a.cmd in ("install", "uninstall"):
|
|
473
|
+
from .mcp_install import run as run_install
|
|
474
|
+
return run_install(a.host, scope="global" if a.glob else "project", root=a.dir, db=a.db,
|
|
475
|
+
tools=a.tools, portable=a.portable, remove=a.cmd == "uninstall" or a.uninstall,
|
|
476
|
+
dry_run=a.dry_run, assume_yes=a.yes)
|
|
445
477
|
if a.cmd == "hooks":
|
|
446
478
|
from . import hooks as HK
|
|
447
479
|
return HK.run(a.action, root=a.dir, db=a.db, dry_run=a.dry_run, assume_yes=a.yes)
|
|
@@ -60,7 +60,7 @@ APP_ROLES = ("backend", "frontend")
|
|
|
60
60
|
KNOWN_KEYS = set(SCHEMA)
|
|
61
61
|
PYTHON_KEYS = SCHEMA["python"]
|
|
62
62
|
VIZ_MODES = ("reaches", "impact", "downstream", "path", "plan")
|
|
63
|
-
# framework plugins of
|
|
63
|
+
# framework plugins of cg_code_graph/indexer.py FRAMEWORK_PLUGINS (frameworks.add / remove also take preset names)
|
|
64
64
|
FRAMEWORK_PLUGIN_NAMES = ("laravel", "nuxt", "django", "fastapi", "flask", "flutter", "nest", "nextjs", "express", "astro")
|
|
65
65
|
|
|
66
66
|
|
|
@@ -371,7 +371,7 @@ def app_pairs(apps: list[dict]) -> list[tuple[dict, dict]]:
|
|
|
371
371
|
|
|
372
372
|
def rust_targets(v, where: str) -> str:
|
|
373
373
|
"""`rust.targets`: extra rust-analyzer runs per target (#56). `auto` (default), `off` / false, or a list of
|
|
374
|
-
platforms / target triples; returned in the
|
|
374
|
+
platforms / target triples; returned in the CG_RUST_TARGETS form."""
|
|
375
375
|
if v is False or (isinstance(v, str) and v.strip().lower() in ("off", "none", "0", "false")):
|
|
376
376
|
return "off"
|
|
377
377
|
if isinstance(v, str) and v.strip().lower() == "auto":
|
|
@@ -466,7 +466,7 @@ def effective(root: str | Path, python_roots: list[str] | None = None, gates: st
|
|
|
466
466
|
row("frameworks", f, f"{fname} frameworks.add" if how == ".cg.yaml" else "detected")
|
|
467
467
|
for f in plan["removed"]:
|
|
468
468
|
row("frameworks", f"{f} (removed)", f"{fname} frameworks.remove")
|
|
469
|
-
row("presets", plan["presets"], "built-in (
|
|
469
|
+
row("presets", plan["presets"], "built-in (cg_code_graph/presets), picked by detection")
|
|
470
470
|
if python_roots:
|
|
471
471
|
row("python.source_roots", [norm_root(r, "--python-root") for r in python_roots], "flag --python-root")
|
|
472
472
|
elif (cfg.get("python") or {}).get("source_roots"):
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"""The per-user cache: where it lives, what is in it, and `cg clean`.
|
|
2
2
|
|
|
3
3
|
Root (one lookup for every user: extractors, SCIP outputs, parse caches, the Swift build directory):
|
|
4
|
-
$
|
|
5
|
-
$XDG_CACHE_HOME/
|
|
4
|
+
$CG_CACHE (older names still work through 0.18.x; see core/env.py), else
|
|
5
|
+
%LOCALAPPDATA%\\cg on Windows, else $XDG_CACHE_HOME/cg, else ~/.cache/cg. The first use of that
|
|
6
|
+
default moves a leftover `codegraph` directory to `cg` and drops `swift-build/` (SwiftPM build
|
|
7
|
+
directories embed absolute paths). An explicit cache path is used as given and is not moved.
|
|
6
8
|
|
|
7
9
|
Layout below the root (`v<N>` is fsutil.CACHE_VERSION, `<rkey>` the first 12 hex digits of sha256 of the resolved
|
|
8
10
|
project root):
|
|
@@ -26,11 +28,17 @@ import hashlib
|
|
|
26
28
|
import os
|
|
27
29
|
import re
|
|
28
30
|
import shutil
|
|
31
|
+
import sys
|
|
29
32
|
import time
|
|
30
33
|
from dataclasses import dataclass, field
|
|
34
|
+
import pathlib
|
|
31
35
|
from pathlib import Path
|
|
32
36
|
|
|
33
|
-
from . import fsutil
|
|
37
|
+
from . import env, fsutil
|
|
38
|
+
|
|
39
|
+
# The concrete class for this process. pathlib.Path follows os.name at each call, so a test
|
|
40
|
+
# that sets os.name to "nt" on another platform cannot construct Path(); this class still can.
|
|
41
|
+
_Path = pathlib.WindowsPath if os.name == "nt" else pathlib.PosixPath
|
|
34
42
|
|
|
35
43
|
try:
|
|
36
44
|
import fcntl
|
|
@@ -45,14 +53,106 @@ class CacheError(Exception):
|
|
|
45
53
|
pass
|
|
46
54
|
|
|
47
55
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
56
|
+
_migrated = False
|
|
57
|
+
_legacy_failure: str | None = None
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _default_root() -> Path:
|
|
61
|
+
"""The cache root when no cache override is set (not created)."""
|
|
53
62
|
if os.name == "nt" and os.environ.get("LOCALAPPDATA"):
|
|
54
|
-
return
|
|
55
|
-
return
|
|
63
|
+
return _Path(os.environ["LOCALAPPDATA"]) / "cg"
|
|
64
|
+
return _Path(os.environ.get("XDG_CACHE_HOME") or _Path.home() / ".cache") / "cg"
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _legacy_path(new: Path) -> Path:
|
|
68
|
+
"""`<parent>/codegraph`. A root with an empty final component cannot use `with_name`."""
|
|
69
|
+
try:
|
|
70
|
+
return new.with_name("codegraph")
|
|
71
|
+
except ValueError:
|
|
72
|
+
return new.parent / "codegraph"
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def _seen(path: Path, *, directory: bool) -> bool | None:
|
|
76
|
+
"""True or False, or None when the path cannot be stat'ed (unreadable parent)."""
|
|
77
|
+
try:
|
|
78
|
+
return path.is_dir() if directory else path.exists()
|
|
79
|
+
except OSError:
|
|
80
|
+
return None
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _remember_move_failure(legacy: Path, new: Path, ex: object) -> None:
|
|
84
|
+
"""Leave a fresh `new` when the move did not happen, and a note for `cg doctor`."""
|
|
85
|
+
global _legacy_failure
|
|
86
|
+
try:
|
|
87
|
+
new.mkdir(parents=True, exist_ok=True)
|
|
88
|
+
except OSError:
|
|
89
|
+
pass
|
|
90
|
+
_legacy_failure = f"could not move {legacy} to {new} ({ex})"
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
def _migrate_legacy(new: Path) -> None:
|
|
94
|
+
"""Move `<parent>/codegraph` to `new` once per process. No override is in effect.
|
|
95
|
+
|
|
96
|
+
A target that already exists is left as it is. An unreadable legacy directory, or a
|
|
97
|
+
rename that loses a race to another process, does not clobber `new` and does not raise.
|
|
98
|
+
The one status line goes to stderr.
|
|
99
|
+
"""
|
|
100
|
+
global _migrated
|
|
101
|
+
if _migrated:
|
|
102
|
+
return
|
|
103
|
+
_migrated = True
|
|
104
|
+
legacy = _legacy_path(new)
|
|
105
|
+
legacy_is_dir = _seen(legacy, directory=True)
|
|
106
|
+
new_exists = _seen(new, directory=False)
|
|
107
|
+
if new_exists:
|
|
108
|
+
return
|
|
109
|
+
if legacy_is_dir is None or new_exists is None:
|
|
110
|
+
_remember_move_failure(legacy, new, "unreadable")
|
|
111
|
+
return
|
|
112
|
+
if not legacy_is_dir:
|
|
113
|
+
return
|
|
114
|
+
try:
|
|
115
|
+
os.rename(legacy, new)
|
|
116
|
+
except OSError as ex:
|
|
117
|
+
if _seen(new, directory=False):
|
|
118
|
+
return
|
|
119
|
+
_remember_move_failure(legacy, new, ex)
|
|
120
|
+
return
|
|
121
|
+
print(f"cg: moved the cache {legacy} -> {new}", file=sys.stderr)
|
|
122
|
+
shutil.rmtree(new / "swift-build", ignore_errors=True)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def root() -> Path:
|
|
126
|
+
"""The cache root (not created, except when a failed move leaves a fresh directory)."""
|
|
127
|
+
override = env.get("CACHE")
|
|
128
|
+
if override:
|
|
129
|
+
return _Path(override).expanduser()
|
|
130
|
+
new = _default_root()
|
|
131
|
+
_migrate_legacy(new)
|
|
132
|
+
return new
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def legacy_root() -> Path | None:
|
|
136
|
+
"""The previous `codegraph` cache directory, when it is still there."""
|
|
137
|
+
legacy = _legacy_path(_default_root())
|
|
138
|
+
try:
|
|
139
|
+
return legacy if legacy.is_dir() else None
|
|
140
|
+
except OSError:
|
|
141
|
+
return None
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def legacy_note() -> str | None:
|
|
145
|
+
"""Why the automatic move did not happen, when `root` tried and failed."""
|
|
146
|
+
return _legacy_failure
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def legacy_report() -> dict | None:
|
|
150
|
+
"""Path, size and move-failure note for doctor, or None when there is nothing to say."""
|
|
151
|
+
path = legacy_root()
|
|
152
|
+
note = legacy_note()
|
|
153
|
+
if path is None and not note:
|
|
154
|
+
return None
|
|
155
|
+
return {"path": str(path) if path else None, "size": _size(path) if path else 0, "note": note}
|
|
56
156
|
|
|
57
157
|
|
|
58
158
|
def subdir(name: str, create: bool = False) -> Path:
|
|
@@ -96,8 +196,8 @@ def check_root(r: Path | None = None) -> Path:
|
|
|
96
196
|
raise CacheError(f"cannot resolve the cache root {r}: {e}")
|
|
97
197
|
home = Path.home().resolve()
|
|
98
198
|
if rr == Path(rr.anchor) or rr == home or rr in home.parents:
|
|
99
|
-
raise CacheError(f"refusing to clean: the cache root resolves to {rr} (set
|
|
100
|
-
"its own, e.g. ~/.cache/
|
|
199
|
+
raise CacheError(f"refusing to clean: the cache root resolves to {rr} (set CG_CACHE to a directory of "
|
|
200
|
+
"its own, e.g. ~/.cache/cg)")
|
|
101
201
|
return rr
|
|
102
202
|
|
|
103
203
|
|
|
@@ -139,7 +239,7 @@ def _size(p: Path) -> int:
|
|
|
139
239
|
|
|
140
240
|
|
|
141
241
|
def _tmp_age_limit() -> float:
|
|
142
|
-
return float(
|
|
242
|
+
return float(env.get("INDEXER_TIMEOUT", "3600")) + 600
|
|
143
243
|
|
|
144
244
|
|
|
145
245
|
def entries(r: Path | None = None) -> list[Entry]:
|
|
@@ -195,11 +295,16 @@ def entries(r: Path | None = None) -> list[Entry]:
|
|
|
195
295
|
e.rkey, e.stale = n[:12], "name from an older cache layout (no cache version)"
|
|
196
296
|
elif name == "swift-build":
|
|
197
297
|
e.swift_key = n
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
298
|
+
import json
|
|
299
|
+
v = None
|
|
300
|
+
for stamp_name in ("cg-stamp.json", "codegraph-stamp.json"):
|
|
301
|
+
try:
|
|
302
|
+
parsed = json.loads((p / stamp_name).read_text())
|
|
303
|
+
except (OSError, ValueError, AttributeError):
|
|
304
|
+
continue
|
|
305
|
+
if isinstance(parsed, dict) and parsed.get("cache_version") is not None:
|
|
306
|
+
v = parsed.get("cache_version")
|
|
307
|
+
break
|
|
203
308
|
if v is not None and v != cur:
|
|
204
309
|
e.stale = f"cache version {v} (current {cur})"
|
|
205
310
|
elif name == "projects":
|
|
@@ -2,9 +2,12 @@
|
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
|
|
4
4
|
import json
|
|
5
|
+
import os
|
|
5
6
|
import re
|
|
6
7
|
from pathlib import Path
|
|
7
8
|
|
|
9
|
+
from ..presets import skip_dirs
|
|
10
|
+
|
|
8
11
|
MARKERS = {
|
|
9
12
|
# language: files/globs that indicate it
|
|
10
13
|
"php": ["composer.json", "artisan"],
|
|
@@ -80,4 +83,34 @@ def detect(root: Path) -> dict:
|
|
|
80
83
|
fw[extra] = {}
|
|
81
84
|
if "typescript" in deps:
|
|
82
85
|
langs.setdefault("typescript", ["package.json:typescript"])
|
|
86
|
+
if _spring_build(root):
|
|
87
|
+
fw["spring"] = {}
|
|
83
88
|
return {"languages": langs, "frameworks": fw}
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _spring_build(root: Path) -> bool:
|
|
92
|
+
"""Spring Boot Gradle plugin or a ``spring-boot-starter-*`` dependency in Gradle / Maven files.
|
|
93
|
+
|
|
94
|
+
The root build file and one module level (``app/build.gradle.kts``). Deeper trees stay out so a
|
|
95
|
+
monorepo's example apps do not mark the repository root.
|
|
96
|
+
"""
|
|
97
|
+
names = {"build.gradle", "build.gradle.kts", "pom.xml"}
|
|
98
|
+
rx = re.compile(r"org\.springframework\.boot|spring-boot-starter(?:-[\w.-]+)?")
|
|
99
|
+
skip = skip_dirs("common") | skip_dirs("common", "scan_skip_dirs")
|
|
100
|
+
for dp, dn, fn in os.walk(root):
|
|
101
|
+
rel = os.path.relpath(dp, root)
|
|
102
|
+
depth = 0 if rel == "." else len(Path(rel).parts)
|
|
103
|
+
if depth > 1:
|
|
104
|
+
dn[:] = []
|
|
105
|
+
continue
|
|
106
|
+
dn[:] = [d for d in dn if d not in skip and not d.startswith(".")]
|
|
107
|
+
for name in fn:
|
|
108
|
+
if name not in names:
|
|
109
|
+
continue
|
|
110
|
+
try:
|
|
111
|
+
text = (Path(dp) / name).read_text(errors="replace")[:200_000]
|
|
112
|
+
except OSError:
|
|
113
|
+
continue
|
|
114
|
+
if rx.search(text):
|
|
115
|
+
return True
|
|
116
|
+
return False
|