cg-code-graph 0.11.0__tar.gz → 0.13.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.13.0/PKG-INFO +84 -0
- cg_code_graph-0.13.0/README.md +60 -0
- cg_code_graph-0.13.0/cg_code_graph.egg-info/PKG-INFO +84 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/cg_code_graph.egg-info/SOURCES.txt +43 -1
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/__init__.py +1 -1
- cg_code_graph-0.13.0/codegraph/agent_rules.py +57 -0
- cg_code_graph-0.13.0/codegraph/agents.py +150 -0
- cg_code_graph-0.13.0/codegraph/android_ipc.py +400 -0
- cg_code_graph-0.13.0/codegraph/apple_ipc.py +184 -0
- cg_code_graph-0.13.0/codegraph/apps.py +88 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/blindspots.py +25 -0
- cg_code_graph-0.13.0/codegraph/brokers.py +1460 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/cli.py +66 -5
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/config.py +16 -4
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/model.py +2 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/coverage.py +2 -1
- cg_code_graph-0.13.0/codegraph/dart_isolates.py +149 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/external.py +519 -45
- cg_code_graph-0.13.0/codegraph/graphql.py +1040 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/indexer.py +72 -0
- cg_code_graph-0.13.0/codegraph/jobs.py +997 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/link.py +223 -75
- cg_code_graph-0.13.0/codegraph/local_ipc.py +676 -0
- cg_code_graph-0.13.0/codegraph/local_sockets.py +462 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/mcp_server.py +27 -6
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/django/plugin.py +34 -2
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/django/urls.py +134 -1
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/express/plugin.py +8 -1
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/kotlin/exact.py +33 -5
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/kotlin/plugin.py +340 -10
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/laravel/plugin.py +109 -12
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/nest/plugin.py +76 -3
- cg_code_graph-0.13.0/codegraph/plugins/nuxt/plugin.py +923 -0
- cg_code_graph-0.13.0/codegraph/plugins/php/external.py +191 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/php/extractor/extract.php +212 -15
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/php/plugin.py +3 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/external.py +61 -1
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/socketio.py +11 -1
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/rust/plugin.py +24 -3
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/swift/plugin.py +9 -8
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/ts/extractor/extract.mjs +317 -5
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/ts/extractor/fw.mjs +2 -1
- cg_code_graph-0.13.0/codegraph/plugins/ts/nav.py +252 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/ts/plugin.py +143 -2
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/tsweb/common.py +4 -3
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/tsweb/data.py +236 -3
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/django.yaml +5 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/process_runs.py +48 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/protocols/__init__.py +65 -5
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/protocols/builtin.py +72 -5
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/protocols/matchers.py +43 -2
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/protocols/view.py +65 -11
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/query.py +327 -27
- cg_code_graph-0.13.0/codegraph/realtime_events.py +470 -0
- cg_code_graph-0.13.0/codegraph/realtime_native.py +267 -0
- cg_code_graph-0.13.0/codegraph/realtime_ws.py +362 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/routes.py +16 -2
- cg_code_graph-0.13.0/codegraph/sdk_systems.py +963 -0
- cg_code_graph-0.13.0/codegraph/webhooks.py +598 -0
- cg_code_graph-0.13.0/tests/test_agents_install.py +123 -0
- cg_code_graph-0.13.0/tests/test_agents_md.py +17 -0
- cg_code_graph-0.13.0/tests/test_android_ipc.py +123 -0
- cg_code_graph-0.13.0/tests/test_apple_ipc.py +55 -0
- cg_code_graph-0.13.0/tests/test_brokers.py +166 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_config_extras.py +9 -9
- cg_code_graph-0.13.0/tests/test_dart_isolates.py +65 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_django_flutter.py +112 -0
- cg_code_graph-0.13.0/tests/test_docs_links.py +57 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_external.py +254 -0
- cg_code_graph-0.13.0/tests/test_graphql.py +148 -0
- cg_code_graph-0.13.0/tests/test_jobs.py +200 -0
- cg_code_graph-0.13.0/tests/test_js_refs.py +54 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_kotlin.py +19 -1
- cg_code_graph-0.13.0/tests/test_laravel_resources.py +138 -0
- cg_code_graph-0.13.0/tests/test_local_ipc.py +119 -0
- cg_code_graph-0.13.0/tests/test_local_sockets.py +104 -0
- cg_code_graph-0.13.0/tests/test_nuxt_import_dirs.py +136 -0
- cg_code_graph-0.13.0/tests/test_plain_js.py +76 -0
- cg_code_graph-0.13.0/tests/test_process_ipc.py +72 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_protocols.py +8 -1
- cg_code_graph-0.13.0/tests/test_realtime.py +117 -0
- cg_code_graph-0.13.0/tests/test_realtime_native.py +90 -0
- cg_code_graph-0.13.0/tests/test_route_tables.py +186 -0
- cg_code_graph-0.13.0/tests/test_sdk_external.py +102 -0
- cg_code_graph-0.13.0/tests/test_snippet.py +106 -0
- cg_code_graph-0.13.0/tests/test_vue_nav.py +122 -0
- cg_code_graph-0.13.0/tests/test_webhooks.py +134 -0
- cg_code_graph-0.13.0/tests/test_websockets.py +142 -0
- cg_code_graph-0.13.0/tests/test_workspace_link.py +201 -0
- cg_code_graph-0.11.0/PKG-INFO +0 -679
- cg_code_graph-0.11.0/README.md +0 -655
- cg_code_graph-0.11.0/cg_code_graph.egg-info/PKG-INFO +0 -679
- cg_code_graph-0.11.0/codegraph/apps.py +0 -76
- cg_code_graph-0.11.0/codegraph/plugins/nuxt/plugin.py +0 -308
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/LICENSE +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/MANIFEST.in +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/cg_code_graph.egg-info/dependency_links.txt +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/cg_code_graph.egg-info/entry_points.txt +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/cg_code_graph.egg-info/requires.txt +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/cg_code_graph.egg-info/top_level.txt +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/aitools.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/bridges.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/concepts.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/cache.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/detect.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/extractors.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/fsutil.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/generated.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/paths.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/plugin.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/store.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/core/syntax_errors.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/doctor.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/lint_async.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/parity.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/parity_structure.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/payload.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plans.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/platform_scan.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/platforms.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/cfamily/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/cfamily/plugin.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/cfamily/syntax.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/dart/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/dart/bridges.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/dart/extractor/bin/extract.dart +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/dart/extractor/pubspec.lock +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/dart/extractor/pubspec.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/dart/http.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/dart/models.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/dart/plugin.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/dart/program.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/django/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/django/extras.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/django/models.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/django/schemas.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/django/shapes.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/express/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/flutter/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/flutter/plugin.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/kotlin/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/kotlin/reparse.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/laravel/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/laravel/broadcast.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/laravel/tests.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/laravel/values.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/native/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/native/gates.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/native/runner.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/native/scipread.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/native/ts.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/nest/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/nextjs/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/nextjs/plugin.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/nuxt/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/php/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/php/extractor/composer.json +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/php/extractor/composer.lock +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/php/gating.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/php/strings.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/aitools.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/fields.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/plugin.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/refs.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/roots.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/subproc.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/tests.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/python/values.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/pyweb/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/pyweb/plugin.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/pyweb/values.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/rust/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/rust/cargo.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/rust/syntax.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/scip/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/scip/importer.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/scip/scip.proto +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/scip/scip_pb2.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/stubs/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/stubs/plugins.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/swift/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/swift/baseurl.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/swift/exact.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/swift/indexstore.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/swift/packages.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/ts/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/ts/baseurl.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/ts/extractor/package-lock.json +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/ts/extractor/package.json +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/plugins/tsweb/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/c_cpp.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/common.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/dart.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/django-ninja.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/djangorestframework.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/express.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/kotlin.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/laravel.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/nest.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/nextjs.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/nuxt.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/php.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/python.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/rust.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/swift.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/presets/typescript.yaml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/realtime.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/roundtrip.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/rpc.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/sockets.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/starters.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/tests_index.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/udp_apps.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/__init__.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/graph.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/server.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/static/app.css +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/static/app.js +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/static/index.html +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/static/layered.js +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/static/vendor/VERSIONS.txt +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/static/vendor/cose-base.js +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/static/vendor/cytoscape-fcose.js +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/static/vendor/cytoscape.min.js +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/static/vendor/layout-base.js +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/tools/package-lock.json +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/tools/package.json +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/viz/tools/shoot.mjs +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/codegraph/xcode.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/pyproject.toml +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/setup.cfg +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_ai_tools.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_bridges.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_bridges_pigeon_monorepo.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_cache_clean.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_cache_invalidation.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_channels_tests.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_cli_output.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_completeness.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_coverage.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_coverage_ts_hint.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_dispatch_interfaces.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_enum_constants.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_gating.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_generated.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_impact_overrides.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_index_isolation.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_inherited_overrides.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_kotlin_binding.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_kotlin_exact.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_kotlin_fields.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_kotlin_mixed.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_kotlin_nav_consts.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_kotlin_props.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_laravel_determinism.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_lint_async.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_mcp.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_mcp_index.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_native_cfamily.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_native_concurrency.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_native_rust.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_nuxt_rootsrc.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_packaging.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_parity.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_parity_structure.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_php_props.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_plans.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_platform_gaps.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_platform_type_variants.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_platforms.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_platforms_apple.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_presets_config.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_process_runs.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_app_tests_module.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_collection_chains.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_compat.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_entry_refs.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_fields.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_infer_cycles.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_roots.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_subprocess_tests.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_tests.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_web_hosts.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_web_routes.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_python_web_routes_more.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_roundtrip.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_routes_search_explain.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_rpc.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_scip_health.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_sockets.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_starters_budget.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_binding.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_exact.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_facts.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_fields.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_modules.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_more.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_nav_values.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_parse_errors.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_props.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_sdk.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_testing.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_swift_values.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_tests_scope.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_ts_fields.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_ts_fields_js_vue.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_ts_file_specs.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_ts_frameworks.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_ts_nuxt.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_values.py +0 -0
- {cg_code_graph-0.11.0 → cg_code_graph-0.13.0}/tests/test_viz.py +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cg-code-graph
|
|
3
|
+
Version: 0.13.0
|
|
4
|
+
Summary: cg: a code graph of routes, calls, data access and platform boundaries for agents and humans (CLI + MCP server)
|
|
5
|
+
Author: cyberchronos00
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cyberchronos00/code-graph
|
|
8
|
+
Project-URL: Changelog, https://github.com/cyberchronos00/code-graph/blob/main/CHANGELOG.md
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: mcp>=2.2
|
|
13
|
+
Requires-Dist: pyyaml>=6
|
|
14
|
+
Requires-Dist: protobuf>=4.21
|
|
15
|
+
Requires-Dist: tree-sitter>=0.23
|
|
16
|
+
Requires-Dist: tree-sitter-rust>=0.23
|
|
17
|
+
Requires-Dist: tree-sitter-c>=0.23
|
|
18
|
+
Requires-Dist: tree-sitter-cpp>=0.23
|
|
19
|
+
Requires-Dist: tree-sitter-kotlin>=1.0
|
|
20
|
+
Requires-Dist: tree-sitter-swift<0.7.4,>=0.6
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# code-graph
|
|
26
|
+
|
|
27
|
+
**A deterministic dependency graph for Laravel, Django, FastAPI, Flask, NestJS, Next.js, Express, Nuxt, Flutter, Rust, C and C++ codebases, so you (and your AI agent) can see everything a change touches before you make it.**
|
|
28
|
+
|
|
29
|
+
Ask "what depends on this table, connection, config key or method?" and get every caller, route, command and page that reaches it, each hop backed by `file:line` evidence. It runs locally on your source files. Answers are exact, deterministic and reproducible: the graph is built from parsers and the type checker, with no LLM in the graph. BloodHound-style: you walk real paths instead of grepping names.
|
|
30
|
+
|
|
31
|
+
> **Status:** beta. Laravel (PHP), Django, FastAPI / Starlette and Flask (Python), TypeScript/JavaScript (Nuxt/Vue, NestJS, Next.js, Express/Fastify/Koa/Hono), Flutter (Dart), Rust, C and C++ are supported natively; other languages can be imported through SCIP.
|
|
32
|
+
|
|
33
|
+
## Documentation
|
|
34
|
+
|
|
35
|
+
**[code-graph docs](https://code-graph.cyberchronos00.workers.dev/)** — install, CLI, MCP, architecture, schema, languages and limitations.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
`cg` is a user-level tool (no sudo, no checkout). The PyPI package is [`cg-code-graph`](https://pypi.org/project/cg-code-graph/); the commands are `cg` and `cg-mcp`.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pipx install cg-code-graph # or: uv tool install cg-code-graph
|
|
43
|
+
# or the script (also installs exact-mode tools with --with c,rust,...):
|
|
44
|
+
# curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
|
|
45
|
+
# or the latest commit: uv tool install git+https://github.com/cyberchronos00/code-graph
|
|
46
|
+
cg doctor # what indexes exact / heuristic on this machine
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Update with `uv tool upgrade cg-code-graph`, `pipx upgrade cg-code-graph` or `install.sh --update`. Caches live under `~/.cache/codegraph`; `cg clean` removes them. Windows, options and per-language toolchains: [install](https://code-graph.cyberchronos00.workers.dev/).
|
|
50
|
+
|
|
51
|
+
## Quickstart
|
|
52
|
+
|
|
53
|
+
Clone the repo for the bundled sample apps (a Laravel API and a Nuxt web app). Python 3.11+. PHP 8.2+ and Composer for the Laravel sample; Node.js 20+ for the TypeScript samples.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
git clone https://github.com/cyberchronos00/code-graph.git && cd code-graph
|
|
57
|
+
mkdir -p out
|
|
58
|
+
cg index examples/bookstore-api --name bookstore-api --gates examples/bookstore.gates.json --db out/api.db
|
|
59
|
+
cg index examples/bookstore-web --name bookstore-web --db out/web.db
|
|
60
|
+
cg link --backend out/api.db --frontend out/web.db \
|
|
61
|
+
--backend-name bookstore-api --frontend-name bookstore-web --db out/graph.db
|
|
62
|
+
|
|
63
|
+
cg reaches connection:warehouse table:warehouse_stock --db out/graph.db
|
|
64
|
+
cg impact StockService::reserve --db out/graph.db
|
|
65
|
+
cg path page:/reports/:id table:orders --db out/graph.db
|
|
66
|
+
cg plan check preorders --plans-dir examples/plans --db out/graph.db
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
A workspace `.cg.yaml` can list several apps, including checkouts outside that directory, and `cg index` builds one combined graph. `cg link --repo` merges graphs you already indexed. Other samples in `examples/` (Nest, Next, Express, Django, Flutter, Rust, C, C++) index the same way. Queries, MCP (`cg-mcp --db out/graph.db`) and `cg serve` are in the [docs](https://code-graph.cyberchronos00.workers.dev/).
|
|
70
|
+
|
|
71
|
+
## Preview
|
|
72
|
+
|
|
73
|
+
[](docs/media/cg-view-demo.mp4)
|
|
74
|
+
|
|
75
|
+
[](docs/media/cg-terminal-demo.mp4)
|
|
76
|
+
|
|
77
|
+
More recordings (setup, visual view, agent over MCP): [docs/media/](docs/media).
|
|
78
|
+
|
|
79
|
+
## Links
|
|
80
|
+
|
|
81
|
+
- [Documentation](https://code-graph.cyberchronos00.workers.dev/)
|
|
82
|
+
- [PyPI: cg-code-graph](https://pypi.org/project/cg-code-graph/)
|
|
83
|
+
- [GitHub releases](https://github.com/cyberchronos00/code-graph/releases)
|
|
84
|
+
- [Changelog](CHANGELOG.md) · [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md) · [License: MIT](LICENSE)
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# code-graph
|
|
2
|
+
|
|
3
|
+
**A deterministic dependency graph for Laravel, Django, FastAPI, Flask, NestJS, Next.js, Express, Nuxt, Flutter, Rust, C and C++ codebases, so you (and your AI agent) can see everything a change touches before you make it.**
|
|
4
|
+
|
|
5
|
+
Ask "what depends on this table, connection, config key or method?" and get every caller, route, command and page that reaches it, each hop backed by `file:line` evidence. It runs locally on your source files. Answers are exact, deterministic and reproducible: the graph is built from parsers and the type checker, with no LLM in the graph. BloodHound-style: you walk real paths instead of grepping names.
|
|
6
|
+
|
|
7
|
+
> **Status:** beta. Laravel (PHP), Django, FastAPI / Starlette and Flask (Python), TypeScript/JavaScript (Nuxt/Vue, NestJS, Next.js, Express/Fastify/Koa/Hono), Flutter (Dart), Rust, C and C++ are supported natively; other languages can be imported through SCIP.
|
|
8
|
+
|
|
9
|
+
## Documentation
|
|
10
|
+
|
|
11
|
+
**[code-graph docs](https://code-graph.cyberchronos00.workers.dev/)** — install, CLI, MCP, architecture, schema, languages and limitations.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
`cg` is a user-level tool (no sudo, no checkout). The PyPI package is [`cg-code-graph`](https://pypi.org/project/cg-code-graph/); the commands are `cg` and `cg-mcp`.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pipx install cg-code-graph # or: uv tool install cg-code-graph
|
|
19
|
+
# or the script (also installs exact-mode tools with --with c,rust,...):
|
|
20
|
+
# curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
|
|
21
|
+
# or the latest commit: uv tool install git+https://github.com/cyberchronos00/code-graph
|
|
22
|
+
cg doctor # what indexes exact / heuristic on this machine
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Update with `uv tool upgrade cg-code-graph`, `pipx upgrade cg-code-graph` or `install.sh --update`. Caches live under `~/.cache/codegraph`; `cg clean` removes them. Windows, options and per-language toolchains: [install](https://code-graph.cyberchronos00.workers.dev/).
|
|
26
|
+
|
|
27
|
+
## Quickstart
|
|
28
|
+
|
|
29
|
+
Clone the repo for the bundled sample apps (a Laravel API and a Nuxt web app). Python 3.11+. PHP 8.2+ and Composer for the Laravel sample; Node.js 20+ for the TypeScript samples.
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
git clone https://github.com/cyberchronos00/code-graph.git && cd code-graph
|
|
33
|
+
mkdir -p out
|
|
34
|
+
cg index examples/bookstore-api --name bookstore-api --gates examples/bookstore.gates.json --db out/api.db
|
|
35
|
+
cg index examples/bookstore-web --name bookstore-web --db out/web.db
|
|
36
|
+
cg link --backend out/api.db --frontend out/web.db \
|
|
37
|
+
--backend-name bookstore-api --frontend-name bookstore-web --db out/graph.db
|
|
38
|
+
|
|
39
|
+
cg reaches connection:warehouse table:warehouse_stock --db out/graph.db
|
|
40
|
+
cg impact StockService::reserve --db out/graph.db
|
|
41
|
+
cg path page:/reports/:id table:orders --db out/graph.db
|
|
42
|
+
cg plan check preorders --plans-dir examples/plans --db out/graph.db
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
A workspace `.cg.yaml` can list several apps, including checkouts outside that directory, and `cg index` builds one combined graph. `cg link --repo` merges graphs you already indexed. Other samples in `examples/` (Nest, Next, Express, Django, Flutter, Rust, C, C++) index the same way. Queries, MCP (`cg-mcp --db out/graph.db`) and `cg serve` are in the [docs](https://code-graph.cyberchronos00.workers.dev/).
|
|
46
|
+
|
|
47
|
+
## Preview
|
|
48
|
+
|
|
49
|
+
[](docs/media/cg-view-demo.mp4)
|
|
50
|
+
|
|
51
|
+
[](docs/media/cg-terminal-demo.mp4)
|
|
52
|
+
|
|
53
|
+
More recordings (setup, visual view, agent over MCP): [docs/media/](docs/media).
|
|
54
|
+
|
|
55
|
+
## Links
|
|
56
|
+
|
|
57
|
+
- [Documentation](https://code-graph.cyberchronos00.workers.dev/)
|
|
58
|
+
- [PyPI: cg-code-graph](https://pypi.org/project/cg-code-graph/)
|
|
59
|
+
- [GitHub releases](https://github.com/cyberchronos00/code-graph/releases)
|
|
60
|
+
- [Changelog](CHANGELOG.md) · [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md) · [License: MIT](LICENSE)
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cg-code-graph
|
|
3
|
+
Version: 0.13.0
|
|
4
|
+
Summary: cg: a code graph of routes, calls, data access and platform boundaries for agents and humans (CLI + MCP server)
|
|
5
|
+
Author: cyberchronos00
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/cyberchronos00/code-graph
|
|
8
|
+
Project-URL: Changelog, https://github.com/cyberchronos00/code-graph/blob/main/CHANGELOG.md
|
|
9
|
+
Requires-Python: >=3.11
|
|
10
|
+
Description-Content-Type: text/markdown
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Requires-Dist: mcp>=2.2
|
|
13
|
+
Requires-Dist: pyyaml>=6
|
|
14
|
+
Requires-Dist: protobuf>=4.21
|
|
15
|
+
Requires-Dist: tree-sitter>=0.23
|
|
16
|
+
Requires-Dist: tree-sitter-rust>=0.23
|
|
17
|
+
Requires-Dist: tree-sitter-c>=0.23
|
|
18
|
+
Requires-Dist: tree-sitter-cpp>=0.23
|
|
19
|
+
Requires-Dist: tree-sitter-kotlin>=1.0
|
|
20
|
+
Requires-Dist: tree-sitter-swift<0.7.4,>=0.6
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
23
|
+
Dynamic: license-file
|
|
24
|
+
|
|
25
|
+
# code-graph
|
|
26
|
+
|
|
27
|
+
**A deterministic dependency graph for Laravel, Django, FastAPI, Flask, NestJS, Next.js, Express, Nuxt, Flutter, Rust, C and C++ codebases, so you (and your AI agent) can see everything a change touches before you make it.**
|
|
28
|
+
|
|
29
|
+
Ask "what depends on this table, connection, config key or method?" and get every caller, route, command and page that reaches it, each hop backed by `file:line` evidence. It runs locally on your source files. Answers are exact, deterministic and reproducible: the graph is built from parsers and the type checker, with no LLM in the graph. BloodHound-style: you walk real paths instead of grepping names.
|
|
30
|
+
|
|
31
|
+
> **Status:** beta. Laravel (PHP), Django, FastAPI / Starlette and Flask (Python), TypeScript/JavaScript (Nuxt/Vue, NestJS, Next.js, Express/Fastify/Koa/Hono), Flutter (Dart), Rust, C and C++ are supported natively; other languages can be imported through SCIP.
|
|
32
|
+
|
|
33
|
+
## Documentation
|
|
34
|
+
|
|
35
|
+
**[code-graph docs](https://code-graph.cyberchronos00.workers.dev/)** — install, CLI, MCP, architecture, schema, languages and limitations.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
`cg` is a user-level tool (no sudo, no checkout). The PyPI package is [`cg-code-graph`](https://pypi.org/project/cg-code-graph/); the commands are `cg` and `cg-mcp`.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pipx install cg-code-graph # or: uv tool install cg-code-graph
|
|
43
|
+
# or the script (also installs exact-mode tools with --with c,rust,...):
|
|
44
|
+
# curl -fsSL https://raw.githubusercontent.com/cyberchronos00/code-graph/main/install.sh | sh
|
|
45
|
+
# or the latest commit: uv tool install git+https://github.com/cyberchronos00/code-graph
|
|
46
|
+
cg doctor # what indexes exact / heuristic on this machine
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
Update with `uv tool upgrade cg-code-graph`, `pipx upgrade cg-code-graph` or `install.sh --update`. Caches live under `~/.cache/codegraph`; `cg clean` removes them. Windows, options and per-language toolchains: [install](https://code-graph.cyberchronos00.workers.dev/).
|
|
50
|
+
|
|
51
|
+
## Quickstart
|
|
52
|
+
|
|
53
|
+
Clone the repo for the bundled sample apps (a Laravel API and a Nuxt web app). Python 3.11+. PHP 8.2+ and Composer for the Laravel sample; Node.js 20+ for the TypeScript samples.
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
git clone https://github.com/cyberchronos00/code-graph.git && cd code-graph
|
|
57
|
+
mkdir -p out
|
|
58
|
+
cg index examples/bookstore-api --name bookstore-api --gates examples/bookstore.gates.json --db out/api.db
|
|
59
|
+
cg index examples/bookstore-web --name bookstore-web --db out/web.db
|
|
60
|
+
cg link --backend out/api.db --frontend out/web.db \
|
|
61
|
+
--backend-name bookstore-api --frontend-name bookstore-web --db out/graph.db
|
|
62
|
+
|
|
63
|
+
cg reaches connection:warehouse table:warehouse_stock --db out/graph.db
|
|
64
|
+
cg impact StockService::reserve --db out/graph.db
|
|
65
|
+
cg path page:/reports/:id table:orders --db out/graph.db
|
|
66
|
+
cg plan check preorders --plans-dir examples/plans --db out/graph.db
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
A workspace `.cg.yaml` can list several apps, including checkouts outside that directory, and `cg index` builds one combined graph. `cg link --repo` merges graphs you already indexed. Other samples in `examples/` (Nest, Next, Express, Django, Flutter, Rust, C, C++) index the same way. Queries, MCP (`cg-mcp --db out/graph.db`) and `cg serve` are in the [docs](https://code-graph.cyberchronos00.workers.dev/).
|
|
70
|
+
|
|
71
|
+
## Preview
|
|
72
|
+
|
|
73
|
+
[](docs/media/cg-view-demo.mp4)
|
|
74
|
+
|
|
75
|
+
[](docs/media/cg-terminal-demo.mp4)
|
|
76
|
+
|
|
77
|
+
More recordings (setup, visual view, agent over MCP): [docs/media/](docs/media).
|
|
78
|
+
|
|
79
|
+
## Links
|
|
80
|
+
|
|
81
|
+
- [Documentation](https://code-graph.cyberchronos00.workers.dev/)
|
|
82
|
+
- [PyPI: cg-code-graph](https://pypi.org/project/cg-code-graph/)
|
|
83
|
+
- [GitHub releases](https://github.com/cyberchronos00/code-graph/releases)
|
|
84
|
+
- [Changelog](CHANGELOG.md) · [Contributing](CONTRIBUTING.md) · [Security](SECURITY.md) · [License: MIT](LICENSE)
|
|
@@ -9,19 +9,29 @@ cg_code_graph.egg-info/entry_points.txt
|
|
|
9
9
|
cg_code_graph.egg-info/requires.txt
|
|
10
10
|
cg_code_graph.egg-info/top_level.txt
|
|
11
11
|
codegraph/__init__.py
|
|
12
|
+
codegraph/agent_rules.py
|
|
13
|
+
codegraph/agents.py
|
|
12
14
|
codegraph/aitools.py
|
|
15
|
+
codegraph/android_ipc.py
|
|
16
|
+
codegraph/apple_ipc.py
|
|
13
17
|
codegraph/apps.py
|
|
14
18
|
codegraph/blindspots.py
|
|
15
19
|
codegraph/bridges.py
|
|
20
|
+
codegraph/brokers.py
|
|
16
21
|
codegraph/cli.py
|
|
17
22
|
codegraph/concepts.py
|
|
18
23
|
codegraph/config.py
|
|
19
24
|
codegraph/coverage.py
|
|
25
|
+
codegraph/dart_isolates.py
|
|
20
26
|
codegraph/doctor.py
|
|
21
27
|
codegraph/external.py
|
|
28
|
+
codegraph/graphql.py
|
|
22
29
|
codegraph/indexer.py
|
|
30
|
+
codegraph/jobs.py
|
|
23
31
|
codegraph/link.py
|
|
24
32
|
codegraph/lint_async.py
|
|
33
|
+
codegraph/local_ipc.py
|
|
34
|
+
codegraph/local_sockets.py
|
|
25
35
|
codegraph/mcp_server.py
|
|
26
36
|
codegraph/parity.py
|
|
27
37
|
codegraph/parity_structure.py
|
|
@@ -32,13 +42,18 @@ codegraph/platforms.py
|
|
|
32
42
|
codegraph/process_runs.py
|
|
33
43
|
codegraph/query.py
|
|
34
44
|
codegraph/realtime.py
|
|
45
|
+
codegraph/realtime_events.py
|
|
46
|
+
codegraph/realtime_native.py
|
|
47
|
+
codegraph/realtime_ws.py
|
|
35
48
|
codegraph/roundtrip.py
|
|
36
49
|
codegraph/routes.py
|
|
37
50
|
codegraph/rpc.py
|
|
51
|
+
codegraph/sdk_systems.py
|
|
38
52
|
codegraph/sockets.py
|
|
39
53
|
codegraph/starters.py
|
|
40
54
|
codegraph/tests_index.py
|
|
41
55
|
codegraph/udp_apps.py
|
|
56
|
+
codegraph/webhooks.py
|
|
42
57
|
codegraph/xcode.py
|
|
43
58
|
codegraph/core/__init__.py
|
|
44
59
|
codegraph/core/cache.py
|
|
@@ -96,6 +111,7 @@ codegraph/plugins/nextjs/plugin.py
|
|
|
96
111
|
codegraph/plugins/nuxt/__init__.py
|
|
97
112
|
codegraph/plugins/nuxt/plugin.py
|
|
98
113
|
codegraph/plugins/php/__init__.py
|
|
114
|
+
codegraph/plugins/php/external.py
|
|
99
115
|
codegraph/plugins/php/gating.py
|
|
100
116
|
codegraph/plugins/php/plugin.py
|
|
101
117
|
codegraph/plugins/php/strings.py
|
|
@@ -134,6 +150,7 @@ codegraph/plugins/swift/packages.py
|
|
|
134
150
|
codegraph/plugins/swift/plugin.py
|
|
135
151
|
codegraph/plugins/ts/__init__.py
|
|
136
152
|
codegraph/plugins/ts/baseurl.py
|
|
153
|
+
codegraph/plugins/ts/nav.py
|
|
137
154
|
codegraph/plugins/ts/plugin.py
|
|
138
155
|
codegraph/plugins/ts/extractor/extract.mjs
|
|
139
156
|
codegraph/plugins/ts/extractor/fw.mjs
|
|
@@ -179,9 +196,14 @@ codegraph/viz/static/vendor/layout-base.js
|
|
|
179
196
|
codegraph/viz/tools/package-lock.json
|
|
180
197
|
codegraph/viz/tools/package.json
|
|
181
198
|
codegraph/viz/tools/shoot.mjs
|
|
199
|
+
tests/test_agents_install.py
|
|
200
|
+
tests/test_agents_md.py
|
|
182
201
|
tests/test_ai_tools.py
|
|
202
|
+
tests/test_android_ipc.py
|
|
203
|
+
tests/test_apple_ipc.py
|
|
183
204
|
tests/test_bridges.py
|
|
184
205
|
tests/test_bridges_pigeon_monorepo.py
|
|
206
|
+
tests/test_brokers.py
|
|
185
207
|
tests/test_cache_clean.py
|
|
186
208
|
tests/test_cache_invalidation.py
|
|
187
209
|
tests/test_channels_tests.py
|
|
@@ -190,15 +212,20 @@ tests/test_completeness.py
|
|
|
190
212
|
tests/test_config_extras.py
|
|
191
213
|
tests/test_coverage.py
|
|
192
214
|
tests/test_coverage_ts_hint.py
|
|
215
|
+
tests/test_dart_isolates.py
|
|
193
216
|
tests/test_dispatch_interfaces.py
|
|
194
217
|
tests/test_django_flutter.py
|
|
218
|
+
tests/test_docs_links.py
|
|
195
219
|
tests/test_enum_constants.py
|
|
196
220
|
tests/test_external.py
|
|
197
221
|
tests/test_gating.py
|
|
198
222
|
tests/test_generated.py
|
|
223
|
+
tests/test_graphql.py
|
|
199
224
|
tests/test_impact_overrides.py
|
|
200
225
|
tests/test_index_isolation.py
|
|
201
226
|
tests/test_inherited_overrides.py
|
|
227
|
+
tests/test_jobs.py
|
|
228
|
+
tests/test_js_refs.py
|
|
202
229
|
tests/test_kotlin.py
|
|
203
230
|
tests/test_kotlin_binding.py
|
|
204
231
|
tests/test_kotlin_exact.py
|
|
@@ -207,23 +234,29 @@ tests/test_kotlin_mixed.py
|
|
|
207
234
|
tests/test_kotlin_nav_consts.py
|
|
208
235
|
tests/test_kotlin_props.py
|
|
209
236
|
tests/test_laravel_determinism.py
|
|
237
|
+
tests/test_laravel_resources.py
|
|
210
238
|
tests/test_lint_async.py
|
|
239
|
+
tests/test_local_ipc.py
|
|
240
|
+
tests/test_local_sockets.py
|
|
211
241
|
tests/test_mcp.py
|
|
212
242
|
tests/test_mcp_index.py
|
|
213
243
|
tests/test_native_cfamily.py
|
|
214
244
|
tests/test_native_concurrency.py
|
|
215
245
|
tests/test_native_rust.py
|
|
246
|
+
tests/test_nuxt_import_dirs.py
|
|
216
247
|
tests/test_nuxt_rootsrc.py
|
|
217
248
|
tests/test_packaging.py
|
|
218
249
|
tests/test_parity.py
|
|
219
250
|
tests/test_parity_structure.py
|
|
220
251
|
tests/test_php_props.py
|
|
252
|
+
tests/test_plain_js.py
|
|
221
253
|
tests/test_plans.py
|
|
222
254
|
tests/test_platform_gaps.py
|
|
223
255
|
tests/test_platform_type_variants.py
|
|
224
256
|
tests/test_platforms.py
|
|
225
257
|
tests/test_platforms_apple.py
|
|
226
258
|
tests/test_presets_config.py
|
|
259
|
+
tests/test_process_ipc.py
|
|
227
260
|
tests/test_process_runs.py
|
|
228
261
|
tests/test_protocols.py
|
|
229
262
|
tests/test_python_app_tests_module.py
|
|
@@ -238,10 +271,15 @@ tests/test_python_tests.py
|
|
|
238
271
|
tests/test_python_web_hosts.py
|
|
239
272
|
tests/test_python_web_routes.py
|
|
240
273
|
tests/test_python_web_routes_more.py
|
|
274
|
+
tests/test_realtime.py
|
|
275
|
+
tests/test_realtime_native.py
|
|
241
276
|
tests/test_roundtrip.py
|
|
277
|
+
tests/test_route_tables.py
|
|
242
278
|
tests/test_routes_search_explain.py
|
|
243
279
|
tests/test_rpc.py
|
|
244
280
|
tests/test_scip_health.py
|
|
281
|
+
tests/test_sdk_external.py
|
|
282
|
+
tests/test_snippet.py
|
|
245
283
|
tests/test_sockets.py
|
|
246
284
|
tests/test_starters_budget.py
|
|
247
285
|
tests/test_swift.py
|
|
@@ -264,4 +302,8 @@ tests/test_ts_file_specs.py
|
|
|
264
302
|
tests/test_ts_frameworks.py
|
|
265
303
|
tests/test_ts_nuxt.py
|
|
266
304
|
tests/test_values.py
|
|
267
|
-
tests/test_viz.py
|
|
305
|
+
tests/test_viz.py
|
|
306
|
+
tests/test_vue_nav.py
|
|
307
|
+
tests/test_webhooks.py
|
|
308
|
+
tests/test_websockets.py
|
|
309
|
+
tests/test_workspace_link.py
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""code-graph: deterministic code knowledge graph (beta)."""
|
|
2
|
-
__version__ = "0.
|
|
2
|
+
__version__ = "0.13.0"
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"""Canonical "how to read this codebase with cg" guidance.
|
|
2
|
+
|
|
3
|
+
Single source for this repo's AGENTS.md and for the blocks that `cg agents` installs into a
|
|
4
|
+
project's AGENTS.md / CLAUDE.md / Cursor rules, so the wording never drifts. TEXT is the body;
|
|
5
|
+
wrap it between BEGIN_MARK and END_MARK to get a block that can be replaced in place."""
|
|
6
|
+
|
|
7
|
+
BEGIN_MARK = "<!-- BEGIN cg agent rules (managed by `cg agents`; edit cg, not here) -->"
|
|
8
|
+
END_MARK = "<!-- END cg agent rules -->"
|
|
9
|
+
|
|
10
|
+
TEXT = """\
|
|
11
|
+
# Reading this codebase with cg
|
|
12
|
+
|
|
13
|
+
This repository ships `cg`, a code-graph tool. Read the code by symbol through the index
|
|
14
|
+
instead of opening whole files.
|
|
15
|
+
|
|
16
|
+
## Build the index first
|
|
17
|
+
pip install -e . -q # make `cg` this checkout's version
|
|
18
|
+
cg index . --db out/graph.db --name repo
|
|
19
|
+
There is no incremental index: re-run `cg index` after large changes.
|
|
20
|
+
|
|
21
|
+
## Find code (get file:line; avoid ls / cat / broad grep)
|
|
22
|
+
cg search <name> --db out/graph.db # nodes by name or FQN substring
|
|
23
|
+
cg impact <symbol> --db out/graph.db # callers up to entry points (reverse)
|
|
24
|
+
cg downstream <symbol> --db out/graph.db # what the symbol calls and reaches (forward)
|
|
25
|
+
cg node <symbol> --db out/graph.db # one node's location, kind and edges
|
|
26
|
+
`<symbol>` is a name, an FQN, `Class.method`, or a node id. Ambiguous names list candidates.
|
|
27
|
+
|
|
28
|
+
## Read source (never cat a whole file; never more than ~200 lines at once)
|
|
29
|
+
cg snippet <symbol> --db out/graph.db # just that symbol's source, numbered
|
|
30
|
+
cg snippet <symbol> --db out/graph.db --context 5 # a few lines around it
|
|
31
|
+
sed -n '120,180p' path/to/file # a plain line range when needed
|
|
32
|
+
`cg snippet` prints a `path:start-end` header then the body; `--max-lines` caps long bodies.
|
|
33
|
+
|
|
34
|
+
## Follow an edge only when your change reaches it
|
|
35
|
+
Use `cg impact` and `cg downstream` to decide whether a caller or callee matters before
|
|
36
|
+
opening it. Chase a dependency only if your edit changes what crosses that edge.
|
|
37
|
+
|
|
38
|
+
## After editing, re-query instead of rereading
|
|
39
|
+
Re-run `cg index`, then `cg snippet` or `cg impact` on the changed spot to confirm the new
|
|
40
|
+
shape, rather than reopening files.
|
|
41
|
+
|
|
42
|
+
## Keep output small
|
|
43
|
+
Pipe long output through `head` or `tail`:
|
|
44
|
+
cg impact <symbol> --db out/graph.db | head -n 40
|
|
45
|
+
While iterating, run one file: `pytest -q -x tests/test_x.py`.
|
|
46
|
+
Run the full suite once at the end: `pytest -q 2>&1 | tail -n 30`.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def document() -> str:
|
|
51
|
+
"""The repo-root AGENTS.md content (TEXT, newline-terminated)."""
|
|
52
|
+
return TEXT
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def block() -> str:
|
|
56
|
+
"""The marked block `cg agents` writes into a project file; replaced in place on re-run."""
|
|
57
|
+
return BEGIN_MARK + "\n" + TEXT + END_MARK + "\n"
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
"""`cg agents`: opt-in install of the cg usage guidance (and the cg MCP server entry) into a
|
|
2
|
+
project's AGENTS.md / CLAUDE.md / Cursor rules. It only ever writes a clearly marked block and
|
|
3
|
+
never writes silently: every run previews the exact changes and asks before writing (--dry-run
|
|
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 touch only the `cg` server entry."""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import difflib
|
|
9
|
+
import json
|
|
10
|
+
import re
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
|
|
13
|
+
from . import agent_rules as AR
|
|
14
|
+
|
|
15
|
+
# project guidance files `cg agents` can manage, by --target key
|
|
16
|
+
TARGETS = {"agents": "AGENTS.md", "claude": "CLAUDE.md", "cursor": ".cursor/rules/cg.mdc"}
|
|
17
|
+
DEFAULT_MCP_FILE = ".cursor/mcp.json"
|
|
18
|
+
MCP_ENTRY = {"command": "cg-mcp", "args": ["--db", "out/graph.db"]}
|
|
19
|
+
|
|
20
|
+
_CORE = re.compile(re.escape(AR.BEGIN_MARK) + r".*?" + re.escape(AR.END_MARK), re.S)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _core_text() -> str:
|
|
24
|
+
"""The managed block without a trailing newline (BEGIN … END)."""
|
|
25
|
+
return AR.block().rstrip("\n")
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def plan_text(path: Path, remove: bool) -> dict:
|
|
29
|
+
"""Decide the new content of one guidance file. action: insert | update | remove | noop.
|
|
30
|
+
Everything outside the marked block is preserved; a re-run replaces the block in place and
|
|
31
|
+
remove restores the bytes the matching insert added (for newline-terminated files)."""
|
|
32
|
+
old = path.read_text(encoding="utf-8") if path.exists() else ""
|
|
33
|
+
m = _CORE.search(old)
|
|
34
|
+
core = _core_text()
|
|
35
|
+
if remove:
|
|
36
|
+
if not m:
|
|
37
|
+
return {"path": str(path), "kind": "text", "action": "noop", "old": old, "new": old}
|
|
38
|
+
s, e = m.start(), m.end()
|
|
39
|
+
while e < len(old) and old[e] == "\n": # drop the block's trailing newlines
|
|
40
|
+
e += 1
|
|
41
|
+
j = s
|
|
42
|
+
while j > 0 and old[j - 1] == "\n": # drop separator newlines before it
|
|
43
|
+
j -= 1
|
|
44
|
+
s = j + 1 if j > 0 else 0 # but keep one newline after real content
|
|
45
|
+
new = old[:s] + old[e:]
|
|
46
|
+
return {"path": str(path), "kind": "text", "action": "remove", "old": old, "new": new}
|
|
47
|
+
if m:
|
|
48
|
+
new = old[:m.start()] + core + old[m.end():]
|
|
49
|
+
return {"path": str(path), "kind": "text", "action": "update", "old": old, "new": new}
|
|
50
|
+
if not old:
|
|
51
|
+
new = core + "\n"
|
|
52
|
+
elif old.endswith("\n\n"):
|
|
53
|
+
new = old + core + "\n"
|
|
54
|
+
elif old.endswith("\n"):
|
|
55
|
+
new = old + "\n" + core + "\n"
|
|
56
|
+
else:
|
|
57
|
+
new = old + "\n\n" + core + "\n"
|
|
58
|
+
return {"path": str(path), "kind": "text", "action": "insert", "old": old, "new": new}
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def plan_mcp(path: Path, remove: bool) -> dict:
|
|
62
|
+
"""Add / update / remove only the `cg` entry under mcpServers; every other entry and key is
|
|
63
|
+
kept. Returns action noop when there is nothing to change, or error when the file is not JSON."""
|
|
64
|
+
old = path.read_text(encoding="utf-8") if path.exists() else ""
|
|
65
|
+
if old.strip():
|
|
66
|
+
try:
|
|
67
|
+
data = json.loads(old)
|
|
68
|
+
except ValueError as ex:
|
|
69
|
+
return {"path": str(path), "kind": "mcp", "action": "error", "old": old, "new": old,
|
|
70
|
+
"error": f"not valid JSON ({ex}); left unchanged"}
|
|
71
|
+
else:
|
|
72
|
+
data = {}
|
|
73
|
+
if not isinstance(data, dict):
|
|
74
|
+
return {"path": str(path), "kind": "mcp", "action": "error", "old": old, "new": old,
|
|
75
|
+
"error": "top level is not a JSON object; left unchanged"}
|
|
76
|
+
servers = data.get("mcpServers")
|
|
77
|
+
if not isinstance(servers, dict):
|
|
78
|
+
servers = {}
|
|
79
|
+
if remove:
|
|
80
|
+
if "cg" not in servers:
|
|
81
|
+
return {"path": str(path), "kind": "mcp", "action": "noop", "old": old, "new": old}
|
|
82
|
+
servers = {k: v for k, v in servers.items() if k != "cg"}
|
|
83
|
+
action = "remove"
|
|
84
|
+
else:
|
|
85
|
+
action = "update" if "cg" in servers else "insert"
|
|
86
|
+
servers = {**servers, "cg": MCP_ENTRY}
|
|
87
|
+
data = {**data, "mcpServers": servers}
|
|
88
|
+
new = json.dumps(data, indent=2) + "\n"
|
|
89
|
+
return {"path": str(path), "kind": "mcp", "action": action, "old": old, "new": new}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def preview(plan: dict) -> str:
|
|
93
|
+
"""A unified diff of one plan (the exact proposed change), or a one-line note for noop/error."""
|
|
94
|
+
if plan["action"] == "noop":
|
|
95
|
+
return f"{plan['path']}: no change (block not present)" if plan["kind"] == "text" \
|
|
96
|
+
else f"{plan['path']}: no change (no cg entry)"
|
|
97
|
+
if plan["action"] == "error":
|
|
98
|
+
return f"{plan['path']}: {plan['error']}"
|
|
99
|
+
diff = difflib.unified_diff(plan["old"].splitlines(True), plan["new"].splitlines(True),
|
|
100
|
+
fromfile=plan["path"], tofile=plan["path"], n=1)
|
|
101
|
+
body = "".join(diff).rstrip("\n")
|
|
102
|
+
return f"{plan['path']} [{plan['action']}]\n{body}"
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def build_plans(root: Path, targets: list[str], mcp: bool, mcp_file: str | None, remove: bool) -> list[dict]:
|
|
106
|
+
plans = [plan_text(root / TARGETS[t], remove) for t in targets]
|
|
107
|
+
if mcp:
|
|
108
|
+
plans.append(plan_mcp(Path(mcp_file) if mcp_file else root / DEFAULT_MCP_FILE, remove))
|
|
109
|
+
return plans
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def run(action: str, root: str = ".", targets: list[str] | None = None, all_targets: bool = False,
|
|
113
|
+
mcp: bool = False, mcp_file: str | None = None, dry_run: bool = False, assume_yes: bool = False,
|
|
114
|
+
input_fn=input, out=print) -> int:
|
|
115
|
+
"""Entry point for the CLI. action: install | update | remove | show. Returns a process exit code."""
|
|
116
|
+
rootp = Path(root)
|
|
117
|
+
remove = action == "remove"
|
|
118
|
+
if all_targets:
|
|
119
|
+
sel = list(TARGETS)
|
|
120
|
+
elif targets:
|
|
121
|
+
sel = targets
|
|
122
|
+
else: # default: the guidance files that already exist
|
|
123
|
+
sel = [t for t, f in TARGETS.items() if (rootp / f).exists()]
|
|
124
|
+
if not sel and not mcp:
|
|
125
|
+
out("nothing selected: pass --target agents|claude|cursor (repeatable), --all, or --mcp "
|
|
126
|
+
"(none of AGENTS.md / CLAUDE.md / .cursor/rules/cg.mdc exist here)")
|
|
127
|
+
return 2
|
|
128
|
+
plans = build_plans(rootp, sel, mcp, mcp_file, remove)
|
|
129
|
+
for p in plans:
|
|
130
|
+
out(preview(p))
|
|
131
|
+
if any(p["action"] == "error" for p in plans):
|
|
132
|
+
return 2
|
|
133
|
+
changing = [p for p in plans if p["action"] not in ("noop",)]
|
|
134
|
+
if action == "show" or dry_run:
|
|
135
|
+
out("(dry run: nothing written)" if dry_run else "(show: nothing written)")
|
|
136
|
+
return 0
|
|
137
|
+
if not changing:
|
|
138
|
+
out("nothing to do")
|
|
139
|
+
return 0
|
|
140
|
+
if not assume_yes:
|
|
141
|
+
resp = input_fn(f"apply {len(changing)} change(s)? [y/N] ")
|
|
142
|
+
if (resp or "").strip().lower() not in ("y", "yes"):
|
|
143
|
+
out("aborted; nothing written")
|
|
144
|
+
return 1
|
|
145
|
+
for p in changing:
|
|
146
|
+
fp = Path(p["path"])
|
|
147
|
+
fp.parent.mkdir(parents=True, exist_ok=True)
|
|
148
|
+
fp.write_text(p["new"], encoding="utf-8")
|
|
149
|
+
out(f"wrote {p['path']} ({p['action']})")
|
|
150
|
+
return 0
|