codegraphcontext 0.4.17__tar.gz → 0.4.18__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.
- {codegraphcontext-0.4.17/src/codegraphcontext.egg-info → codegraphcontext-0.4.18}/PKG-INFO +5 -5
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/README.md +4 -4
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/pyproject.toml +1 -1
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/api/app.py +5 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/cli/cli_helpers.py +52 -4
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/cli/config_manager.py +33 -8
- codegraphcontext-0.4.18/src/codegraphcontext/cli/hook_manager.py +220 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/cli/main.py +121 -15
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/cli/setup_wizard.py +96 -10
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/cgc_bundle.py +14 -4
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/database_kuzu.py +10 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/watcher.py +48 -5
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/code_finder.py +1 -1
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/graph_builder.py +38 -178
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/handlers/management_handlers.py +6 -2
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/handlers/watcher_handlers.py +7 -2
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/discovery.py +1 -2
- codegraphcontext-0.4.18/src/codegraphcontext/tools/indexing/persistence/utils.py +46 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/persistence/writer.py +264 -93
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/pipeline.py +27 -13
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/resolution/calls.py +21 -10
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/resolution/post_resolution.py +18 -6
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/scip_pipeline.py +38 -3
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/python.py +10 -11
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/report_generator.py +11 -11
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/utils/path_sandbox.py +2 -1
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18/src/codegraphcontext.egg-info}/PKG-INFO +5 -5
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext.egg-info/SOURCES.txt +2 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/LICENSE +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/MANIFEST.in +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/setup.cfg +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/__init__.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/__main__.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/api/__init__.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/api/mcp_sse.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/api/router.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/api/schemas.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/cli/__init__.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/cli/registry_commands.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/cli/setup_macos.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/cli/visualizer.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/__init__.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/bundle_registry.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/cgcignore.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/database.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/database_falkordb.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/database_falkordb_remote.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/database_ladybug.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/database_nornic.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/falkor_worker.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/core/jobs.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/prompts.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/server.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tool_definitions.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/__init__.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/advanced_language_query_tool.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/datasources/__init__.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/datasources/cassandra_ingester.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/datasources/mysql_ingester.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/datasources/redis_ingester.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/handlers/analysis_handlers.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/handlers/indexing_handlers.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/handlers/query_handlers.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/__init__.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/constants.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/embeddings.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/persistence/__init__.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/pre_scan.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/resolution/__init__.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/resolution/inheritance.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/sanitize.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/schema.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/schema_contract.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/indexing/vector_resolver.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/c.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/cpp.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/csharp.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/css.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/dart.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/elisp.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/elixir.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/go.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/gradle.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/haskell.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/html.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/java.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/javascript.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/kotlin.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/lua.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/maven.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/mybatis.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/perl.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/php.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/ruby.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/rust.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/scala.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/swift.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/typescript.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/languages/typescriptjsx.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/package_resolver.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/c_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/cpp_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/csharp_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/dart_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/elisp_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/go_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/haskell_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/java_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/javascript_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/perl_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/python_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/ruby_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/rust_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/scala_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/swift_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/query_tool_languages/typescript_toolkit.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/scip_indexer.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/scip_pb2.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/system.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/tree_sitter_parser.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/tools/type_utils.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/utils/cypher_readonly.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/utils/debug_log.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/utils/git_utils.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/utils/path_ignore.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/utils/repo_path.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/utils/tool_limits.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/utils/tree_sitter_manager.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/utils/visualize_graph.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/assets/__vite-browser-external-9wXp6ZBx.js +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/assets/function-calls-BtRHrqa2.png +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/assets/graph-total-D1fBAugo.png +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/assets/hero-graph-2voMJp2a.jpg +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/assets/hierarchy-DGADo0YT.png +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/assets/index-C-187lf0.js +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/assets/index-fNAa6jgv.css +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/assets/parser-pyodide.worker-BgsDfaad.js +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/assets/parser.worker-_nvrecvj.js +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/assets/tree-sitter-qKYAACSa.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/cgcIcon.png +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/favicon.ico +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/index.html +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/logo-icon.svg +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/logo.svg +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/placeholder.svg +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/preview-image.png +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/robots.txt +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-c.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-c_sharp.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-core.js +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-cpp.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-dart.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-go.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-java.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-javascript.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-kotlin.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-perl.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-php.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-python.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-ruby.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-rust.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-swift.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-tsx.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter-typescript.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/tree-sitter.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.js +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/dist/wasm/web-tree-sitter.wasm +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/viz/server.py +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext.egg-info/dependency_links.txt +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext.egg-info/entry_points.txt +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext.egg-info/requires.txt +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext.egg-info/top_level.txt +0 -0
- {codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/tests/test_issue_806_fix.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: codegraphcontext
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.18
|
|
4
4
|
Summary: An MCP server that indexes local code into a graph database to provide context to AI assistants.
|
|
5
5
|
Author-email: Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
6
6
|
License: MIT License
|
|
@@ -96,7 +96,7 @@ Dynamic: license-file
|
|
|
96
96
|
- 🇯🇵 [日本語](docs/translations/README.ja.md)
|
|
97
97
|
- 🇪🇸 Español (Soon)
|
|
98
98
|
|
|
99
|
-
🌍 **Help translate CodeGraphContext to your language by raising an issue & PR on https://github.com/Shashankss1205/CodeGraphContext/issues!**
|
|
99
|
+
🌍 **Help translate CodeGraphContext to your language by raising an issue & PR on [GitHub Issues](https://github.com/Shashankss1205/CodeGraphContext/issues)!**
|
|
100
100
|
|
|
101
101
|
<p align="center">
|
|
102
102
|
<br>
|
|
@@ -185,7 +185,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
185
185
|
---
|
|
186
186
|
|
|
187
187
|
## Project Details
|
|
188
|
-
- **Version:** 0.4.
|
|
188
|
+
- **Version:** 0.4.18
|
|
189
189
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
190
190
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
191
191
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -214,7 +214,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
214
214
|
- **Code Indexing:** Analyzes code and builds a knowledge graph of its components.
|
|
215
215
|
- **Relationship Analysis:** Query for callers, callees, class hierarchies, call chains and more.
|
|
216
216
|
- **Pre-indexed Bundles:** Load famous repositories instantly with `.cgc` bundles - no indexing required! ([Learn more](docs/BUNDLES.md))
|
|
217
|
-
- **Live File Watching:** Watch directories for changes and automatically update the graph in real-time (`
|
|
217
|
+
- **Live File Watching:** Watch directories for changes and automatically update the graph in real-time (`cgc watch`).
|
|
218
218
|
- **Interactive Setup:** A user-friendly command-line wizard for easy setup.
|
|
219
219
|
- **Dual Mode:** Works as a standalone **CLI toolkit** for developers and as an **MCP server** for AI agents.
|
|
220
220
|
- **Multi-Language Support:** Full support for 22 programming languages.
|
|
@@ -248,7 +248,7 @@ CodeGraphContext supports multiple graph database backends to suit your environm
|
|
|
248
248
|
|
|
249
249
|
| Feature | KuzuDB | LadybugDB | FalkorDB Lite | Neo4j / Nornic DB |
|
|
250
250
|
| :--- | :--- | :--- | :--- | :--- |
|
|
251
|
-
| **Typical default** |
|
|
251
|
+
| **Typical default** | Cross-platform fallback when FalkorDB Lite is unavailable | Optional embedded backend | **Default on Unix** (Python 3.12+, when `falkordblite` is installed) | When explicitly configured via `cgc config db` |
|
|
252
252
|
| **Setup** | Zero-config / Embedded | Zero-config / Embedded | Zero-config / In-process | Docker / External |
|
|
253
253
|
| **Platform** | **All (Windows Native, macOS, Linux)** | **All (Windows Native, macOS, Linux)** | Unix-only (Linux/macOS/WSL) | All Platforms |
|
|
254
254
|
| **Use Case** | Desktop, IDE, Local development | Custom research projects | Specialized Unix development | Enterprise, Massive graphs |
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
- 🇯🇵 [日本語](docs/translations/README.ja.md)
|
|
12
12
|
- 🇪🇸 Español (Soon)
|
|
13
13
|
|
|
14
|
-
🌍 **Help translate CodeGraphContext to your language by raising an issue & PR on https://github.com/Shashankss1205/CodeGraphContext/issues!**
|
|
14
|
+
🌍 **Help translate CodeGraphContext to your language by raising an issue & PR on [GitHub Issues](https://github.com/Shashankss1205/CodeGraphContext/issues)!**
|
|
15
15
|
|
|
16
16
|
<p align="center">
|
|
17
17
|
<br>
|
|
@@ -100,7 +100,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
100
100
|
---
|
|
101
101
|
|
|
102
102
|
## Project Details
|
|
103
|
-
- **Version:** 0.4.
|
|
103
|
+
- **Version:** 0.4.18
|
|
104
104
|
- **Authors:** Shashank Shekhar Singh <shashankshekharsingh1205@gmail.com>
|
|
105
105
|
- **License:** MIT License (See [LICENSE](LICENSE) for details)
|
|
106
106
|
- **Website:** [CodeGraphContext](http://codegraphcontext.vercel.app/)
|
|
@@ -129,7 +129,7 @@ A powerful **MCP server** and **CLI toolkit** that indexes local code into a gra
|
|
|
129
129
|
- **Code Indexing:** Analyzes code and builds a knowledge graph of its components.
|
|
130
130
|
- **Relationship Analysis:** Query for callers, callees, class hierarchies, call chains and more.
|
|
131
131
|
- **Pre-indexed Bundles:** Load famous repositories instantly with `.cgc` bundles - no indexing required! ([Learn more](docs/BUNDLES.md))
|
|
132
|
-
- **Live File Watching:** Watch directories for changes and automatically update the graph in real-time (`
|
|
132
|
+
- **Live File Watching:** Watch directories for changes and automatically update the graph in real-time (`cgc watch`).
|
|
133
133
|
- **Interactive Setup:** A user-friendly command-line wizard for easy setup.
|
|
134
134
|
- **Dual Mode:** Works as a standalone **CLI toolkit** for developers and as an **MCP server** for AI agents.
|
|
135
135
|
- **Multi-Language Support:** Full support for 22 programming languages.
|
|
@@ -163,7 +163,7 @@ CodeGraphContext supports multiple graph database backends to suit your environm
|
|
|
163
163
|
|
|
164
164
|
| Feature | KuzuDB | LadybugDB | FalkorDB Lite | Neo4j / Nornic DB |
|
|
165
165
|
| :--- | :--- | :--- | :--- | :--- |
|
|
166
|
-
| **Typical default** |
|
|
166
|
+
| **Typical default** | Cross-platform fallback when FalkorDB Lite is unavailable | Optional embedded backend | **Default on Unix** (Python 3.12+, when `falkordblite` is installed) | When explicitly configured via `cgc config db` |
|
|
167
167
|
| **Setup** | Zero-config / Embedded | Zero-config / Embedded | Zero-config / In-process | Docker / External |
|
|
168
168
|
| **Platform** | **All (Windows Native, macOS, Linux)** | **All (Windows Native, macOS, Linux)** | Unix-only (Linux/macOS/WSL) | All Platforms |
|
|
169
169
|
| **Use Case** | Desktop, IDE, Local development | Custom research projects | Specialized Unix development | Enterprise, Massive graphs |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "codegraphcontext"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.18"
|
|
4
4
|
description = "An MCP server that indexes local code into a graph database to provide context to AI assistants."
|
|
5
5
|
authors = [{ name = "Shashank Shekhar Singh", email = "shashankshekharsingh1205@gmail.com" }]
|
|
6
6
|
readme = "README.md"
|
|
@@ -24,6 +24,11 @@ def create_app() -> FastAPI:
|
|
|
24
24
|
|
|
25
25
|
app.include_router(router, prefix="/api/v1")
|
|
26
26
|
|
|
27
|
+
@app.get("/health")
|
|
28
|
+
async def health():
|
|
29
|
+
"""Liveness probe for load balancers and k8s."""
|
|
30
|
+
return {"status": "ok"}
|
|
31
|
+
|
|
27
32
|
# MCP-over-SSE Endpoints
|
|
28
33
|
app.add_api_route("/api/v1/mcp/sse", handle_sse, methods=["GET"])
|
|
29
34
|
app.add_api_route("/api/v1/mcp/messages", handle_messages, methods=["POST"])
|
|
@@ -260,6 +260,10 @@ def index_helper(path: str, context: Optional[str] = None):
|
|
|
260
260
|
"""Synchronously indexes a repository in a given context."""
|
|
261
261
|
time_start = time.time()
|
|
262
262
|
path_obj = Path(path).resolve()
|
|
263
|
+
# Normalize to forward slashes for cross-platform DB consistency.
|
|
264
|
+
# The graph DB always stores paths via Path.resolve().as_posix(),
|
|
265
|
+
# so Cypher queries must also use forward slashes on Windows.
|
|
266
|
+
repo_path_str = path_obj.as_posix()
|
|
263
267
|
index_cwd = path_obj if path_obj.is_dir() else path_obj.parent
|
|
264
268
|
services = _initialize_services(context, cwd=index_cwd)
|
|
265
269
|
if not all(services[:3]):
|
|
@@ -283,7 +287,7 @@ def index_helper(path: str, context: Optional[str] = None):
|
|
|
283
287
|
with db_manager.get_driver().session() as session:
|
|
284
288
|
result = session.run(
|
|
285
289
|
"MATCH (r:Repository {path: $path})-[:CONTAINS*]->(f:File) RETURN count(DISTINCT f) as file_count",
|
|
286
|
-
path=
|
|
290
|
+
path=repo_path_str
|
|
287
291
|
)
|
|
288
292
|
record = result.single()
|
|
289
293
|
file_count = record["file_count"] if record else 0
|
|
@@ -415,6 +419,49 @@ def delete_helper(repo_path: str, context: Optional[str] = None):
|
|
|
415
419
|
finally:
|
|
416
420
|
db_manager.close_driver()
|
|
417
421
|
|
|
422
|
+
def _print_query_exception(e: Exception, query: str) -> None:
|
|
423
|
+
"""
|
|
424
|
+
Pretty-print a database query exception, surfacing the raw driver
|
|
425
|
+
error message so Cypher syntax problems are clearly visible.
|
|
426
|
+
"""
|
|
427
|
+
import traceback
|
|
428
|
+
|
|
429
|
+
error_type = type(e).__name__
|
|
430
|
+
error_module = type(e).__module__ or ""
|
|
431
|
+
|
|
432
|
+
# Neo4j: CypherSyntaxError and other ClientError subclasses carry
|
|
433
|
+
# a .message and .code attribute with the full server-side detail.
|
|
434
|
+
if "neo4j" in error_module:
|
|
435
|
+
code = getattr(e, "code", None)
|
|
436
|
+
msg = getattr(e, "message", None) or str(e)
|
|
437
|
+
console.print(f"[bold red]Query Error ({error_type}):[/bold red]")
|
|
438
|
+
if code:
|
|
439
|
+
console.print(f" [yellow]Code:[/yellow] {code}")
|
|
440
|
+
console.print(f" [yellow]Message:[/yellow] {msg}")
|
|
441
|
+
|
|
442
|
+
# FalkorDB: ResponseError / exceptions in falkordb or redis packages
|
|
443
|
+
elif "falkordb" in error_module or "redis" in error_module:
|
|
444
|
+
console.print(f"[bold red]Query Error ({error_type}):[/bold red]")
|
|
445
|
+
console.print(f" [yellow]Database message:[/yellow] {e}")
|
|
446
|
+
|
|
447
|
+
# KuzuDB: RuntimeError from the kuzu extension
|
|
448
|
+
# KuzuDB: RuntimeError from the kuzu extension or database_kuzu wrapper
|
|
449
|
+
elif "kuzu" in error_module or (
|
|
450
|
+
error_type == "RuntimeError" and "Parser exception" in str(e)
|
|
451
|
+
):
|
|
452
|
+
console.print(f"[bold red]Query Error ({error_type}):[/bold red]")
|
|
453
|
+
console.print(f" [yellow]Database message:[/yellow] {e}")
|
|
454
|
+
|
|
455
|
+
else:
|
|
456
|
+
# Fallback: unknown backend — print type + message + traceback
|
|
457
|
+
console.print(f"[bold red]An error occurred while executing query ({error_type}):[/bold red]")
|
|
458
|
+
console.print(f" [yellow]Message:[/yellow] {e}")
|
|
459
|
+
console.print("[dim]--- Traceback ---[/dim]")
|
|
460
|
+
console.print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
461
|
+
|
|
462
|
+
console.print(f"\n[dim]Failed query:[/dim]")
|
|
463
|
+
console.print(f"[dim] {query}[/dim]")
|
|
464
|
+
|
|
418
465
|
|
|
419
466
|
def cypher_helper(query: str, context: Optional[str] = None):
|
|
420
467
|
"""Executes a read-only Cypher query."""
|
|
@@ -440,7 +487,7 @@ def cypher_helper(query: str, context: Optional[str] = None):
|
|
|
440
487
|
records = [record.data() for record in result]
|
|
441
488
|
console.print(json.dumps(records, indent=2))
|
|
442
489
|
except Exception as e:
|
|
443
|
-
|
|
490
|
+
_print_query_exception(e, query)
|
|
444
491
|
db_manager.close_driver()
|
|
445
492
|
raise typer.Exit(code=1)
|
|
446
493
|
finally:
|
|
@@ -466,7 +513,7 @@ def cypher_helper_visual(query: str, context: Optional[str] = None):
|
|
|
466
513
|
try:
|
|
467
514
|
visualize_cypher_results(query)
|
|
468
515
|
except Exception as e:
|
|
469
|
-
|
|
516
|
+
_print_query_exception(e, query)
|
|
470
517
|
db_manager.close_driver()
|
|
471
518
|
raise typer.Exit(code=1)
|
|
472
519
|
finally:
|
|
@@ -844,10 +891,11 @@ def watch_helper(path: str, context: Optional[str] = None, use_polling: Optional
|
|
|
844
891
|
|
|
845
892
|
# Add the directory to watch
|
|
846
893
|
if is_indexed:
|
|
847
|
-
console.print("[green]✓[/green] Already indexed
|
|
894
|
+
console.print("[green]✓[/green] Already indexed. Synchronizing current files...")
|
|
848
895
|
watcher.watch_directory(
|
|
849
896
|
str(path_obj),
|
|
850
897
|
perform_initial_scan=False,
|
|
898
|
+
sync_on_start=True,
|
|
851
899
|
cgcignore_path=ctx.cgcignore_path,
|
|
852
900
|
)
|
|
853
901
|
else:
|
{codegraphcontext-0.4.17 → codegraphcontext-0.4.18}/src/codegraphcontext/cli/config_manager.py
RENAMED
|
@@ -160,6 +160,14 @@ CONFIG_VALIDATORS = {
|
|
|
160
160
|
"CGC_EMBEDDING_MODEL": ["local", "openai"],
|
|
161
161
|
"FUZZY_SEARCH": ["true", "false"],
|
|
162
162
|
}
|
|
163
|
+
|
|
164
|
+
SUPPORTED_DATABASES: List[str] = CONFIG_VALIDATORS["DEFAULT_DATABASE"]
|
|
165
|
+
DATABASE_CLI_HELP = (
|
|
166
|
+
"Database backend ("
|
|
167
|
+
+ "|".join(SUPPORTED_DATABASES)
|
|
168
|
+
+ "). Defaults to DEFAULT_DATABASE from config."
|
|
169
|
+
)
|
|
170
|
+
|
|
163
171
|
DEFAULT_CGCIGNORE_PATTERNS = """\
|
|
164
172
|
# Default .cgcignore patterns
|
|
165
173
|
# Lines starting with # are comments; blank lines are ignored.
|
|
@@ -279,18 +287,25 @@ def load_config() -> Dict[str, str]:
|
|
|
279
287
|
def should_apply_project_dotenv() -> bool:
|
|
280
288
|
"""True when cwd-local ``.codegraphcontext/.env`` should merge with global config.
|
|
281
289
|
|
|
282
|
-
|
|
283
|
-
|
|
290
|
+
Project env is loaded only in **per-repo** context mode (or when
|
|
291
|
+
``CGC_LOAD_PROJECT_ENV=1``). In **global** / **named** mode, ``~/.codegraphcontext/.env``
|
|
292
|
+
wins so clones with a checked-in ``.codegraphcontext/.env`` do not hijack config.
|
|
293
|
+
|
|
294
|
+
Set ``CGC_IGNORE_PROJECT_ENV=1`` to force skip; ``CGC_LOAD_PROJECT_ENV=1`` to force load.
|
|
284
295
|
"""
|
|
285
296
|
if os.getenv("CGC_IGNORE_PROJECT_ENV", "").strip().lower() in ("1", "true", "yes"):
|
|
286
297
|
return False
|
|
287
298
|
if os.getenv("CGC_LOAD_PROJECT_ENV", "").strip().lower() in ("1", "true", "yes"):
|
|
288
299
|
return True
|
|
300
|
+
cfg = load_context_config()
|
|
301
|
+
if cfg.mode != "per-repo":
|
|
302
|
+
return False
|
|
289
303
|
try:
|
|
290
304
|
Path.cwd().resolve().relative_to(Path.home().resolve())
|
|
291
305
|
return True
|
|
292
306
|
except ValueError:
|
|
293
|
-
|
|
307
|
+
# Per-repo indexing from /tmp with an isolated HOME (common in E2E/CI).
|
|
308
|
+
return True
|
|
294
309
|
|
|
295
310
|
|
|
296
311
|
def find_local_env() -> Optional[Path]:
|
|
@@ -869,23 +884,33 @@ def resolve_context(
|
|
|
869
884
|
local_cgc = cwd / ".codegraphcontext"
|
|
870
885
|
local_cgc.mkdir(parents=True, exist_ok=True)
|
|
871
886
|
(local_cgc / "db").mkdir(exist_ok=True)
|
|
872
|
-
|
|
887
|
+
|
|
888
|
+
inherited_db = load_config().get("DEFAULT_DATABASE", "falkordb")
|
|
889
|
+
|
|
873
890
|
# Copy global .env into local context for easy per-repo tweaking
|
|
874
891
|
import shutil
|
|
875
892
|
if CONFIG_FILE.exists():
|
|
876
893
|
shutil.copy2(CONFIG_FILE, local_cgc / ".env")
|
|
877
|
-
|
|
878
|
-
|
|
894
|
+
|
|
895
|
+
local_yaml = local_cgc / "config.yaml"
|
|
896
|
+
if not local_yaml.exists():
|
|
897
|
+
with open(local_yaml, "w", encoding="utf-8") as f:
|
|
898
|
+
yaml.safe_dump({"database": inherited_db}, f)
|
|
899
|
+
|
|
900
|
+
console.print(
|
|
901
|
+
f"[dim]Auto-initialized per-repo context at {local_cgc} "
|
|
902
|
+
f"(Database: {inherited_db})[/dim]"
|
|
903
|
+
)
|
|
879
904
|
|
|
880
905
|
if local_cgc is not None:
|
|
881
906
|
# Read local config.yaml if present
|
|
882
907
|
local_yaml = local_cgc / "config.yaml"
|
|
883
|
-
local_db = "falkordb"
|
|
908
|
+
local_db = load_config().get("DEFAULT_DATABASE", "falkordb")
|
|
884
909
|
if local_yaml.exists():
|
|
885
910
|
try:
|
|
886
911
|
with open(local_yaml, encoding="utf-8") as f:
|
|
887
912
|
local_raw = yaml.safe_load(f) or {}
|
|
888
|
-
local_db = local_raw.get("database",
|
|
913
|
+
local_db = local_raw.get("database", local_db)
|
|
889
914
|
except Exception:
|
|
890
915
|
pass
|
|
891
916
|
db_path = str(local_cgc / "db" / local_db)
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"""Git hook management for keeping CGC indexes in sync."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
import stat
|
|
8
|
+
import subprocess
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
MANAGED_MARKER = "# CGC_MANAGED_HOOK"
|
|
12
|
+
HOOK_NAMES = ("post-commit", "post-checkout")
|
|
13
|
+
GITATTRIBUTES_ENTRY = "*.cgc merge=cgc-bundle"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class HookError(RuntimeError):
|
|
17
|
+
"""Raised when hook installation cannot proceed safely."""
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
@dataclass(frozen=True)
|
|
21
|
+
class GitRepository:
|
|
22
|
+
root: Path
|
|
23
|
+
git_dir: Path
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True)
|
|
27
|
+
class HookStatus:
|
|
28
|
+
repo_root: Path
|
|
29
|
+
git_dir: Path
|
|
30
|
+
installed_hooks: tuple[str, ...]
|
|
31
|
+
unmanaged_hooks: tuple[str, ...]
|
|
32
|
+
has_merge_driver: bool
|
|
33
|
+
has_gitattributes_entry: bool
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def installed(self) -> bool:
|
|
37
|
+
return (
|
|
38
|
+
bool(self.installed_hooks)
|
|
39
|
+
and self.has_merge_driver
|
|
40
|
+
and self.has_gitattributes_entry
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def find_git_repository(start: Path | str | None = None) -> GitRepository:
|
|
45
|
+
"""Find the nearest Git repository root and git directory."""
|
|
46
|
+
current = Path(start or Path.cwd()).resolve()
|
|
47
|
+
if current.is_file():
|
|
48
|
+
current = current.parent
|
|
49
|
+
|
|
50
|
+
for candidate in (current, *current.parents):
|
|
51
|
+
git_path = candidate / ".git"
|
|
52
|
+
if git_path.is_dir():
|
|
53
|
+
return GitRepository(root=candidate, git_dir=git_path)
|
|
54
|
+
if git_path.is_file():
|
|
55
|
+
target = _read_worktree_gitdir(git_path)
|
|
56
|
+
return GitRepository(root=candidate, git_dir=target)
|
|
57
|
+
|
|
58
|
+
raise HookError("No Git repository found from the current directory.")
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def install_hooks(start: Path | str | None = None, *, force: bool = False) -> HookStatus:
|
|
62
|
+
repo = find_git_repository(start)
|
|
63
|
+
hooks_dir = repo.git_dir / "hooks"
|
|
64
|
+
hooks_dir.mkdir(parents=True, exist_ok=True)
|
|
65
|
+
|
|
66
|
+
script = _hook_script(repo.root)
|
|
67
|
+
for hook_name in HOOK_NAMES:
|
|
68
|
+
hook_path = hooks_dir / hook_name
|
|
69
|
+
if hook_path.exists() and not _is_managed_hook(hook_path) and not force:
|
|
70
|
+
raise HookError(
|
|
71
|
+
f"{hook_name} already exists and is not managed by CGC. "
|
|
72
|
+
"Re-run with --force to replace it."
|
|
73
|
+
)
|
|
74
|
+
hook_path.write_text(script, encoding="utf-8")
|
|
75
|
+
mode = hook_path.stat().st_mode
|
|
76
|
+
hook_path.chmod(mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
|
77
|
+
|
|
78
|
+
_ensure_gitattributes(repo.root)
|
|
79
|
+
_configure_merge_driver(repo.root)
|
|
80
|
+
return get_hook_status(repo.root)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def uninstall_hooks(start: Path | str | None = None) -> HookStatus:
|
|
84
|
+
repo = find_git_repository(start)
|
|
85
|
+
hooks_dir = repo.git_dir / "hooks"
|
|
86
|
+
|
|
87
|
+
for hook_name in HOOK_NAMES:
|
|
88
|
+
hook_path = hooks_dir / hook_name
|
|
89
|
+
if hook_path.exists() and _is_managed_hook(hook_path):
|
|
90
|
+
hook_path.unlink()
|
|
91
|
+
|
|
92
|
+
_remove_gitattributes_entry(repo.root)
|
|
93
|
+
_unset_git_config(repo.root, "merge.cgc-bundle.name")
|
|
94
|
+
_unset_git_config(repo.root, "merge.cgc-bundle.driver")
|
|
95
|
+
return get_hook_status(repo.root)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def get_hook_status(start: Path | str | None = None) -> HookStatus:
|
|
99
|
+
repo = find_git_repository(start)
|
|
100
|
+
hooks_dir = repo.git_dir / "hooks"
|
|
101
|
+
installed_hooks: list[str] = []
|
|
102
|
+
unmanaged_hooks: list[str] = []
|
|
103
|
+
|
|
104
|
+
for hook_name in HOOK_NAMES:
|
|
105
|
+
hook_path = hooks_dir / hook_name
|
|
106
|
+
if not hook_path.exists():
|
|
107
|
+
continue
|
|
108
|
+
if _is_managed_hook(hook_path):
|
|
109
|
+
installed_hooks.append(hook_name)
|
|
110
|
+
else:
|
|
111
|
+
unmanaged_hooks.append(hook_name)
|
|
112
|
+
|
|
113
|
+
return HookStatus(
|
|
114
|
+
repo_root=repo.root,
|
|
115
|
+
git_dir=repo.git_dir,
|
|
116
|
+
installed_hooks=tuple(installed_hooks),
|
|
117
|
+
unmanaged_hooks=tuple(unmanaged_hooks),
|
|
118
|
+
has_merge_driver=_has_git_config(repo.root, "merge.cgc-bundle.driver"),
|
|
119
|
+
has_gitattributes_entry=_has_gitattributes_entry(repo.root),
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _read_worktree_gitdir(git_file: Path) -> Path:
|
|
124
|
+
content = git_file.read_text(encoding="utf-8").strip()
|
|
125
|
+
prefix = "gitdir:"
|
|
126
|
+
if not content.lower().startswith(prefix):
|
|
127
|
+
raise HookError(f"Unsupported .git file format at {git_file}")
|
|
128
|
+
|
|
129
|
+
raw_path = content[len(prefix):].strip()
|
|
130
|
+
git_dir = Path(raw_path)
|
|
131
|
+
if not git_dir.is_absolute():
|
|
132
|
+
git_dir = (git_file.parent / git_dir).resolve()
|
|
133
|
+
return git_dir
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def _hook_script(repo_root: Path) -> str:
|
|
137
|
+
repo_root_value = _sh_quote(str(repo_root))
|
|
138
|
+
return (
|
|
139
|
+
"#!/bin/sh\n"
|
|
140
|
+
f"{MANAGED_MARKER}: CodeGraphContext auto-update hook\n"
|
|
141
|
+
f"CGC_REPO_ROOT={repo_root_value}\n"
|
|
142
|
+
"if command -v cgc >/dev/null 2>&1; then\n"
|
|
143
|
+
' cgc update "$CGC_REPO_ROOT" --quiet\n'
|
|
144
|
+
"else\n"
|
|
145
|
+
' python -m codegraphcontext update "$CGC_REPO_ROOT" --quiet\n'
|
|
146
|
+
"fi\n"
|
|
147
|
+
)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _sh_quote(value: str) -> str:
|
|
151
|
+
return "'" + value.replace("'", "'\"'\"'") + "'"
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def _is_managed_hook(path: Path) -> bool:
|
|
155
|
+
try:
|
|
156
|
+
return MANAGED_MARKER in path.read_text(encoding="utf-8", errors="ignore")
|
|
157
|
+
except OSError:
|
|
158
|
+
return False
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def _ensure_gitattributes(repo_root: Path) -> None:
|
|
162
|
+
path = repo_root / ".gitattributes"
|
|
163
|
+
existing = path.read_text(encoding="utf-8") if path.exists() else ""
|
|
164
|
+
lines = existing.splitlines()
|
|
165
|
+
if any(line.strip() == GITATTRIBUTES_ENTRY for line in lines):
|
|
166
|
+
return
|
|
167
|
+
|
|
168
|
+
prefix = existing
|
|
169
|
+
if prefix and not prefix.endswith("\n"):
|
|
170
|
+
prefix += "\n"
|
|
171
|
+
path.write_text(f"{prefix}{GITATTRIBUTES_ENTRY}\n", encoding="utf-8")
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def _remove_gitattributes_entry(repo_root: Path) -> None:
|
|
175
|
+
path = repo_root / ".gitattributes"
|
|
176
|
+
if not path.exists():
|
|
177
|
+
return
|
|
178
|
+
|
|
179
|
+
lines = [
|
|
180
|
+
line
|
|
181
|
+
for line in path.read_text(encoding="utf-8").splitlines()
|
|
182
|
+
if line.strip() != GITATTRIBUTES_ENTRY
|
|
183
|
+
]
|
|
184
|
+
if lines:
|
|
185
|
+
path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
|
186
|
+
else:
|
|
187
|
+
path.unlink()
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
def _has_gitattributes_entry(repo_root: Path) -> bool:
|
|
191
|
+
path = repo_root / ".gitattributes"
|
|
192
|
+
if not path.exists():
|
|
193
|
+
return False
|
|
194
|
+
return any(
|
|
195
|
+
line.strip() == GITATTRIBUTES_ENTRY
|
|
196
|
+
for line in path.read_text(encoding="utf-8").splitlines()
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
def _configure_merge_driver(repo_root: Path) -> None:
|
|
201
|
+
_git_config(repo_root, "merge.cgc-bundle.name", "CodeGraphContext bundle merge driver")
|
|
202
|
+
_git_config(repo_root, "merge.cgc-bundle.driver", "cgc bundle merge %O %A %B")
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
def _git_config(repo_root: Path, key: str, value: str) -> None:
|
|
206
|
+
subprocess.run(["git", "-C", str(repo_root), "config", key, value], check=True)
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def _unset_git_config(repo_root: Path, key: str) -> None:
|
|
210
|
+
subprocess.run(["git", "-C", str(repo_root), "config", "--unset-all", key], check=False)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def _has_git_config(repo_root: Path, key: str) -> bool:
|
|
214
|
+
result = subprocess.run(
|
|
215
|
+
["git", "-C", str(repo_root), "config", "--get", key],
|
|
216
|
+
check=False,
|
|
217
|
+
stdout=subprocess.DEVNULL,
|
|
218
|
+
stderr=subprocess.DEVNULL,
|
|
219
|
+
)
|
|
220
|
+
return result.returncode == 0
|