descry-codegraph 1.0.1__tar.gz → 1.0.2__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.
Files changed (217) hide show
  1. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/CHANGELOG.md +20 -0
  2. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/PKG-INFO +2 -2
  3. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/README.md +1 -1
  4. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/pyproject.toml +1 -1
  5. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/__init__.py +1 -1
  6. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/cli.py +9 -0
  7. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/mcp_server.py +2 -2
  8. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/resolver.py +63 -11
  9. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/rust_parser.py +5 -1
  10. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_cli.py +23 -0
  11. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_generate.py +93 -0
  12. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_mcp.py +1 -1
  13. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/.github/assets/01-landing.png +0 -0
  14. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/.github/workflows/ci.yml +0 -0
  15. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/.github/workflows/release.yml +0 -0
  16. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/.gitignore +0 -0
  17. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/AGENTS.md +0 -0
  18. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/CONTRACT.md +0 -0
  19. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/LICENSE +0 -0
  20. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/SECURITY.md +0 -0
  21. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/THIRD-PARTY-NOTICES.md +0 -0
  22. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/claude-skill/README.md +0 -0
  23. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/claude-skill/descry/SKILL.md +0 -0
  24. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/claude-skill/descry/references/cli-reference.md +0 -0
  25. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/claude-skill/descry/references/mcp-tools.md +0 -0
  26. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/claude-skill/descry/references/recipes.md +0 -0
  27. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/docs/CERTAINTY.md +0 -0
  28. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/docs/TOOLS.md +0 -0
  29. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/docs/UPGRADING.md +0 -0
  30. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/justfile +0 -0
  31. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/pi-extension/README.md +0 -0
  32. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/pi-extension/descry-cli.py +0 -0
  33. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/pi-extension/descry-tools.ts +0 -0
  34. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/_answers.py +0 -0
  35. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/_comments.py +0 -0
  36. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/_env.py +0 -0
  37. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/_files.py +0 -0
  38. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/_graph.py +0 -0
  39. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/_parse_cache.py +0 -0
  40. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/_parsing.py +0 -0
  41. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/_reads.py +0 -0
  42. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/_stdlib.py +0 -0
  43. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/_streams.py +0 -0
  44. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/clang_parser.py +0 -0
  45. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/cross_lang.py +0 -0
  46. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/dart_parser.py +0 -0
  47. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/dotnet_parser.py +0 -0
  48. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/embeddings.py +0 -0
  49. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/generate.py +0 -0
  50. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/git_history.py +0 -0
  51. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/go_parser.py +0 -0
  52. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/handlers.py +0 -0
  53. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/java_parser.py +0 -0
  54. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/php_parser.py +0 -0
  55. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/proto_parser.py +0 -0
  56. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/python_parser.py +0 -0
  57. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/query.py +0 -0
  58. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/ruby_parser.py +0 -0
  59. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/__init__.py +0 -0
  60. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapter.py +0 -0
  61. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/__init__.py +0 -0
  62. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/_empty_environment.json +0 -0
  63. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/_java_compat.init.gradle +0 -0
  64. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/clang.py +0 -0
  65. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/dart.py +0 -0
  66. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/dotnet.py +0 -0
  67. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/go.py +0 -0
  68. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/java.py +0 -0
  69. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/php.py +0 -0
  70. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/python.py +0 -0
  71. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/ruby.py +0 -0
  72. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/rust.py +0 -0
  73. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/adapters/typescript.py +0 -0
  74. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/cache.py +0 -0
  75. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/parser.py +0 -0
  76. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/pb2.py +0 -0
  77. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/scip/support.py +0 -0
  78. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/c.json +0 -0
  79. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/cpp.json +0 -0
  80. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/dart.json +0 -0
  81. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/dotnet.json +0 -0
  82. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/go.json +0 -0
  83. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/java.json +0 -0
  84. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/node.json +0 -0
  85. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/php.json +0 -0
  86. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/python.json +0 -0
  87. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/ruby.json +0 -0
  88. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/rust.json +0 -0
  89. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/stdlib/typescript.json +0 -0
  90. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/ts_parser.py +0 -0
  91. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/web/__init__.py +0 -0
  92. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/web/server.py +0 -0
  93. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/web/web/index.html +0 -0
  94. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/src/descry/web/web/style.css +0 -0
  95. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/__init__.py +0 -0
  96. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/conftest.py +0 -0
  97. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/eval/README.md +0 -0
  98. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/eval/__init__.py +0 -0
  99. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/eval/compare.py +0 -0
  100. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/eval/corpus.py +0 -0
  101. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/eval/metrics.py +0 -0
  102. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/eval/registry.py +0 -0
  103. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/eval/results/results-descry.json +0 -0
  104. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/eval/results/results-ripgrep.json +0 -0
  105. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/fixtures/small_graph.json +0 -0
  106. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/c/Makefile +0 -0
  107. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/c/expected.json +0 -0
  108. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/c/io.c +0 -0
  109. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/c/io.h +0 -0
  110. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/c/main.c +0 -0
  111. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/c/order.c +0 -0
  112. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/cpp/Makefile +0 -0
  113. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/cpp/expected.json +0 -0
  114. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/cpp/main.cpp +0 -0
  115. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/cpp/models.hpp +0 -0
  116. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/cpp/reader.hpp +0 -0
  117. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/csharp/Gt.csproj +0 -0
  118. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/csharp/Io.cs +0 -0
  119. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/csharp/Models.cs +0 -0
  120. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/csharp/Program.cs +0 -0
  121. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/csharp/expected.json +0 -0
  122. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/dart/bin/main.dart +0 -0
  123. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/dart/expected.json +0 -0
  124. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/dart/lib/io.dart +0 -0
  125. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/dart/lib/models.dart +0 -0
  126. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/dart/pubspec.yaml +0 -0
  127. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/go/expected.json +0 -0
  128. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/go/go.mod +0 -0
  129. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/go/io.go +0 -0
  130. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/go/main.go +0 -0
  131. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/go/models.go +0 -0
  132. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/java/expected.json +0 -0
  133. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/Base.java +0 -0
  134. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/Io.java +0 -0
  135. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/Main.java +0 -0
  136. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/Order.java +0 -0
  137. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/Reader.java +0 -0
  138. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/java/src/gt/User.java +0 -0
  139. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/javascript/expected.json +0 -0
  140. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/javascript/package.json +0 -0
  141. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/javascript/src/io.js +0 -0
  142. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/javascript/src/main.js +0 -0
  143. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/javascript/src/models.js +0 -0
  144. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/php/composer.json +0 -0
  145. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/php/expected.json +0 -0
  146. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/php/src/Io.php +0 -0
  147. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/php/src/Models.php +0 -0
  148. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/php/src/main.php +0 -0
  149. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/python/app/__init__.py +0 -0
  150. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/python/app/io.py +0 -0
  151. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/python/app/main.py +0 -0
  152. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/python/app/models.py +0 -0
  153. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/python/expected.json +0 -0
  154. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/python/pyproject.toml +0 -0
  155. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/ruby/Gemfile +0 -0
  156. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/ruby/expected.json +0 -0
  157. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/ruby/lib/io.rb +0 -0
  158. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/ruby/lib/main.rb +0 -0
  159. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/ruby/lib/models.rb +0 -0
  160. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/rust/Cargo.toml +0 -0
  161. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/rust/expected.json +0 -0
  162. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/rust/src/io.rs +0 -0
  163. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/rust/src/main.rs +0 -0
  164. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/rust/src/models.rs +0 -0
  165. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/typescript/expected.json +0 -0
  166. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/typescript/package.json +0 -0
  167. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/typescript/src/io.ts +0 -0
  168. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/typescript/src/main.ts +0 -0
  169. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/ground_truth/typescript/src/models.ts +0 -0
  170. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_backtracking.py +0 -0
  171. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_clang_parser.py +0 -0
  172. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_config.py +0 -0
  173. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_cross_lang.py +0 -0
  174. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_dart_parser.py +0 -0
  175. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_docs.py +0 -0
  176. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_dotnet_parser.py +0 -0
  177. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_embeddings.py +0 -0
  178. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_git_history.py +0 -0
  179. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_go_parser.py +0 -0
  180. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_ground_truth.py +0 -0
  181. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_handlers.py +0 -0
  182. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_hardening.py +0 -0
  183. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_interfaces.py +0 -0
  184. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_java_parser.py +0 -0
  185. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_non_regular_files.py +0 -0
  186. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_parse_cache.py +0 -0
  187. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_php_parser.py +0 -0
  188. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_query.py +0 -0
  189. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_resolve_cache.py +0 -0
  190. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_ruby_parser.py +0 -0
  191. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_scip.py +0 -0
  192. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_scip_cache.py +0 -0
  193. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_scip_clang.py +0 -0
  194. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_scip_dart.py +0 -0
  195. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_scip_dotnet.py +0 -0
  196. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_scip_go.py +0 -0
  197. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_scip_java.py +0 -0
  198. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_scip_php.py +0 -0
  199. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_scip_ruby.py +0 -0
  200. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_stdlib.py +0 -0
  201. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_web_server.py +0 -0
  202. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tests/test_written_through.py +0 -0
  203. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/docs/gen_tools.py +0 -0
  204. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/README.md +0 -0
  205. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/common.py +0 -0
  206. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_c.py +0 -0
  207. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_cpp.py +0 -0
  208. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_dart.py +0 -0
  209. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_dotnet.py +0 -0
  210. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_go.py +0 -0
  211. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_java.py +0 -0
  212. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_node.py +0 -0
  213. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_php.py +0 -0
  214. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_python.py +0 -0
  215. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_ruby.py +0 -0
  216. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_rust.py +0 -0
  217. {descry_codegraph-1.0.1 → descry_codegraph-1.0.2}/tools/stdlib/gen_typescript.py +0 -0
@@ -4,6 +4,26 @@ 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.0.2] — 2026-10-31
8
+
9
+ ### Fixed
10
+
11
+ - Rust glob re-exports (`pub use m::*`) that reach a module by several
12
+ routes, or lead back round a cycle, no longer make indexing exponential:
13
+ each name a glob brings, and each type alias, is looked up once per
14
+ file.
15
+ - Rust: `<Self>::f(x)` is read as `Self::f(x)`; it, and a crate-root path
16
+ `::f(x)` with an argument of a project type, stopped the index.
17
+ - Rust: indexing a nested `vec![vec![..]; n]` twice stopped the index.
18
+ - Rust: a `static` or `const` in a `quote!` template, its type written
19
+ with `#` interpolations, stopped the index.
20
+ - MCP: arguments a tool cannot read are refused naming what is wrong with
21
+ each (`terms: Field required`), not the field alone.
22
+ - CLI: without a terminal on stderr, loading the embedding model prints no
23
+ progress bars or Hugging Face Hub notices; `HF_HUB_DISABLE_PROGRESS_BARS`,
24
+ `HF_HUB_VERBOSITY` and `TRANSFORMERS_VERBOSITY` set by the user are kept.
25
+ - README: `[timeouts] index_minutes = 0` is no time limit.
26
+
7
27
  ## [1.0.1] — 2026-10-30
8
28
 
9
29
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: descry-codegraph
3
- Version: 1.0.1
3
+ Version: 1.0.2
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
@@ -308,7 +308,7 @@ timeout = 30
308
308
  scip_minutes = 30 # per indexer; 0 = unlimited
309
309
  embedding_seconds = 60 # MCP and web answer `loading` past it; the CLI waits
310
310
  query_ms = 4000 # 0 = no time limit
311
- index_minutes = 30 # Timeout for `descry index` subprocess
311
+ index_minutes = 30 # Timeout for `descry index` subprocess; 0 = unlimited
312
312
 
313
313
  [query]
314
314
  max_depth = 3
@@ -247,7 +247,7 @@ timeout = 30
247
247
  scip_minutes = 30 # per indexer; 0 = unlimited
248
248
  embedding_seconds = 60 # MCP and web answer `loading` past it; the CLI waits
249
249
  query_ms = 4000 # 0 = no time limit
250
- index_minutes = 30 # Timeout for `descry index` subprocess
250
+ index_minutes = 30 # Timeout for `descry index` subprocess; 0 = unlimited
251
251
 
252
252
  [query]
253
253
  max_depth = 3
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "descry-codegraph"
3
- version = "1.0.1"
3
+ version = "1.0.2"
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"}]
@@ -1,4 +1,4 @@
1
1
  """Descry — Codebase knowledge graph: polyglot indexer, semantic search, call-graph analysis."""
2
2
 
3
- __version__ = "1.0.1"
3
+ __version__ = "1.0.2"
4
4
  __all__ = ["__version__"]
@@ -11,6 +11,7 @@ Usage:
11
11
  import argparse
12
12
  import asyncio
13
13
  import json
14
+ import os
14
15
  import sys
15
16
 
16
17
  from descry._answers import fail
@@ -516,6 +517,14 @@ def build_parser():
516
517
 
517
518
  def main():
518
519
  write_utf8()
520
+ if not sys.stderr.isatty():
521
+ # Scripted use: no model-loading progress bars or Hub notices.
522
+ for name, value in (
523
+ ("HF_HUB_DISABLE_PROGRESS_BARS", "1"),
524
+ ("HF_HUB_VERBOSITY", "error"),
525
+ ("TRANSFORMERS_VERBOSITY", "error"),
526
+ ):
527
+ os.environ.setdefault(name, value)
519
528
  parser = build_parser()
520
529
  args = parser.parse_args()
521
530
 
@@ -115,13 +115,13 @@ class _Server(MCPServer):
115
115
  if isinstance(exc.__cause__, ValidationError):
116
116
  fields = sorted(
117
117
  {
118
- ".".join(str(part) for part in err["loc"])
118
+ f"{'.'.join(str(part) for part in err['loc'])}: {err['msg']}"
119
119
  for err in exc.__cause__.errors()
120
120
  }
121
121
  )
122
122
  answer = fail(
123
123
  "invalid",
124
- f"Invalid arguments for {name}: {', '.join(fields)}.",
124
+ f"Invalid arguments for {name}: {'; '.join(fields)}.",
125
125
  )
126
126
  return _answered(json.dumps(public(answer), indent=2), answer)
127
127
  raise
@@ -1297,7 +1297,9 @@ class CallResolver:
1297
1297
  # signature a call of it is of
1298
1298
  "overloads",
1299
1299
  "reaches", # file ID -> the files its includes reach (C/C++)
1300
+ "rust_aliases", # (Rust module, name) -> see _alias_in
1300
1301
  "rust_in_scope", # Rust scope ID -> the modules named there
1302
+ "rust_used", # (Rust module, name) -> see _rust_used
1301
1303
  "rust_uses", # Rust scope ID -> what the `use`s in force bind
1302
1304
  "shared_declaration", # candidate node IDs -> node ID or None
1303
1305
  # Language -> the last name segments of the types and functions its
@@ -1327,6 +1329,8 @@ class CallResolver:
1327
1329
  "_forwarding",
1328
1330
  "open_aliases",
1329
1331
  "standard",
1332
+ "_rust_walked",
1333
+ "_rust_begun",
1330
1334
  )
1331
1335
 
1332
1336
  def begin_file(self):
@@ -1593,6 +1597,9 @@ class CallResolver:
1593
1597
  builder.rust_mods, files
1594
1598
  )
1595
1599
  self._importing = set() # (scope ID, name) of the Rust `use`s being read
1600
+ self._rust_cuts = 0 # times a Rust cycle guard stopped a walk
1601
+ self._rust_walked = {} # see _rust_keep
1602
+ self._rust_begun = [] # see _rust_recall
1596
1603
  # A module is importable by its path below its topmost package and,
1597
1604
  # through namespace packages, by any longer path no other module owns.
1598
1605
  for top, parts, file_id in py_files:
@@ -2104,10 +2111,11 @@ class CallResolver:
2104
2111
  elif (
2105
2112
  verdict == (None, _EXTERNAL)
2106
2113
  and self._path_call
2114
+ and (split := _split_callee(callee))[0]
2107
2115
  and (owner := self._receiver_type())
2108
2116
  ):
2109
2117
  # An outside trait's path: the receiver's project impl of it.
2110
- path, name = _split_callee(callee)
2118
+ path, name = split
2111
2119
  own = [
2112
2120
  m
2113
2121
  for m in self._rust_trait_methods(owner, name, path[-1])
@@ -3124,7 +3132,9 @@ class CallResolver:
3124
3132
  (target,),
3125
3133
  )
3126
3134
  found = None
3127
- if (scope_id, name) not in self._importing:
3135
+ if (scope_id, name) in self._importing:
3136
+ self._rust_cuts += 1
3137
+ else:
3128
3138
  # A `use` may lead back to itself through the module tree.
3129
3139
  self._importing.add((scope_id, name))
3130
3140
  try:
@@ -3357,11 +3367,42 @@ class CallResolver:
3357
3367
  ]
3358
3368
  return defined or found
3359
3369
 
3370
+ def _rust_recall(self, memo, key, seen):
3371
+ """``[value]`` kept for the Rust walk through `use`s and globs for
3372
+ ``key`` whose cycle guard holds ``seen`` (see `_rust_keep`); else
3373
+ None, and the walk is begun."""
3374
+ if key in memo:
3375
+ return [memo[key]]
3376
+ if seen and key in self._rust_walked:
3377
+ self._rust_cuts += 1
3378
+ return [self._rust_walked[key]]
3379
+ self._rust_begun.append((self._rust_cuts, self._rust_walked))
3380
+ if not seen:
3381
+ self._rust_walked = {}
3382
+ return None
3383
+
3384
+ def _rust_keep(self, memo, key, seen, found):
3385
+ """``found``, what the walk `_rust_recall` began gives: kept in
3386
+ ``memo`` for the file; where a cycle guard cut it short, only until
3387
+ the walk that began with no ``seen`` ends. A module that globs reach
3388
+ by several routes is then walked once."""
3389
+ cuts, outer = self._rust_begun.pop()
3390
+ if not seen:
3391
+ self._rust_walked = outer
3392
+ if self._rust_cuts == cuts:
3393
+ memo[key] = found
3394
+ elif seen:
3395
+ self._rust_walked[key] = found
3396
+ return found
3397
+
3360
3398
  def _rust_used(self, module, segment, seen):
3361
3399
  """What a `use` of the Rust module ``module`` binds ``segment`` to,
3362
3400
  a path from the module or from a crate, else what each glob `use`
3363
3401
  of the module's own does: IDs, ``"external"`` where one leads
3364
3402
  outside the project. ``seen`` as `_rust_path`'s."""
3403
+ key = (module, segment)
3404
+ if kept := self._rust_recall(self.rust_used, key, seen):
3405
+ return kept[0]
3365
3406
  uses = self._uses(module)
3366
3407
  alternatives = self.builder.rust_use_alternatives.get((module, segment))
3367
3408
  written = [uses[segment]] if segment in uses else []
@@ -3376,16 +3417,18 @@ class CallResolver:
3376
3417
  if segment in uses and not self._rust_rooted(target, module):
3377
3418
  held = self._imported(segment, module)
3378
3419
  elif self._rust_rooted(target, module):
3379
- if (module, segment) not in seen:
3380
- followed = seen | {(module, segment)}
3381
- held = self._rust_path(target.split("::"), module, followed)
3420
+ if key in seen:
3421
+ self._rust_cuts += 1
3422
+ else:
3423
+ held = self._rust_path(target.split("::"), module, seen | {key})
3382
3424
  else:
3383
3425
  # A glob of another crate's module may bring the name.
3384
3426
  held = _EXTERNAL
3385
3427
  if held == _EXTERNAL:
3386
- return _EXTERNAL
3428
+ hits = _EXTERNAL
3429
+ break
3387
3430
  hits += held or []
3388
- return hits
3431
+ return self._rust_keep(self.rust_used, key, seen, hits)
3389
3432
 
3390
3433
  def _rust_library(self, name, scope_id):
3391
3434
  """The root of the library of the project crate ``name`` written in
@@ -4820,7 +4863,7 @@ class CallResolver:
4820
4863
  value = self._called(member, value if len(value) > 2 else value[1])
4821
4864
  value = value[1] if value and value[0] == "pointer" else value
4822
4865
  continue
4823
- if step == "[]" and isinstance(value, tuple):
4866
+ if step == "[]" and isinstance(value, tuple) and value[0] != "literal":
4824
4867
  # A subscript gives what the type's `operator[]` returns, in
4825
4868
  # Rust its `Index` impl's `Output`, the element an iterator
4826
4869
  # gives where the index decides it: by the data for a
@@ -8152,17 +8195,24 @@ class CallResolver:
8152
8195
  found = self.builder.rust_alias_types.get((module, name))
8153
8196
  if found:
8154
8197
  return module, name, _rust_declared(found)
8198
+ key = (module, name)
8199
+ if kept := self._rust_recall(self.rust_aliases, key, seen):
8200
+ return kept[0]
8155
8201
  uses = self._uses(module)
8156
8202
  written = [uses[name]] if name in uses else []
8157
8203
  written = written or [
8158
8204
  f"{path[:-1]}{name}" for path in uses.values() if path[-3:] == "::*"
8159
8205
  ]
8206
+ hit = None
8160
8207
  for target in written:
8161
8208
  *qualifier, leaf = target.split("::")
8162
8209
  if qualifier and self._rust_child(module, qualifier[0]):
8163
8210
  qualifier = ["self", *qualifier]
8164
8211
  path = "::".join([*qualifier, leaf])
8165
- if not qualifier or (module, path) in seen:
8212
+ if not qualifier:
8213
+ continue
8214
+ if (module, path) in seen:
8215
+ self._rust_cuts += 1
8166
8216
  continue
8167
8217
  if not self._rust_rooted(path, module):
8168
8218
  continue
@@ -8170,8 +8220,10 @@ class CallResolver:
8170
8220
  for scope in held if isinstance(held, list) else ():
8171
8221
  hit = self._alias_in(scope, leaf, seen | {(module, path)})
8172
8222
  if hit:
8173
- return hit
8174
- return None
8223
+ break
8224
+ if hit:
8225
+ break
8226
+ return self._rust_keep(self.rust_aliases, key, seen, hit)
8175
8227
 
8176
8228
  def _alias_value(self, alias, written, scope_id, receiver):
8177
8229
  """Value of the type ``written`` in ``scope_id`` that names the Rust
@@ -50,7 +50,7 @@ _RUST_STRING_LET_RE = re.compile(
50
50
 
51
51
  _RUST_CONST_RE = re.compile(
52
52
  r"\b(?:const|static)\s+(?:mut\s+)?(?P<name>[A-Z][A-Z0-9_]*)\s*:\s*"
53
- r"(?P<type>[^=;().]+?)\s*="
53
+ r"(?P<type>[^=;().#]+?)\s*="
54
54
  )
55
55
 
56
56
 
@@ -1960,6 +1960,10 @@ class RustParser(BaseParser):
1960
1960
  # with its arguments.
1961
1961
  typed = re.fullmatch(r"(\w+)::<(.+)>::(\w+)", callee)
1962
1962
  typed = typed and f"{typed[1]}<{typed[2]}>.{typed[3]}"
1963
+ # `<Self>::f` is `Self::f`.
1964
+ closed = callee[:1] == "<" and _angle_end(callee, 0)
1965
+ if closed and callee[closed + 1 : closed + 3] == "::":
1966
+ callee = callee[1:closed] + callee[closed + 1 :]
1963
1967
  # `parse::<T>` calls `parse`; the type arguments are the
1964
1968
  # call site's, not part of the callee's name.
1965
1969
  callee = _strip_generics(callee)
@@ -65,6 +65,29 @@ class TestCliNoCommand:
65
65
  assert result.returncode == 1
66
66
 
67
67
 
68
+ class TestCliHubOutput:
69
+ _NAMES = (
70
+ "HF_HUB_DISABLE_PROGRESS_BARS",
71
+ "HF_HUB_VERBOSITY",
72
+ "TRANSFORMERS_VERBOSITY",
73
+ )
74
+
75
+ @pytest.mark.parametrize("terminal", [False, True])
76
+ def test_scripted_use_quiets_model_loading(self, monkeypatch, terminal):
77
+ """Without a terminal on stderr, model loading shows no progress bars
78
+ or Hub notices; a value the user set is kept."""
79
+ for name in self._NAMES:
80
+ monkeypatch.delenv(name, raising=False)
81
+ monkeypatch.setenv("HF_HUB_VERBOSITY", "info")
82
+ monkeypatch.setattr(sys.stderr, "isatty", lambda: terminal)
83
+ monkeypatch.setattr(sys, "argv", ["descry"])
84
+ with pytest.raises(SystemExit):
85
+ cli.main()
86
+ assert [os.environ.get(name) for name in self._NAMES] == (
87
+ [None, "info", None] if terminal else ["1", "info", "error"]
88
+ )
89
+
90
+
68
91
  class TestCliArguments:
69
92
  @pytest.mark.parametrize(
70
93
  "args", [["callers", "x", "--limit", "ten"], ["search", "x", "--frob", "1"]]
@@ -4398,6 +4398,99 @@ class TestRustCallResolution:
4398
4398
  "FILE:src/lib.rs::Vec2::new"
4399
4399
  ]
4400
4400
 
4401
+ def test_qualified_self_path_is_the_type_path(self, tmp_path):
4402
+ """`<Self>::make()` and `<W>::make()` call `W::make`."""
4403
+ builder = _index(
4404
+ tmp_path,
4405
+ {
4406
+ "src/lib.rs": """
4407
+ pub struct W;
4408
+ impl W {
4409
+ pub fn make() -> W {
4410
+ W
4411
+ }
4412
+ pub fn both() {
4413
+ <Self>::make();
4414
+ <W>::make();
4415
+ }
4416
+ }
4417
+ """
4418
+ },
4419
+ )
4420
+ assert _calls(builder, "FILE:src/lib.rs::W::both") == [
4421
+ "FILE:src/lib.rs::W::make",
4422
+ "FILE:src/lib.rs::W::make",
4423
+ ]
4424
+
4425
+ def test_crate_root_path_on_project_argument_indexes(self, tmp_path):
4426
+ """`::try_from(x)`, a Rust 2015 crate-root path, names no trait: an
4427
+ argument of a project type does not make it one."""
4428
+ builder = _index(
4429
+ tmp_path,
4430
+ {
4431
+ "src/lib.rs": """
4432
+ pub struct Sl;
4433
+ pub struct Arr;
4434
+ impl TryFrom<&Sl> for Arr {
4435
+ type Error = ();
4436
+ fn try_from(value: &Sl) -> Result<Self, ()> {
4437
+ Err(())
4438
+ }
4439
+ }
4440
+ impl TryFrom<&mut Sl> for Arr {
4441
+ type Error = ();
4442
+ fn try_from(value: &mut Sl) -> Result<Self, ()> {
4443
+ ::try_from(&*value)
4444
+ }
4445
+ }
4446
+ """
4447
+ },
4448
+ )
4449
+ assert _calls(builder, "FILE:src/lib.rs::Arr::try_from#2") == []
4450
+
4451
+ def test_index_of_nested_vec_literal_indexes(self, tmp_path):
4452
+ """`data[i][j].go()` on `vec![vec![P; r]; c]` reads the inner
4453
+ literal's element, not a member of the outer literal."""
4454
+ builder = _index(
4455
+ tmp_path,
4456
+ {
4457
+ "src/lib.rs": """
4458
+ #[derive(Clone)]
4459
+ pub struct P;
4460
+ impl P {
4461
+ pub fn go(&self) {}
4462
+ }
4463
+ pub fn grid(r: usize, c: usize) {
4464
+ let data = vec![vec![P; r]; c];
4465
+ data[0][0].go();
4466
+ }
4467
+ """
4468
+ },
4469
+ )
4470
+ assert _calls(builder, "FILE:src/lib.rs::grid") == ["REF:go"]
4471
+
4472
+ def test_static_in_quote_template_has_no_type(self, tmp_path):
4473
+ """`static CELL: #path::#ty = ...;` in a `quote!` template writes no
4474
+ type: `#` interpolates a variable."""
4475
+ builder = _index(
4476
+ tmp_path,
4477
+ {
4478
+ "src/lib.rs": """
4479
+ pub struct Cell;
4480
+ impl Cell {
4481
+ pub fn get_or_set(&self) {}
4482
+ }
4483
+ pub fn gen(p: u8, cell_type: u8) {
4484
+ quote! {
4485
+ static CELL: #p::utility::#cell_type = #p::utility::#cell_type::new();
4486
+ CELL.get_or_set(|| {});
4487
+ }
4488
+ }
4489
+ """
4490
+ },
4491
+ )
4492
+ assert _calls(builder, "FILE:src/lib.rs::gen") == ["REF:CELL.get_or_set"]
4493
+
4401
4494
  def test_a_name_only_hit_does_not_type_its_result(self, tmp_path):
4402
4495
  """`m.start()` where `m` is what `find_at` yields: `find_at` fits
4403
4496
  by name only on a receiver no project type owns, so what it
@@ -294,7 +294,7 @@ class TestLifespan:
294
294
  result = await mod.mcp.call_tool("descry_callees", {"symbol": 42})
295
295
  assert result.is_error
296
296
  assert result.structured_content == {
297
- "error": "Invalid arguments for descry_callees: symbol.",
297
+ "error": "Invalid arguments for descry_callees: symbol: Input should be a valid string.",
298
298
  "reason": "invalid",
299
299
  }
300
300