descry-codegraph 1.0.2__tar.gz → 1.2.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.
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/.github/workflows/release.yml +3 -3
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/AGENTS.md +3 -3
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/CHANGELOG.md +71 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/CONTRACT.md +2 -2
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/PKG-INFO +10 -8
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/README.md +9 -7
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/claude-skill/README.md +1 -1
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/claude-skill/descry/SKILL.md +7 -7
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/claude-skill/descry/references/cli-reference.md +4 -3
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/claude-skill/descry/references/mcp-tools.md +3 -3
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/claude-skill/descry/references/recipes.md +3 -3
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/docs/CERTAINTY.md +5 -4
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/docs/TOOLS.md +8 -6
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/pi-extension/descry-cli.py +4 -2
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/pi-extension/descry-tools.ts +5 -1
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/pyproject.toml +4 -1
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/__init__.py +1 -1
- descry_codegraph-1.2.0/src/descry/_files.py +158 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/cli.py +11 -3
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/embeddings.py +2 -79
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/generate.py +76 -33
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/handlers.py +229 -41
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/mcp_server.py +11 -7
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/resolver.py +54 -21
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/rust_parser.py +60 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/web/server.py +6 -2
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/eval/README.md +20 -0
- descry_codegraph-1.2.0/tests/eval/results/search-after.json +510 -0
- descry_codegraph-1.2.0/tests/eval/results/search-before.json +510 -0
- descry_codegraph-1.2.0/tests/eval/search_eval.py +75 -0
- descry_codegraph-1.2.0/tests/eval/search_questions.json +400 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_cli.py +50 -1
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_embeddings.py +82 -10
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_generate.py +292 -1
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_handlers.py +220 -1
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_interfaces.py +31 -1
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_parse_cache.py +29 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_resolve_cache.py +46 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_web_server.py +9 -6
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_written_through.py +39 -5
- descry_codegraph-1.0.2/src/descry/_files.py +0 -68
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/.github/assets/01-landing.png +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/.github/workflows/ci.yml +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/.gitignore +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/LICENSE +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/SECURITY.md +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/THIRD-PARTY-NOTICES.md +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/docs/UPGRADING.md +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/justfile +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/pi-extension/README.md +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/_answers.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/_comments.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/_env.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/_graph.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/_parse_cache.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/_parsing.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/_reads.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/_stdlib.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/_streams.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/clang_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/cross_lang.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/dart_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/dotnet_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/git_history.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/go_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/java_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/php_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/proto_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/python_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/query.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/ruby_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/__init__.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapter.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/__init__.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/_empty_environment.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/_java_compat.init.gradle +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/clang.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/dart.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/dotnet.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/go.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/java.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/php.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/python.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/ruby.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/rust.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/adapters/typescript.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/cache.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/pb2.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/scip/support.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/c.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/cpp.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/dart.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/dotnet.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/go.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/java.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/node.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/php.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/python.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/ruby.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/rust.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/stdlib/typescript.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/ts_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/web/__init__.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/web/web/index.html +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/src/descry/web/web/style.css +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/__init__.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/conftest.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/eval/__init__.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/eval/compare.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/eval/corpus.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/eval/metrics.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/eval/registry.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/eval/results/results-descry.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/eval/results/results-ripgrep.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/fixtures/small_graph.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/c/Makefile +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/c/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/c/io.c +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/c/io.h +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/c/main.c +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/c/order.c +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/cpp/Makefile +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/cpp/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/cpp/main.cpp +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/cpp/models.hpp +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/cpp/reader.hpp +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/csharp/Gt.csproj +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/csharp/Io.cs +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/csharp/Models.cs +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/csharp/Program.cs +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/csharp/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/dart/bin/main.dart +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/dart/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/dart/lib/io.dart +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/dart/lib/models.dart +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/dart/pubspec.yaml +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/go/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/go/go.mod +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/go/io.go +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/go/main.go +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/go/models.go +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/java/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/java/src/gt/Base.java +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/java/src/gt/Io.java +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/java/src/gt/Main.java +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/java/src/gt/Order.java +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/java/src/gt/Reader.java +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/java/src/gt/User.java +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/javascript/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/javascript/package.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/javascript/src/io.js +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/javascript/src/main.js +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/javascript/src/models.js +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/php/composer.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/php/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/php/src/Io.php +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/php/src/Models.php +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/php/src/main.php +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/python/app/__init__.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/python/app/io.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/python/app/main.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/python/app/models.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/python/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/python/pyproject.toml +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/ruby/Gemfile +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/ruby/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/ruby/lib/io.rb +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/ruby/lib/main.rb +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/ruby/lib/models.rb +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/rust/Cargo.toml +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/rust/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/rust/src/io.rs +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/rust/src/main.rs +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/rust/src/models.rs +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/typescript/expected.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/typescript/package.json +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/typescript/src/io.ts +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/typescript/src/main.ts +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/ground_truth/typescript/src/models.ts +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_backtracking.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_clang_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_config.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_cross_lang.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_dart_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_docs.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_dotnet_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_git_history.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_go_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_ground_truth.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_hardening.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_java_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_mcp.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_non_regular_files.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_php_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_query.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_ruby_parser.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_scip.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_scip_cache.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_scip_clang.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_scip_dart.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_scip_dotnet.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_scip_go.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_scip_java.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_scip_php.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_scip_ruby.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tests/test_stdlib.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/docs/gen_tools.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/README.md +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/common.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_c.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_cpp.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_dart.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_dotnet.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_go.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_java.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_node.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_php.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_python.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_ruby.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_rust.py +0 -0
- {descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/tools/stdlib/gen_typescript.py +0 -0
|
@@ -32,16 +32,16 @@ jobs:
|
|
|
32
32
|
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
|
33
33
|
with:
|
|
34
34
|
python-version: "3.12"
|
|
35
|
-
- name: Verify tag matches
|
|
35
|
+
- name: Verify tag matches package version
|
|
36
36
|
# A manual run that targets PyPI must be dispatched from the release tag.
|
|
37
37
|
if: github.event_name == 'push' || inputs.target == 'pypi'
|
|
38
38
|
env:
|
|
39
39
|
GIT_TAG: ${{ github.ref_name }}
|
|
40
40
|
run: |
|
|
41
|
-
PKG_VERSION=$(python -c "import
|
|
41
|
+
PKG_VERSION=$(PYTHONPATH=src python -c "import descry; print(descry.__version__)")
|
|
42
42
|
TAG_VERSION="${GIT_TAG#v}"
|
|
43
43
|
if [ "$PKG_VERSION" != "$TAG_VERSION" ]; then
|
|
44
|
-
echo "::error::tag $GIT_TAG does not match
|
|
44
|
+
echo "::error::tag $GIT_TAG does not match package version $PKG_VERSION"
|
|
45
45
|
exit 1
|
|
46
46
|
fi
|
|
47
47
|
- name: Build sdist + wheel
|
|
@@ -23,7 +23,7 @@ just test tests/test_config.py::TestFromToml::test_from_toml_basic # one test
|
|
|
23
23
|
just test -k "cross_lang and not slow" # by expression
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Python 3.11+ required (enforced by `pyproject.toml`). Pre-commit gate: `just lint && just fmt && just test` all pass (
|
|
26
|
+
Python 3.11+ required (enforced by `pyproject.toml`). Pre-commit gate: `just lint && just fmt && just test` all pass (3380 tests pass; a handful more are skipped where the environment lacks their fixture — a drop is a regression signal).
|
|
27
27
|
|
|
28
28
|
Invoke the tool while developing:
|
|
29
29
|
|
|
@@ -43,7 +43,7 @@ Packaging: `pyproject.toml` defines four console scripts — `descry`, `descry-m
|
|
|
43
43
|
|
|
44
44
|
**Two graph phases:**
|
|
45
45
|
|
|
46
|
-
1. **Generate** (`generate.py`, invoked via `descry index` or `descry-generate`) — walks the project, parses source files with regex + AST (`_parsing.py` holds what every parser shares; each language has its `<lang>_parser.py`), resolves calls (`CallResolver` in `resolver.py`) from imports, declared and returned types, scope and the class hierarchy, optionally runs SCIP indexers (rust-analyzer, scip-typescript) for type-aware call resolution, optionally builds embeddings. Writes `.descry_cache/codebase_graph.json
|
|
46
|
+
1. **Generate** (`generate.py`, invoked via `descry index` or `descry-generate`) — walks the project, parses source files with regex + AST (`_parsing.py` holds what every parser shares; each language has its `<lang>_parser.py`), resolves calls (`CallResolver` in `resolver.py`) from imports, declared and returned types, scope and the class hierarchy, optionally runs SCIP indexers (rust-analyzer, scip-typescript) for type-aware call resolution, optionally builds embeddings. Writes `.descry_cache/codebase_graph.json` last, once its embeddings are written (the graph is built under a temporary name and dated when the walk began), and holds `index.lock` for the whole run. A call is resolved, left unresolved with the definitions that fit recorded as `candidates`, or dropped as external. Never resolve by name alone when more than one definition fits, never by file path, and never guess the type of a receiver: an unknown receiver stays unresolved.
|
|
47
47
|
2. **Query** (`query.py` → `GraphQuerier`) — loads the cached graph and answers callers/callees/flow/path/context queries. All service methods lazy-load the querier; freshness is tracked by graph file mtime.
|
|
48
48
|
|
|
49
49
|
**Graph schema is versioned.** `src/descry/_graph.py` exports `CURRENT_SCHEMA` (currently `2`) and `load_graph_with_schema()`. Every graph-consuming code path must load via this helper — it raises `GraphSchemaError` on mismatch so stale graphs are rejected rather than silently producing wrong results. If you change the graph shape in a breaking way, bump `CURRENT_SCHEMA`.
|
|
@@ -70,7 +70,7 @@ These are load-bearing — see the `### Security` sections of `CHANGELOG.md`. Do
|
|
|
70
70
|
- **The default cache directory stays inside the project.** A repository can ship `.descry_cache`, or its `scip` or `parse` subdirectory, as a symlink to another directory; `DescryConfig.cache_dir_error()` refuses indexing and embedding there, and only `DESCRY_CACHE_DIR` names a cache outside the project.
|
|
71
71
|
- **A parse is reused only from an entry descry wrote.** Each file's parse is kept in `<cache>/parse` as JSON, never pickle, with an HMAC of the entry's name and content under a key in the user's state directory (`$XDG_STATE_HOME/descry/parse.key` when that is absolute, else `~/.local/state`; `%LOCALAPPDATA%` on Windows); where the key would be inside the project, no entry is read or kept. An entry a repository ships, or one moved to another file's name, fails the check and the file is parsed again; restoring an entry cannot stop an index.
|
|
72
72
|
- **TOML-sourced subprocess args are validated.** `_validate_toolchain`, `_validate_scip_extra_arg`, `_validate_embedding_model` in `handlers.py` reject short flags, shell metacharacters, and out-of-root local paths. New TOML → subprocess plumbing must validate.
|
|
73
|
-
- **Web UI is local-only by design.** `descry-web` binds `127.0.0.1`, has no auth, and deliberately omits `CORSMiddleware` so browsers enforce same-origin — a tab on `evil.com` cannot read `/api/source`. State-changing requests are refused unless same-origin (`Origin` / `Sec-Fetch-Site`), so it cannot trigger `/api/index` either. The host middleware rejects non-loopback `Host` headers to defeat DNS-rebinding that would otherwise bypass the 127.0.0.1 bind. `/api/source` enforces project-root containment, rejects non-regular files, files over `[code_files] max_file_mb` (10 by default; 0, which a repository's `.descry.toml` can set, lifts the cap) and files with a NUL byte in their first 8 KiB, and opens every path component with `O_NOFOLLOW` (on Windows, which has no `openat`, it checks after opening that the file opened is the one the path resolves to, inside the root). `/api/index` (and `/api/index/stream`) take no path parameter (always indexes the configured root). `DescryService` runs one index at a time for every interface and stops the indexer's whole process tree when a run ends early. The page's remote scripts carry SRI hashes and every response carries the Content-Security-Policy that `web/server.py` builds from the page's own tags, allowing exactly those asset URLs; a new remote script needs an SRI hash. Don't add a `--host 0.0.0.0` flag, don't add `CORSMiddleware`, and don't expose network listeners.
|
|
73
|
+
- **Web UI is local-only by design.** `descry-web` binds `127.0.0.1`, has no auth, and deliberately omits `CORSMiddleware` so browsers enforce same-origin — a tab on `evil.com` cannot read `/api/source`. State-changing requests are refused unless same-origin (`Origin` / `Sec-Fetch-Site`), so it cannot trigger `/api/index` either. The host middleware rejects non-loopback `Host` headers to defeat DNS-rebinding that would otherwise bypass the 127.0.0.1 bind. `/api/source` enforces project-root containment, rejects non-regular files, files over `[code_files] max_file_mb` (10 by default; 0, which a repository's `.descry.toml` can set, lifts the cap) and files with a NUL byte in their first 8 KiB, and opens every path component with `O_NOFOLLOW` (on Windows, which has no `openat`, it checks after opening that the file opened is the one the path resolves to, inside the root). `/api/index` (and `/api/index/stream`) take no path parameter (always indexes the configured root). `DescryService` runs one index at a time for every interface, refuses one while another process holds the project's `index.lock`, and stops the indexer's whole process tree when a run ends early. The page's remote scripts carry SRI hashes and every response carries the Content-Security-Policy that `web/server.py` builds from the page's own tags, allowing exactly those asset URLs; a new remote script needs an SRI hash. Don't add a `--host 0.0.0.0` flag, don't add `CORSMiddleware`, and don't expose network listeners.
|
|
74
74
|
- **MCP `index(path=...)`** is restricted to the configured project root; a path below it narrows the walk but still writes the root's graph.
|
|
75
75
|
- **Embedding cache** uses numpy safe-mode load + JSON sidecar + atomic writes, keyed by the graph's bytes and time and the recipe. A rebuild reuses a node's vector, by the digest of its text, only from a cache descry signed with the key in the user's state directory (`signing_key()` in `_parse_cache.py`), so a shipped cache is never reused. `MODEL_REGISTRY` in `embeddings.py` is the single source of truth for which models descry ships pinned configurations for — each entry carries its revision and its task prompts. **`trust_remote_code` is always `False`**: there is no registry field, loader parameter or config key that enables it, so descry never executes code from a model repository — do not add one. A model named in `.descry.toml` that is not registered is loaded unpinned. Adding a model means adding a registry entry, not editing the loader.
|
|
76
76
|
- **The cache key is the embedding recipe's identity.** `_recipe_fingerprint()` folds in the resolved repo id, the pinned revision, `RECIPE_VERSION`, `DOCSTRING_CHAR_LIMIT`, the prompt names, the entry's loading options, and whether source code is embedded (`CODE_CHAR_LIMIT`). Anything that changes the vectors without changing the graph must be added there and `RECIPE_VERSION` bumped, or a stale cache is served against freshly-encoded queries — comparing two different embedding spaces.
|
|
@@ -4,6 +4,77 @@ All notable changes to Descry will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [semver](https://semver.org/) from 1.0.0.
|
|
6
6
|
|
|
7
|
+
## [1.2.0] — 2026-11-04
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- `descry --version`; the skill's CLI reference lists it.
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- An index publishes the graph only once its embeddings are written, so
|
|
16
|
+
searches during a re-index stay hybrid on the previous graph. Before, the
|
|
17
|
+
new graph appeared first: searches fell back to keyword-only until the
|
|
18
|
+
embeddings were done, one stalled for `[timeouts] embedding_seconds`
|
|
19
|
+
(60 s by default), and after ten minutes `semantic` reported the model
|
|
20
|
+
unavailable.
|
|
21
|
+
- During a first index, a tool that needs the graph and `status` answer
|
|
22
|
+
"No graph yet: an index is building it", and the text header reads
|
|
23
|
+
`[Graph: BUILDING]`, instead of saying no graph exists.
|
|
24
|
+
- An index of a project another process is indexing is refused as `busy`
|
|
25
|
+
(`index`, `ensure`, the web's index stream, and `descry-generate`).
|
|
26
|
+
- `ensure` re-indexes when files the graph tracks changed or were removed
|
|
27
|
+
since it was written, as well as when it is older than `max_stale_hours`.
|
|
28
|
+
A file dated in the future is not counted as changed, there or in
|
|
29
|
+
`status`.
|
|
30
|
+
- The graph is dated when its index began, so a file edited while an index
|
|
31
|
+
runs counts as changed since it; before, an edit made before the graph
|
|
32
|
+
was written was missed.
|
|
33
|
+
|
|
34
|
+
### Security
|
|
35
|
+
|
|
36
|
+
- Windows: a lock file in the cache directory (`embeddings.lock`,
|
|
37
|
+
`index.lock`) that the repository ships as a symlink is refused instead
|
|
38
|
+
of followed, so an index neither locks nor creates the file it names, as
|
|
39
|
+
on other platforms.
|
|
40
|
+
|
|
41
|
+
### Documentation
|
|
42
|
+
|
|
43
|
+
- README: the MCP server is `descry-mcp.exe` on Windows, and
|
|
44
|
+
`python -m descry.mcp_server` starts it on every platform. Install
|
|
45
|
+
lines quote the extra (`"descry-codegraph[all]"`) so zsh does not
|
|
46
|
+
read the brackets as a glob.
|
|
47
|
+
|
|
48
|
+
## [1.1.0] — 2026-11-03
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
|
|
52
|
+
- `callers` and `callees` take `exclude_tests` (CLI `--exclude-tests`, MCP
|
|
53
|
+
`exclude_tests`, web `?exclude_tests=true`), as `search` does.
|
|
54
|
+
- `status` answers `changed_since_index`: how many files the graph tracks
|
|
55
|
+
are newer than it or gone; every text answer's header says so
|
|
56
|
+
(`| 2 file(s) changed since index`).
|
|
57
|
+
- `descry index` logs its progress every 15 seconds while it parses and
|
|
58
|
+
while it resolves calls.
|
|
59
|
+
|
|
60
|
+
### Changed
|
|
61
|
+
|
|
62
|
+
- Rust: `<X as Trait>::f(x)` calls `X`'s impl of `Trait::f`, the trait's
|
|
63
|
+
default body where the impl has none, and `<dyn Trait>::f(x)` is
|
|
64
|
+
`Trait::f(x)`; the callee was read from the trait's type arguments
|
|
65
|
+
(`Trait>::f`).
|
|
66
|
+
- Rust: a call on an element of a `vec![..]` a `let` binds reads what its
|
|
67
|
+
elements hold (`d[0].go()`).
|
|
68
|
+
- Search: the keyword side leaves out the words a question or prompt is
|
|
69
|
+
written with ("where", "which", "the", "function"), so a whole prompt
|
|
70
|
+
searches what it asks about; a search of such words alone is unchanged.
|
|
71
|
+
- Rust: glob re-exports that lead back round a cycle are walked once per
|
|
72
|
+
file: the walk that entered the cycle gives every module of it its answer.
|
|
73
|
+
- Search: while an embedding model load is under way (the MCP server's at
|
|
74
|
+
its start, or the one an index run begins), a search answers keyword-only
|
|
75
|
+
instead of waiting; a search that finds no load under way, as each CLI
|
|
76
|
+
command's, begins one and waits as before.
|
|
77
|
+
|
|
7
78
|
## [1.0.2] — 2026-10-31
|
|
8
79
|
|
|
9
80
|
### Fixed
|
|
@@ -59,7 +59,7 @@ as its type (`limit=ten`) is `invalid` there too.
|
|
|
59
59
|
|
|
60
60
|
| tool | parameters | answer |
|
|
61
61
|
|---|---|---|
|
|
62
|
-
| `callers`, `callees` | `symbol`, `limit`=20 | `symbol`, `total`, counts, `more` (counts), `callers` / `callees` (references) |
|
|
62
|
+
| `callers`, `callees` | `symbol`, `limit`=20, `exclude_tests`=false | `symbol`, `total`, counts, `more` (counts), `callers` / `callees` (references) |
|
|
63
63
|
| `context` | `symbol`, `brief`, `full`, `expand_callees`, `deduplicate`, `depth`=1, `max_tokens`=2000, `callee_budget`=2000, `head_lines`, `max_output_tokens` | `symbol` (definition), `brief`; brief: `callers`, `callees` (counts); else `depth`, `callers`, `callees` (references), `callers_more`, `callees_more` (counts), `examples` (`file`, `line`, `candidates`), `members` (`id`, `name`, `line`, `tokens`), `tests`, `configs` (`id`, `line`, `type`), `omitted`, `truncated`; with `deduplicate`, a symbol shown before answers `symbol` and `repeated` only |
|
|
64
64
|
| `flow` | `start`, `direction`=forward, `depth`=3, `target`, `inline_threshold`=100 | `start`, `direction`, `asked`, `depth`, `target`, `root` (tree: `id`, `name`, `type`, `tokens`, `file`, `line`, `kind`, `candidates`, `children`, `more`, `more_possible`, `seen`), `path_to_target`?, `cut`? |
|
|
65
65
|
| `path` | `start`, `end`, `max_depth`=10, `direction`=forward | `status` (`found`, `not_found`, `timeout`), `start`, `end`, `direction`, `max_depth`, `hops` (`caller`, `callee` references, `file`, `line`) |
|
|
@@ -73,7 +73,7 @@ as its type (`limit=ten`) is `invalid` there too.
|
|
|
73
73
|
| `churn` | `time_range`, `path_filter`, `limit`=20, `mode`=symbols, `exclude_generated`=true | `mode`, `time_range`, `path_filter`, `truncation_note`?, and `symbols`, `files`, `pairs` (with `file_level`?) or `message` |
|
|
74
74
|
| `changes` | `commit_range`, `time_range`, `path_filter`, `show_callers`=true, `limit`=50 | `range`, `commits`, `files_count`, `symbols_count`, and `symbols` (with `callers`) or `changed_files`; or `message` |
|
|
75
75
|
| `evolution` | `symbol`, `time_range`, `limit`=10, `show_diff`, `crate` | `node_id`, `mode` (`lines`, `file`), `truncation_note`?, `authors`, `commits` (`hash`, `date`, and in `lines` mode `added`, `removed`); or `message` |
|
|
76
|
-
| `status` | — | `exists`, `age_str`, `age_hours`, `nodes`, `edges`, `languages`, `stale`, `error`, `scip` (`state`, `indexers`, `cached`), `embeddings` (`state`, `nodes`, `model`) |
|
|
76
|
+
| `status` | — | `exists`, `age_str`, `age_hours`, `nodes`, `edges`, `languages`, `stale`, `changed_since_index`, `error`, `scip` (`state`, `indexers`, `cached`), `embeddings` (`state`, `nodes`, `model`) |
|
|
77
77
|
| `health` | — | `status`, `version`, `project_root`, `cache_dir`, `warm`, `max_depth` (the deepest a `flow` or `context` goes), `features`, `graph` |
|
|
78
78
|
| `ensure` | `max_age_hours` | `action` (`ready`, `refreshed`, `generated`), `summary`, `graph` (status) |
|
|
79
79
|
| `index` | `path`=. (not on the web, which always indexes the project root) | the graph's status after the run |
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: descry-codegraph
|
|
3
|
-
Version: 1.0
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: Codebase knowledge graph: polyglot indexer, semantic search, call-graph analysis
|
|
5
5
|
Project-URL: Homepage, https://github.com/06chaynes/descry
|
|
6
6
|
Project-URL: Repository, https://github.com/06chaynes/descry
|
|
@@ -165,7 +165,7 @@ yourself, which is also loaded unpinned.
|
|
|
165
165
|
|
|
166
166
|
```bash
|
|
167
167
|
# Install with all optional features
|
|
168
|
-
pip install descry-codegraph[all]
|
|
168
|
+
pip install "descry-codegraph[all]"
|
|
169
169
|
|
|
170
170
|
# Index your project
|
|
171
171
|
cd your-project
|
|
@@ -225,6 +225,8 @@ Or with a specific Python path:
|
|
|
225
225
|
|
|
226
226
|
Descry uses the standard MCP stdio transport. Any MCP-compatible host can spawn `descry-mcp` as a subprocess.
|
|
227
227
|
|
|
228
|
+
On Windows the executable is `descry-mcp.exe`. `python -m descry.mcp_server`, with the Python descry is installed in, starts the same server on every platform.
|
|
229
|
+
|
|
228
230
|
## Tools
|
|
229
231
|
|
|
230
232
|
Descry provides 19 tools, available through all interfaces:
|
|
@@ -233,7 +235,7 @@ Descry provides 19 tools, available through all interfaces:
|
|
|
233
235
|
|------|-------------|
|
|
234
236
|
| `health` | Diagnostic check — version, graph status, feature availability |
|
|
235
237
|
| `status` | Graph existence and freshness |
|
|
236
|
-
| `ensure` | Ensure graph exists and is fresh (regenerates if stale) |
|
|
238
|
+
| `ensure` | Ensure graph exists and is fresh (regenerates if stale or files changed) |
|
|
237
239
|
| `index` | Regenerate graph, SCIP indices, and embeddings |
|
|
238
240
|
| `search` | Search symbol names and docstrings (keyword + semantic) |
|
|
239
241
|
| `semantic` | Pure semantic search using embeddings only |
|
|
@@ -410,19 +412,19 @@ pip install descry-codegraph
|
|
|
410
412
|
### With MCP server
|
|
411
413
|
|
|
412
414
|
```bash
|
|
413
|
-
pip install descry-codegraph[mcp]
|
|
415
|
+
pip install "descry-codegraph[mcp]"
|
|
414
416
|
```
|
|
415
417
|
|
|
416
418
|
### With Web UI
|
|
417
419
|
|
|
418
420
|
```bash
|
|
419
|
-
pip install descry-codegraph[web]
|
|
421
|
+
pip install "descry-codegraph[web]"
|
|
420
422
|
```
|
|
421
423
|
|
|
422
424
|
### With semantic search
|
|
423
425
|
|
|
424
426
|
```bash
|
|
425
|
-
pip install descry-codegraph[embeddings]
|
|
427
|
+
pip install "descry-codegraph[embeddings]"
|
|
426
428
|
```
|
|
427
429
|
|
|
428
430
|
To select `embeddinggemma-2`, install its extra instead (adds Pillow and
|
|
@@ -435,7 +437,7 @@ pip install "descry-codegraph[embeddinggemma-2]"
|
|
|
435
437
|
### Everything
|
|
436
438
|
|
|
437
439
|
```bash
|
|
438
|
-
pip install descry-codegraph[all]
|
|
440
|
+
pip install "descry-codegraph[all]"
|
|
439
441
|
```
|
|
440
442
|
|
|
441
443
|
### Choosing a torch build
|
|
@@ -489,7 +491,7 @@ Requires [uv](https://github.com/astral-sh/uv) and [just](https://github.com/cas
|
|
|
489
491
|
|
|
490
492
|
3. **Query** — All tools query the cached graph. Keyword search uses TF-IDF scoring. Semantic search uses sentence-transformer embeddings. Call-graph traversal follows edges in the graph.
|
|
491
493
|
|
|
492
|
-
4. **Freshness** — `ensure` regenerates the graph when its age exceeds `[project] max_stale_hours` (default 24), or the `--max-age-hours` flag (CLI) / `max_age_hours` argument (MCP) when one is given. The same setting drives the "STALE" badge in `descry status`. The MCP server pre-warms the graph on startup.
|
|
494
|
+
4. **Freshness** — `ensure` regenerates the graph when files it indexed changed or were removed since it was written, and when its age exceeds `[project] max_stale_hours` (default 24), or the `--max-age-hours` flag (CLI) / `max_age_hours` argument (MCP) when one is given. The same setting drives the "STALE" badge in `descry status`. The MCP server pre-warms the graph on startup.
|
|
493
495
|
|
|
494
496
|
## Design Notes
|
|
495
497
|
|
|
@@ -104,7 +104,7 @@ yourself, which is also loaded unpinned.
|
|
|
104
104
|
|
|
105
105
|
```bash
|
|
106
106
|
# Install with all optional features
|
|
107
|
-
pip install descry-codegraph[all]
|
|
107
|
+
pip install "descry-codegraph[all]"
|
|
108
108
|
|
|
109
109
|
# Index your project
|
|
110
110
|
cd your-project
|
|
@@ -164,6 +164,8 @@ Or with a specific Python path:
|
|
|
164
164
|
|
|
165
165
|
Descry uses the standard MCP stdio transport. Any MCP-compatible host can spawn `descry-mcp` as a subprocess.
|
|
166
166
|
|
|
167
|
+
On Windows the executable is `descry-mcp.exe`. `python -m descry.mcp_server`, with the Python descry is installed in, starts the same server on every platform.
|
|
168
|
+
|
|
167
169
|
## Tools
|
|
168
170
|
|
|
169
171
|
Descry provides 19 tools, available through all interfaces:
|
|
@@ -172,7 +174,7 @@ Descry provides 19 tools, available through all interfaces:
|
|
|
172
174
|
|------|-------------|
|
|
173
175
|
| `health` | Diagnostic check — version, graph status, feature availability |
|
|
174
176
|
| `status` | Graph existence and freshness |
|
|
175
|
-
| `ensure` | Ensure graph exists and is fresh (regenerates if stale) |
|
|
177
|
+
| `ensure` | Ensure graph exists and is fresh (regenerates if stale or files changed) |
|
|
176
178
|
| `index` | Regenerate graph, SCIP indices, and embeddings |
|
|
177
179
|
| `search` | Search symbol names and docstrings (keyword + semantic) |
|
|
178
180
|
| `semantic` | Pure semantic search using embeddings only |
|
|
@@ -349,19 +351,19 @@ pip install descry-codegraph
|
|
|
349
351
|
### With MCP server
|
|
350
352
|
|
|
351
353
|
```bash
|
|
352
|
-
pip install descry-codegraph[mcp]
|
|
354
|
+
pip install "descry-codegraph[mcp]"
|
|
353
355
|
```
|
|
354
356
|
|
|
355
357
|
### With Web UI
|
|
356
358
|
|
|
357
359
|
```bash
|
|
358
|
-
pip install descry-codegraph[web]
|
|
360
|
+
pip install "descry-codegraph[web]"
|
|
359
361
|
```
|
|
360
362
|
|
|
361
363
|
### With semantic search
|
|
362
364
|
|
|
363
365
|
```bash
|
|
364
|
-
pip install descry-codegraph[embeddings]
|
|
366
|
+
pip install "descry-codegraph[embeddings]"
|
|
365
367
|
```
|
|
366
368
|
|
|
367
369
|
To select `embeddinggemma-2`, install its extra instead (adds Pillow and
|
|
@@ -374,7 +376,7 @@ pip install "descry-codegraph[embeddinggemma-2]"
|
|
|
374
376
|
### Everything
|
|
375
377
|
|
|
376
378
|
```bash
|
|
377
|
-
pip install descry-codegraph[all]
|
|
379
|
+
pip install "descry-codegraph[all]"
|
|
378
380
|
```
|
|
379
381
|
|
|
380
382
|
### Choosing a torch build
|
|
@@ -428,7 +430,7 @@ Requires [uv](https://github.com/astral-sh/uv) and [just](https://github.com/cas
|
|
|
428
430
|
|
|
429
431
|
3. **Query** — All tools query the cached graph. Keyword search uses TF-IDF scoring. Semantic search uses sentence-transformer embeddings. Call-graph traversal follows edges in the graph.
|
|
430
432
|
|
|
431
|
-
4. **Freshness** — `ensure` regenerates the graph when its age exceeds `[project] max_stale_hours` (default 24), or the `--max-age-hours` flag (CLI) / `max_age_hours` argument (MCP) when one is given. The same setting drives the "STALE" badge in `descry status`. The MCP server pre-warms the graph on startup.
|
|
433
|
+
4. **Freshness** — `ensure` regenerates the graph when files it indexed changed or were removed since it was written, and when its age exceeds `[project] max_stale_hours` (default 24), or the `--max-age-hours` flag (CLI) / `max_age_hours` argument (MCP) when one is given. The same setting drives the "STALE" badge in `descry status`. The MCP server pre-warms the graph on startup.
|
|
432
434
|
|
|
433
435
|
## Design Notes
|
|
434
436
|
|
|
@@ -29,7 +29,7 @@ without forcing it on simple file-read tasks.
|
|
|
29
29
|
## Prerequisites
|
|
30
30
|
|
|
31
31
|
- Python 3.11+.
|
|
32
|
-
- `descry-codegraph` installed: `pip install descry-codegraph[all]`.
|
|
32
|
+
- `descry-codegraph` installed: `pip install "descry-codegraph[all]"`.
|
|
33
33
|
- Optional but recommended: the MCP server registered (see below).
|
|
34
34
|
- Optional: `rust-analyzer` (Rust SCIP), `scip-typescript` (TS SCIP),
|
|
35
35
|
`scip-python` (Python SCIP) for type-aware call resolution.
|
|
@@ -83,7 +83,7 @@ under the project root. Before the first query in a session:
|
|
|
83
83
|
|
|
84
84
|
```bash
|
|
85
85
|
descry status # Is there a graph? How old is it?
|
|
86
|
-
descry ensure # Regenerate if missing
|
|
86
|
+
descry ensure # Regenerate if missing, stale (max_stale_hours) or files changed
|
|
87
87
|
```
|
|
88
88
|
|
|
89
89
|
`descry ensure` is safe to call unconditionally — it no-ops if the graph is
|
|
@@ -92,12 +92,12 @@ refreshes SCIP indices and embeddings, which can take minutes on large
|
|
|
92
92
|
Rust workspaces). If the user hasn't asked for indexing and no graph exists,
|
|
93
93
|
prompt them before running `descry index`.
|
|
94
94
|
|
|
95
|
-
Graph freshness is tracked by file mtime
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
95
|
+
Graph freshness is tracked by file mtime: `descry ensure` rebuilds a graph
|
|
96
|
+
older than `[project] max_stale_hours` (24 by default), or one whose files
|
|
97
|
+
changed or were removed since it was written. A file added since is not
|
|
98
|
+
noticed: after the user adds files, run `descry index` before querying
|
|
99
|
+
again. Cached queriers, semantic searchers, and dedup caches all invalidate
|
|
100
|
+
by mtime.
|
|
101
101
|
|
|
102
102
|
## Commands — grouped by intent
|
|
103
103
|
|
{descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/claude-skill/descry/references/cli-reference.md
RENAMED
|
@@ -7,9 +7,10 @@ the detected project root. Freshness is managed via `descry status` /
|
|
|
7
7
|
## Global discovery
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
+
descry --version # installed version
|
|
10
11
|
descry health # version, graph status, SCIP/embeddings/git state
|
|
11
12
|
descry status # just the graph: exists? nodes? edges? stale?
|
|
12
|
-
descry ensure # regenerate only if missing or
|
|
13
|
+
descry ensure # regenerate only if missing, unusable, stale or files changed
|
|
13
14
|
descry index [path] # force full rebuild (SCIP + embeddings)
|
|
14
15
|
descry embedding-models # registered embedding models, and the one selected
|
|
15
16
|
```
|
|
@@ -43,8 +44,8 @@ descry quick <symbol>
|
|
|
43
44
|
## Call graph
|
|
44
45
|
|
|
45
46
|
```bash
|
|
46
|
-
descry callers <symbol> [--limit N]
|
|
47
|
-
descry callees <symbol> [--limit N]
|
|
47
|
+
descry callers <symbol> [--limit N] [--exclude-tests] # default 20
|
|
48
|
+
descry callees <symbol> [--limit N] [--exclude-tests] # default 20
|
|
48
49
|
|
|
49
50
|
descry flow <start>
|
|
50
51
|
[--direction forward|backward] # default forward
|
{descry_codegraph-1.0.2 → descry_codegraph-1.2.0}/claude-skill/descry/references/mcp-tools.md
RENAMED
|
@@ -23,7 +23,7 @@ This is descry's prompt-injection defense — preserve it when quoting.
|
|
|
23
23
|
### Freshness and diagnostics
|
|
24
24
|
- `descry_health` — version, graph status, feature availability.
|
|
25
25
|
- `descry_status` — graph existence / freshness only.
|
|
26
|
-
- `descry_ensure` — regenerate iff missing or
|
|
26
|
+
- `descry_ensure` — regenerate iff missing, unusable, stale or files it indexed changed.
|
|
27
27
|
- `descry_index(path=".")` — authoritative rebuild. A `path` below the
|
|
28
28
|
project root narrows which files are walked; the result still replaces
|
|
29
29
|
the root's graph. Paths outside the root are rejected.
|
|
@@ -35,8 +35,8 @@ This is descry's prompt-injection defense — preserve it when quoting.
|
|
|
35
35
|
- `descry_quick(symbol, full=False, brief=False)` — search + context in one.
|
|
36
36
|
|
|
37
37
|
### Call graph
|
|
38
|
-
- `descry_callers(symbol, limit=20)`
|
|
39
|
-
- `descry_callees(symbol, limit=20)`
|
|
38
|
+
- `descry_callers(symbol, limit=20, exclude_tests=False)`
|
|
39
|
+
- `descry_callees(symbol, limit=20, exclude_tests=False)`
|
|
40
40
|
- `descry_flow(start, direction="forward", depth=3, target=None, inline_threshold=100)`
|
|
41
41
|
- `descry_path(start, end, max_depth=10, direction="forward")`
|
|
42
42
|
|
|
@@ -140,9 +140,9 @@ Requires an OpenAPI spec: set `[cross_lang] openapi_path = "..."` in
|
|
|
140
140
|
- **Don't** use `descry search` for behavior-worded queries; `descry semantic`
|
|
141
141
|
is built for that and will do better.
|
|
142
142
|
- **Don't** bypass `status` on a stale graph. Out-of-date graphs
|
|
143
|
-
produce plausible-looking wrong answers. After edits
|
|
144
|
-
|
|
145
|
-
|
|
143
|
+
produce plausible-looking wrong answers. After edits, `descry ensure`
|
|
144
|
+
rebuilds a graph whose files changed or were removed; after adding
|
|
145
|
+
files, `descry index` brings the graph current.
|
|
146
146
|
- **Don't** shell out to grep when the question is structural. Even one
|
|
147
147
|
descry call beats three Greps for "who calls X".
|
|
148
148
|
|
|
@@ -54,8 +54,9 @@ answers; a call dropped as one out of the project is not among them.
|
|
|
54
54
|
|
|
55
55
|
## Keeping up with the source
|
|
56
56
|
|
|
57
|
-
An index is a snapshot. `status` says how old it is
|
|
58
|
-
again when it is older than
|
|
59
|
-
|
|
60
|
-
|
|
57
|
+
An index is a snapshot. `status` says how old it is and how many of its
|
|
58
|
+
files changed since; `ensure` builds it again when it is older than
|
|
59
|
+
`[project] max_stale_hours` or files it holds changed or were removed. An
|
|
60
|
+
index after a change parses only the files that changed, and resolves again
|
|
61
|
+
only the calls of files whose resolution read something that changed, so its
|
|
61
62
|
answers are those a full index would give.
|
|
@@ -30,7 +30,7 @@ MCP `descry_health`; web `GET /api/health`; CLI `usage: descry health [--json]`
|
|
|
30
30
|
|
|
31
31
|
## ensure
|
|
32
32
|
|
|
33
|
-
Ensure the codebase graph exists and is fresh. Call this FIRST before other descry queries. Regenerates if missing
|
|
33
|
+
Ensure the codebase graph exists and is fresh. Call this FIRST before other descry queries. Regenerates if missing, older than max_age_hours (default: the project's configured max_stale_hours), or if files it indexed changed since. Returns graph status with node/edge counts. WARNING: May take 30-60 seconds if regeneration is needed.
|
|
34
34
|
|
|
35
35
|
| parameter | type | default |
|
|
36
36
|
|---|---|---|
|
|
@@ -46,22 +46,23 @@ Check if the codebase graph exists and its freshness. Returns existence, age, an
|
|
|
46
46
|
|
|
47
47
|
No parameters.
|
|
48
48
|
|
|
49
|
-
Answer: `exists`, `age_str`, `age_hours`, `nodes`, `edges`, `languages`, `stale`, `error`, `scip` (`state`, `indexers`, `cached`), `embeddings` (`state`, `nodes`, `model`)
|
|
49
|
+
Answer: `exists`, `age_str`, `age_hours`, `nodes`, `edges`, `languages`, `stale`, `changed_since_index`, `error`, `scip` (`state`, `indexers`, `cached`), `embeddings` (`state`, `nodes`, `model`)
|
|
50
50
|
|
|
51
51
|
MCP `descry_status`; web `GET /api/status`; CLI `usage: descry status [--json]`
|
|
52
52
|
|
|
53
53
|
## callers
|
|
54
54
|
|
|
55
|
-
Find all functions/methods that call a given symbol. More reliable than grep for call relationships - distinguishes actual calls from definitions and comments. Use for impact analysis before refactoring or to understand usage patterns.
|
|
55
|
+
Find all functions/methods that call a given symbol. More reliable than grep for call relationships - distinguishes actual calls from definitions and comments. Use for impact analysis before refactoring or to understand usage patterns. Set exclude_tests=true to leave out test callers.
|
|
56
56
|
|
|
57
57
|
| parameter | type | default |
|
|
58
58
|
|---|---|---|
|
|
59
59
|
| `symbol` | string | required |
|
|
60
60
|
| `limit` | integer | 20 |
|
|
61
|
+
| `exclude_tests` | boolean | false |
|
|
61
62
|
|
|
62
63
|
Answer: `symbol`, `total`, counts, `more` (counts), `callers` / `callees` (references)
|
|
63
64
|
|
|
64
|
-
MCP `descry_callers`; web `GET /api/callers`; CLI `usage: descry callers [--json] [--limit LIMIT] symbol`
|
|
65
|
+
MCP `descry_callers`; web `GET /api/callers`; CLI `usage: descry callers [--json] [--limit LIMIT] [--exclude-tests] symbol`
|
|
65
66
|
|
|
66
67
|
`descry callers load --json`:
|
|
67
68
|
|
|
@@ -91,16 +92,17 @@ MCP `descry_callers`; web `GET /api/callers`; CLI `usage: descry callers [--json
|
|
|
91
92
|
|
|
92
93
|
## callees
|
|
93
94
|
|
|
94
|
-
Find what functions/methods a given symbol calls. Use for dependency analysis and understanding what a function relies on.
|
|
95
|
+
Find what functions/methods a given symbol calls. Use for dependency analysis and understanding what a function relies on. Set exclude_tests=true to leave out test callees.
|
|
95
96
|
|
|
96
97
|
| parameter | type | default |
|
|
97
98
|
|---|---|---|
|
|
98
99
|
| `symbol` | string | required |
|
|
99
100
|
| `limit` | integer | 20 |
|
|
101
|
+
| `exclude_tests` | boolean | false |
|
|
100
102
|
|
|
101
103
|
Answer: `symbol`, `total`, counts, `more` (counts), `callers` / `callees` (references)
|
|
102
104
|
|
|
103
|
-
MCP `descry_callees`; web `GET /api/callees`; CLI `usage: descry callees [--json] [--limit LIMIT] symbol`
|
|
105
|
+
MCP `descry_callees`; web `GET /api/callees`; CLI `usage: descry callees [--json] [--limit LIMIT] [--exclude-tests] symbol`
|
|
104
106
|
|
|
105
107
|
`descry callees main --json`:
|
|
106
108
|
|
|
@@ -38,11 +38,13 @@ def main():
|
|
|
38
38
|
p = subparsers.add_parser("callers")
|
|
39
39
|
p.add_argument("--symbol", required=True)
|
|
40
40
|
p.add_argument("--limit", type=int, default=20)
|
|
41
|
+
p.add_argument("--exclude-tests", action="store_true")
|
|
41
42
|
|
|
42
43
|
# callees
|
|
43
44
|
p = subparsers.add_parser("callees")
|
|
44
45
|
p.add_argument("--symbol", required=True)
|
|
45
46
|
p.add_argument("--limit", type=int, default=20)
|
|
47
|
+
p.add_argument("--exclude-tests", action="store_true")
|
|
46
48
|
|
|
47
49
|
# context
|
|
48
50
|
p = subparsers.add_parser("context")
|
|
@@ -157,9 +159,9 @@ async def dispatch(args):
|
|
|
157
159
|
elif cmd == "status":
|
|
158
160
|
return await service.status()
|
|
159
161
|
elif cmd == "callers":
|
|
160
|
-
return await service.callers(args.symbol, args.limit)
|
|
162
|
+
return await service.callers(args.symbol, args.limit, args.exclude_tests)
|
|
161
163
|
elif cmd == "callees":
|
|
162
|
-
return await service.callees(args.symbol, args.limit)
|
|
164
|
+
return await service.callees(args.symbol, args.limit, args.exclude_tests)
|
|
163
165
|
elif cmd == "context":
|
|
164
166
|
return await service.context(
|
|
165
167
|
args.symbol,
|
|
@@ -72,7 +72,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
72
72
|
label: "Descry Ensure",
|
|
73
73
|
description:
|
|
74
74
|
"Ensure the codebase graph exists and is fresh. Call this FIRST before other descry queries. " +
|
|
75
|
-
"Regenerates if missing
|
|
75
|
+
"Regenerates if missing, older than max_age_hours, or if files it indexed changed since. Returns graph status with node/edge counts. " +
|
|
76
76
|
"WARNING: May take 30-60 seconds if regeneration is needed.",
|
|
77
77
|
parameters: Type.Object({
|
|
78
78
|
max_age_hours: Type.Optional(Type.Number({ description: "Max graph age in hours before regeneration (default: the project's max_stale_hours)" })),
|
|
@@ -124,10 +124,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
124
124
|
parameters: Type.Object({
|
|
125
125
|
symbol: Type.String({ description: "A node ID, or a symbol name" }),
|
|
126
126
|
limit: Type.Optional(Type.Number({ description: "Max results", default: 20 })),
|
|
127
|
+
exclude_tests: Type.Optional(Type.Boolean({ description: "Exclude test files", default: false })),
|
|
127
128
|
}),
|
|
128
129
|
async execute(_toolCallId, params, signal) {
|
|
129
130
|
const args = ["--symbol", params.symbol];
|
|
130
131
|
if (params.limit !== undefined) args.push("--limit", String(params.limit));
|
|
132
|
+
if (params.exclude_tests) args.push("--exclude-tests");
|
|
131
133
|
const result = await runDescry("callers", args, signal);
|
|
132
134
|
return { content: [{ type: "text", text: result }] };
|
|
133
135
|
},
|
|
@@ -142,10 +144,12 @@ export default function (pi: ExtensionAPI) {
|
|
|
142
144
|
parameters: Type.Object({
|
|
143
145
|
symbol: Type.String({ description: "A node ID, or a symbol name" }),
|
|
144
146
|
limit: Type.Optional(Type.Number({ description: "Max results", default: 20 })),
|
|
147
|
+
exclude_tests: Type.Optional(Type.Boolean({ description: "Exclude test files", default: false })),
|
|
145
148
|
}),
|
|
146
149
|
async execute(_toolCallId, params, signal) {
|
|
147
150
|
const args = ["--symbol", params.symbol];
|
|
148
151
|
if (params.limit !== undefined) args.push("--limit", String(params.limit));
|
|
152
|
+
if (params.exclude_tests) args.push("--exclude-tests");
|
|
149
153
|
const result = await runDescry("callees", args, signal);
|
|
150
154
|
return { content: [{ type: "text", text: result }] };
|
|
151
155
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "descry-codegraph"
|
|
3
|
-
|
|
3
|
+
dynamic = ["version"]
|
|
4
4
|
description = "Codebase knowledge graph: polyglot indexer, semantic search, call-graph analysis"
|
|
5
5
|
requires-python = ">=3.11"
|
|
6
6
|
authors = [{name = "Christian Haynes"}]
|
|
@@ -72,5 +72,8 @@ extend-exclude = ["src/descry/scip/pb2.py"]
|
|
|
72
72
|
requires = ["hatchling>=1.27"]
|
|
73
73
|
build-backend = "hatchling.build"
|
|
74
74
|
|
|
75
|
+
[tool.hatch.version]
|
|
76
|
+
path = "src/descry/__init__.py"
|
|
77
|
+
|
|
75
78
|
[tool.hatch.build.targets.wheel]
|
|
76
79
|
packages = ["src/descry"]
|