descry-codegraph 1.0.0__tar.gz → 1.0.1__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.0/CLAUDE.md → descry_codegraph-1.0.1/AGENTS.md +3 -3
  2. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/CHANGELOG.md +12 -0
  3. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/PKG-INFO +1 -1
  4. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/pyproject.toml +1 -1
  5. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/__init__.py +1 -1
  6. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/handlers.py +1 -1
  7. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_backtracking.py +91 -64
  8. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_generate.py +39 -31
  9. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_ground_truth.py +4 -1
  10. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_web_server.py +4 -4
  11. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/.github/assets/01-landing.png +0 -0
  12. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/.github/workflows/ci.yml +0 -0
  13. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/.github/workflows/release.yml +0 -0
  14. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/.gitignore +0 -0
  15. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/CONTRACT.md +0 -0
  16. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/LICENSE +0 -0
  17. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/README.md +0 -0
  18. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/SECURITY.md +0 -0
  19. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/THIRD-PARTY-NOTICES.md +0 -0
  20. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/claude-skill/README.md +0 -0
  21. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/claude-skill/descry/SKILL.md +0 -0
  22. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/claude-skill/descry/references/cli-reference.md +0 -0
  23. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/claude-skill/descry/references/mcp-tools.md +0 -0
  24. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/claude-skill/descry/references/recipes.md +0 -0
  25. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/docs/CERTAINTY.md +0 -0
  26. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/docs/TOOLS.md +0 -0
  27. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/docs/UPGRADING.md +0 -0
  28. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/justfile +0 -0
  29. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/pi-extension/README.md +0 -0
  30. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/pi-extension/descry-cli.py +0 -0
  31. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/pi-extension/descry-tools.ts +0 -0
  32. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/_answers.py +0 -0
  33. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/_comments.py +0 -0
  34. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/_env.py +0 -0
  35. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/_files.py +0 -0
  36. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/_graph.py +0 -0
  37. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/_parse_cache.py +0 -0
  38. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/_parsing.py +0 -0
  39. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/_reads.py +0 -0
  40. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/_stdlib.py +0 -0
  41. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/_streams.py +0 -0
  42. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/clang_parser.py +0 -0
  43. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/cli.py +0 -0
  44. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/cross_lang.py +0 -0
  45. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/dart_parser.py +0 -0
  46. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/dotnet_parser.py +0 -0
  47. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/embeddings.py +0 -0
  48. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/generate.py +0 -0
  49. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/git_history.py +0 -0
  50. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/go_parser.py +0 -0
  51. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/java_parser.py +0 -0
  52. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/mcp_server.py +0 -0
  53. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/php_parser.py +0 -0
  54. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/proto_parser.py +0 -0
  55. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/python_parser.py +0 -0
  56. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/query.py +0 -0
  57. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/resolver.py +0 -0
  58. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/ruby_parser.py +0 -0
  59. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/rust_parser.py +0 -0
  60. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/__init__.py +0 -0
  61. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapter.py +0 -0
  62. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/__init__.py +0 -0
  63. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/_empty_environment.json +0 -0
  64. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/_java_compat.init.gradle +0 -0
  65. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/clang.py +0 -0
  66. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/dart.py +0 -0
  67. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/dotnet.py +0 -0
  68. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/go.py +0 -0
  69. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/java.py +0 -0
  70. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/php.py +0 -0
  71. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/python.py +0 -0
  72. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/ruby.py +0 -0
  73. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/rust.py +0 -0
  74. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/adapters/typescript.py +0 -0
  75. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/cache.py +0 -0
  76. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/parser.py +0 -0
  77. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/pb2.py +0 -0
  78. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/scip/support.py +0 -0
  79. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/c.json +0 -0
  80. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/cpp.json +0 -0
  81. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/dart.json +0 -0
  82. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/dotnet.json +0 -0
  83. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/go.json +0 -0
  84. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/java.json +0 -0
  85. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/node.json +0 -0
  86. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/php.json +0 -0
  87. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/python.json +0 -0
  88. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/ruby.json +0 -0
  89. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/rust.json +0 -0
  90. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/stdlib/typescript.json +0 -0
  91. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/ts_parser.py +0 -0
  92. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/web/__init__.py +0 -0
  93. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/web/server.py +0 -0
  94. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/web/web/index.html +0 -0
  95. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/src/descry/web/web/style.css +0 -0
  96. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/__init__.py +0 -0
  97. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/conftest.py +0 -0
  98. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/eval/README.md +0 -0
  99. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/eval/__init__.py +0 -0
  100. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/eval/compare.py +0 -0
  101. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/eval/corpus.py +0 -0
  102. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/eval/metrics.py +0 -0
  103. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/eval/registry.py +0 -0
  104. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/eval/results/results-descry.json +0 -0
  105. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/eval/results/results-ripgrep.json +0 -0
  106. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/fixtures/small_graph.json +0 -0
  107. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/c/Makefile +0 -0
  108. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/c/expected.json +0 -0
  109. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/c/io.c +0 -0
  110. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/c/io.h +0 -0
  111. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/c/main.c +0 -0
  112. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/c/order.c +0 -0
  113. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/cpp/Makefile +0 -0
  114. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/cpp/expected.json +0 -0
  115. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/cpp/main.cpp +0 -0
  116. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/cpp/models.hpp +0 -0
  117. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/cpp/reader.hpp +0 -0
  118. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/csharp/Gt.csproj +0 -0
  119. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/csharp/Io.cs +0 -0
  120. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/csharp/Models.cs +0 -0
  121. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/csharp/Program.cs +0 -0
  122. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/csharp/expected.json +0 -0
  123. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/dart/bin/main.dart +0 -0
  124. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/dart/expected.json +0 -0
  125. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/dart/lib/io.dart +0 -0
  126. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/dart/lib/models.dart +0 -0
  127. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/dart/pubspec.yaml +0 -0
  128. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/go/expected.json +0 -0
  129. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/go/go.mod +0 -0
  130. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/go/io.go +0 -0
  131. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/go/main.go +0 -0
  132. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/go/models.go +0 -0
  133. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/java/expected.json +0 -0
  134. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/java/src/gt/Base.java +0 -0
  135. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/java/src/gt/Io.java +0 -0
  136. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/java/src/gt/Main.java +0 -0
  137. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/java/src/gt/Order.java +0 -0
  138. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/java/src/gt/Reader.java +0 -0
  139. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/java/src/gt/User.java +0 -0
  140. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/javascript/expected.json +0 -0
  141. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/javascript/package.json +0 -0
  142. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/javascript/src/io.js +0 -0
  143. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/javascript/src/main.js +0 -0
  144. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/javascript/src/models.js +0 -0
  145. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/php/composer.json +0 -0
  146. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/php/expected.json +0 -0
  147. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/php/src/Io.php +0 -0
  148. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/php/src/Models.php +0 -0
  149. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/php/src/main.php +0 -0
  150. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/python/app/__init__.py +0 -0
  151. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/python/app/io.py +0 -0
  152. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/python/app/main.py +0 -0
  153. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/python/app/models.py +0 -0
  154. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/python/expected.json +0 -0
  155. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/python/pyproject.toml +0 -0
  156. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/ruby/Gemfile +0 -0
  157. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/ruby/expected.json +0 -0
  158. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/ruby/lib/io.rb +0 -0
  159. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/ruby/lib/main.rb +0 -0
  160. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/ruby/lib/models.rb +0 -0
  161. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/rust/Cargo.toml +0 -0
  162. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/rust/expected.json +0 -0
  163. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/rust/src/io.rs +0 -0
  164. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/rust/src/main.rs +0 -0
  165. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/rust/src/models.rs +0 -0
  166. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/typescript/expected.json +0 -0
  167. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/typescript/package.json +0 -0
  168. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/typescript/src/io.ts +0 -0
  169. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/typescript/src/main.ts +0 -0
  170. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/ground_truth/typescript/src/models.ts +0 -0
  171. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_clang_parser.py +0 -0
  172. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_cli.py +0 -0
  173. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_config.py +0 -0
  174. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_cross_lang.py +0 -0
  175. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_dart_parser.py +0 -0
  176. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_docs.py +0 -0
  177. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_dotnet_parser.py +0 -0
  178. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_embeddings.py +0 -0
  179. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_git_history.py +0 -0
  180. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_go_parser.py +0 -0
  181. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_handlers.py +0 -0
  182. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_hardening.py +0 -0
  183. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_interfaces.py +0 -0
  184. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_java_parser.py +0 -0
  185. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_mcp.py +0 -0
  186. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_non_regular_files.py +0 -0
  187. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_parse_cache.py +0 -0
  188. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_php_parser.py +0 -0
  189. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_query.py +0 -0
  190. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_resolve_cache.py +0 -0
  191. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_ruby_parser.py +0 -0
  192. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_scip.py +0 -0
  193. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_scip_cache.py +0 -0
  194. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_scip_clang.py +0 -0
  195. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_scip_dart.py +0 -0
  196. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_scip_dotnet.py +0 -0
  197. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_scip_go.py +0 -0
  198. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_scip_java.py +0 -0
  199. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_scip_php.py +0 -0
  200. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_scip_ruby.py +0 -0
  201. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_stdlib.py +0 -0
  202. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tests/test_written_through.py +0 -0
  203. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/docs/gen_tools.py +0 -0
  204. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/README.md +0 -0
  205. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/common.py +0 -0
  206. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_c.py +0 -0
  207. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_cpp.py +0 -0
  208. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_dart.py +0 -0
  209. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_dotnet.py +0 -0
  210. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_go.py +0 -0
  211. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_java.py +0 -0
  212. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_node.py +0 -0
  213. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_php.py +0 -0
  214. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_python.py +0 -0
  215. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_ruby.py +0 -0
  216. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_rust.py +0 -0
  217. {descry_codegraph-1.0.0 → descry_codegraph-1.0.1}/tools/stdlib/gen_typescript.py +0 -0
@@ -1,6 +1,6 @@
1
- # CLAUDE.md
1
+ # AGENTS.md
2
2
 
3
- This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
3
+ This file provides guidance to coding agents when working with code in this repository.
4
4
 
5
5
  ## Commands
6
6
 
@@ -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 (3306 tests pass; a handful more are skipped where the environment lacks their fixture — a drop is a regression signal).
26
+ Python 3.11+ required (enforced by `pyproject.toml`). Pre-commit gate: `just lint && just fmt && just test` all pass (3343 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
 
@@ -4,6 +4,18 @@ 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.1] — 2026-10-30
8
+
9
+ ### Fixed
10
+
11
+ - On macOS, stopping `descry index` (Ctrl-C, `SIGINT`) stops the run as
12
+ `SIGTERM` and `SIGHUP` do; it reported "Index error: Operation not
13
+ permitted" and exited 2.
14
+
15
+ ### Changed
16
+
17
+ - `CLAUDE.md` is `AGENTS.md`.
18
+
7
19
  ## [1.0.0] — 2026-10-29
8
20
 
9
21
  ### Breaking
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: descry-codegraph
3
- Version: 1.0.0
3
+ Version: 1.0.1
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
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "descry-codegraph"
3
- version = "1.0.0"
3
+ version = "1.0.1"
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.0"
3
+ __version__ = "1.0.1"
4
4
  __all__ = ["__version__"]
@@ -1058,7 +1058,7 @@ def _kill_process_tree(proc: asyncio.subprocess.Process) -> None:
1058
1058
  )
1059
1059
  else:
1060
1060
  # The child may have exited without the event loop having seen it yet.
1061
- with contextlib.suppress(ProcessLookupError):
1061
+ with contextlib.suppress(ProcessLookupError, PermissionError):
1062
1062
  os.killpg(proc.pid, signal.SIGKILL)
1063
1063
 
1064
1064
 
@@ -21,45 +21,80 @@ from descry.generate import CodeGraphBuilder
21
21
 
22
22
  _GO_FIELD = next(r for r in go_parser._DECLARATIONS if "(?!(?:return" in r.pattern)
23
23
 
24
- # 3,000 characters took seconds to minutes where the time was cubic, and
25
- # 20,000 seconds where it was quadratic; each now takes milliseconds.
26
- _RUN = " " * 3000
27
- _LONG_RUN = " " * 20000
28
24
 
25
+ def _seconds(run):
26
+ """The least CPU time of three calls of `run`."""
27
+
28
+ def once():
29
+ start = time.process_time()
30
+ run()
31
+ return time.process_time() - start
32
+
33
+ return min(once() for _ in range(3))
34
+
35
+
36
+ def assert_linear(run, n):
37
+ """`run(n)` takes under ten times the CPU time of `run(n // 4)`: time
38
+ linear in `n` gives four times, quadratic sixteen."""
39
+ quarter = _seconds(lambda: run(n // 4))
40
+ assert _seconds(lambda: run(n)) < 10 * max(quarter, 0.05)
29
41
 
42
+
43
+ # 3,000 characters took seconds to minutes where the time was cubic, and
44
+ # 20,000 seconds where it was quadratic.
30
45
  @pytest.mark.parametrize(
31
- ("find", "text"),
46
+ ("find", "text", "length"),
32
47
  [
33
- (_RE_LOCAL_FUNCTION.match, _RUN + "!"),
34
- (DartParser.binding_re.search, "const" + _RUN),
35
- (java_parser._RE_METHOD.match, "final" + _RUN),
36
- (java_parser._RE_FIELD.match, "final" + _RUN),
37
- (ts_parser._TS_IMPORT_RE.findall, "import" + _RUN + "x;\n"),
38
- (rust_parser._RUST_ARM_RE.search, _RUN + "!"),
39
- (java_parser._RE_METHOD.match, "public <T>" + _RUN),
40
- (java_parser._RE_METHOD.match, "public @A" + _RUN),
41
- (java_parser._RE_ENUM_CONSTANT.match, "A" + _RUN + ")"),
42
- (rust_parser._RUST_BINDER_RES[1].findall, "for" + _RUN),
43
- (rust_parser._RUST_FOR_RE.search, " for" + _RUN + "x"),
44
- (rust_parser._RUST_IF_LET_RE.search, "while let" + _RUN),
45
- (rust_parser._RUST_MATCH_RE.search, "match" + _RUN + "a b"),
46
- (ruby_parser._RE_INLINE_BODY.match, "x" + "\r\n" * 1500 + ")"),
47
- (dotnet_parser._RE_MEMBER.match, "partial unsafe" + _LONG_RUN + ")"),
48
- (dotnet_parser._RE_PARAMETER.search, "scoped readonly" + _LONG_RUN + "x;"),
49
- (_GO_FIELD.search, " chan a" + _LONG_RUN + "x("),
50
- (ruby_parser._RE_ALIAS.search, "alias" + _LONG_RUN + ")"),
51
- (ruby_parser._RE_MIXIN.match, " prepend" + _LONG_RUN + "="),
52
- (_RE_TYPE.fullmatch, _LONG_RUN + ")"),
53
- (java_parser._RE_METHOD.match, "private final a" + _LONG_RUN + "b"),
54
- (java_parser._RE_FIELD.match, "public static a" + _LONG_RUN + "b("),
55
- (ruby_parser._RE_ENDLESS.match, _LONG_RUN * 3 + "x"),
56
- (ruby_parser._RE_INLINE_BODY.match, "end" + "\n" * 60000 + "x"),
57
- (dotnet_parser._RE_PRIMARY_CONSTRUCTOR.match, _LONG_RUN * 3 + "x"),
58
- (dotnet_parser._RE_PARAMETER.findall, "readonly" + "\t\n " * 20000 + ")"),
59
- (_RE_CLOSURE.findall, "\n" * 60000),
60
- (ts_parser._TS_IMPORT_RE.findall, "\n" * 60000),
61
- (ts_parser._TS_DEFAULT_EXPORT_RE.findall, "\u2028" * 60000),
62
- (rust_parser._RUST_USE_RE.findall, "\n" * 60000),
48
+ (_RE_LOCAL_FUNCTION.match, lambda n: " " * n + "!", 3000),
49
+ (DartParser.binding_re.search, lambda n: "const" + " " * n, 3000),
50
+ (java_parser._RE_METHOD.match, lambda n: "final" + " " * n, 3000),
51
+ (java_parser._RE_FIELD.match, lambda n: "final" + " " * n, 3000),
52
+ (ts_parser._TS_IMPORT_RE.findall, lambda n: "import" + " " * n + "x;\n", 3000),
53
+ (rust_parser._RUST_ARM_RE.search, lambda n: " " * n + "!", 3000),
54
+ (java_parser._RE_METHOD.match, lambda n: "public <T>" + " " * n, 3000),
55
+ (java_parser._RE_METHOD.match, lambda n: "public @A" + " " * n, 3000),
56
+ (java_parser._RE_ENUM_CONSTANT.match, lambda n: "A" + " " * n + ")", 3000),
57
+ (rust_parser._RUST_BINDER_RES[1].findall, lambda n: "for" + " " * n, 3000),
58
+ (rust_parser._RUST_FOR_RE.search, lambda n: " for" + " " * n + "x", 3000),
59
+ (rust_parser._RUST_IF_LET_RE.search, lambda n: "while let" + " " * n, 3000),
60
+ (rust_parser._RUST_MATCH_RE.search, lambda n: "match" + " " * n + "a b", 3000),
61
+ (ruby_parser._RE_INLINE_BODY.match, lambda n: "x" + "\r\n" * n + ")", 1500),
62
+ (
63
+ dotnet_parser._RE_MEMBER.match,
64
+ lambda n: "partial unsafe" + " " * n + ")",
65
+ 20000,
66
+ ),
67
+ (
68
+ dotnet_parser._RE_PARAMETER.search,
69
+ lambda n: "scoped readonly" + " " * n + "x;",
70
+ 20000,
71
+ ),
72
+ (_GO_FIELD.search, lambda n: " chan a" + " " * n + "x(", 20000),
73
+ (ruby_parser._RE_ALIAS.search, lambda n: "alias" + " " * n + ")", 20000),
74
+ (ruby_parser._RE_MIXIN.match, lambda n: " prepend" + " " * n + "=", 20000),
75
+ (_RE_TYPE.fullmatch, lambda n: " " * n + ")", 20000),
76
+ (
77
+ java_parser._RE_METHOD.match,
78
+ lambda n: "private final a" + " " * n + "b",
79
+ 20000,
80
+ ),
81
+ (
82
+ java_parser._RE_FIELD.match,
83
+ lambda n: "public static a" + " " * n + "b(",
84
+ 20000,
85
+ ),
86
+ (ruby_parser._RE_ENDLESS.match, lambda n: " " * n + "x", 60000),
87
+ (ruby_parser._RE_INLINE_BODY.match, lambda n: "end" + "\n" * n + "x", 60000),
88
+ (dotnet_parser._RE_PRIMARY_CONSTRUCTOR.match, lambda n: " " * n + "x", 60000),
89
+ (
90
+ dotnet_parser._RE_PARAMETER.findall,
91
+ lambda n: "readonly" + "\t\n " * n + ")",
92
+ 20000,
93
+ ),
94
+ (_RE_CLOSURE.findall, lambda n: "\n" * n, 60000),
95
+ (ts_parser._TS_IMPORT_RE.findall, lambda n: "\n" * n, 60000),
96
+ (ts_parser._TS_DEFAULT_EXPORT_RE.findall, lambda n: "\u2028" * n, 60000),
97
+ (rust_parser._RUST_USE_RE.findall, lambda n: "\n" * n, 60000),
63
98
  ],
64
99
  ids=[
65
100
  "dart-local-function",
@@ -94,34 +129,30 @@ _LONG_RUN = " " * 20000
94
129
  "rust-use-blank-lines",
95
130
  ],
96
131
  )
97
- def test_a_whitespace_run_is_taken_once(find, text):
98
- start = time.process_time()
99
-
100
- find(text)
101
-
102
- assert time.process_time() - start < 1
132
+ def test_a_whitespace_run_is_taken_once(find, text, length):
133
+ assert_linear(lambda n: find(text(n)), length)
103
134
 
104
135
 
105
136
  @pytest.mark.parametrize(
106
137
  ("name", "source", "count"),
107
138
  [
108
- ("m.js", lambda n: "const b = { a: g() };\n" * n, 20000),
109
- ("m.js", lambda n: "let b = 1;\n" + "b = g();\nb.x();\n" * n, 10000),
139
+ ("m.js", lambda n: "const b = { a: g() };\n" * n, 10000),
140
+ ("m.js", lambda n: "let b = 1;\n" + "b = g();\nb.x();\n" * n, 5000),
110
141
  (
111
142
  "m.js",
112
143
  lambda n: (
113
144
  "function f(xs) {\n" + " for (const x of xs) { x.a(); }\n" * n + "}\n"
114
145
  ),
115
- 15000,
146
+ 7500,
116
147
  ),
117
- ("m.rb", lambda n: "b = 2\n" * n, 20000),
118
- ("m.rb", lambda n: "a = []\n" + "a <<-b\n" * n, 60000),
119
- ("m.dart", lambda n: "void main() {\n" + " var b = 2;\n" * n + "}\n", 20000),
120
- ("m.py", lambda n: "def f():\n" + " b = B()\n b.x()\n" * n, 20000),
148
+ ("m.rb", lambda n: "b = 2\n" * n, 10000),
149
+ ("m.rb", lambda n: "a = []\n" + "a <<-b\n" * n, 30000),
150
+ ("m.dart", lambda n: "void main() {\n" + " var b = 2;\n" * n + "}\n", 10000),
151
+ ("m.py", lambda n: "def f():\n" + " b = B()\n b.x()\n" * n, 10000),
121
152
  (
122
153
  "m.py",
123
154
  lambda n: "def f(xs):\n" + " for x in xs:\n x.a()\n" * n,
124
- 10000,
155
+ 5000,
125
156
  ),
126
157
  (
127
158
  "M.java",
@@ -130,7 +161,7 @@ def test_a_whitespace_run_is_taken_once(find, text):
130
161
  + " B b = new B();\n b.x();\n" * n
131
162
  + " }\n}\n"
132
163
  ),
133
- 10000,
164
+ 5000,
134
165
  ),
135
166
  (
136
167
  "M.cs",
@@ -139,14 +170,14 @@ def test_a_whitespace_run_is_taken_once(find, text):
139
170
  + " var b = new B();\n b.X();\n" * n
140
171
  + " }\n}\n"
141
172
  ),
142
- 8000,
173
+ 4000,
143
174
  ),
144
175
  (
145
176
  "M.cs",
146
177
  lambda n: "".join(
147
178
  f"class C{i} {{ int M() {{ return {i}; }} }}\n" for i in range(n)
148
179
  ),
149
- 3000,
180
+ 1500,
150
181
  ),
151
182
  (
152
183
  "m.go",
@@ -156,7 +187,7 @@ def test_a_whitespace_run_is_taken_once(find, text):
156
187
  * n
157
188
  + "\treturn nil\n}\n"
158
189
  ),
159
- 10000,
190
+ 5000,
160
191
  ),
161
192
  (
162
193
  "m.php",
@@ -165,14 +196,14 @@ def test_a_whitespace_run_is_taken_once(find, text):
165
196
  + " foreach ($xs as $x) { $x->a(); }\n" * n
166
197
  + "}\n"
167
198
  ),
168
- 8000,
199
+ 4000,
169
200
  ),
170
201
  (
171
202
  "src/lib.rs",
172
203
  lambda n: "".join(
173
204
  f"fn f{i}<T: Clone>(a: T) -> T {{ a.clone() }}\n" for i in range(n)
174
205
  ),
175
- 12000,
206
+ 6000,
176
207
  ),
177
208
  (
178
209
  "m.js",
@@ -182,7 +213,7 @@ def test_a_whitespace_run_is_taken_once(find, text):
182
213
  * n
183
214
  + "}\n"
184
215
  ),
185
- 5000,
216
+ 2500,
186
217
  ),
187
218
  (
188
219
  "src/lib.rs",
@@ -191,7 +222,7 @@ def test_a_whitespace_run_is_taken_once(find, text):
191
222
  + " match v { Some(b) => b.a(), None => () }\n" * n
192
223
  + "}\n"
193
224
  ),
194
- 10000,
225
+ 5000,
195
226
  ),
196
227
  ],
197
228
  ids=[
@@ -216,22 +247,18 @@ def test_a_whitespace_run_is_taken_once(find, text):
216
247
  def test_a_repeated_line_is_read_in_linear_time(name, source, count, tmp_path):
217
248
  """A line that binds a name again, loops over it, matches it, or
218
249
  declares a type or a generic function costs the same time however many
219
- came before it: four times the lines take about four times as long,
220
- where they took sixteen times, minutes in all. The ratio, not a time,
221
- is checked, so a slow machine does not fail it."""
250
+ came before it, where four times the lines took sixteen times as long,
251
+ minutes in all."""
222
252
 
223
253
  def reading(lines):
224
254
  root = tmp_path / str(lines)
225
255
  (root / name).parent.mkdir(parents=True, exist_ok=True)
226
256
  (root / name).write_text(source(lines))
227
- start = time.process_time()
228
257
  builder = CodeGraphBuilder(root)
229
258
  builder.process_directory()
230
259
  builder.resolve_references()
231
- return time.process_time() - start
232
260
 
233
- quarter = reading(count // 4)
234
- assert reading(count) < 8 * max(quarter, 0.05)
261
+ assert_linear(reading, count)
235
262
 
236
263
 
237
264
  def test_the_patterns_still_match_source():
@@ -22,6 +22,7 @@ from descry.python_parser import PythonParser
22
22
  from descry.resolver import CallResolver
23
23
  from descry.rust_parser import RustParser
24
24
  from descry.ts_parser import TSParser
25
+ from tests.test_backtracking import assert_linear
25
26
 
26
27
 
27
28
  class TestPythonParser:
@@ -3168,13 +3169,18 @@ class TestPythonCallResolution:
3168
3169
 
3169
3170
  def test_many_branches_merge_in_time_linear_in_the_code(self, tmp_path):
3170
3171
  """Merging the ways of many branches costs time in the bindings they
3171
- hold, not in every name the file declares: four thousand `if`s are
3172
- parsed in seconds."""
3173
- source = "def f(c):\n" + "".join(f" if c: x{i} = 1\n" for i in range(4000))
3174
- (tmp_path / "m.py").write_text(source)
3175
- started = time.process_time()
3176
- CodeGraphBuilder(tmp_path).process_directory()
3177
- assert time.process_time() - started < 3
3172
+ hold, not in every name the file declares."""
3173
+
3174
+ def parse(n):
3175
+ _index(
3176
+ tmp_path / str(n),
3177
+ {
3178
+ "m.py": "def f(c):\n"
3179
+ + "".join(f" if c: x{i} = 1\n" for i in range(n))
3180
+ },
3181
+ )
3182
+
3183
+ assert_linear(parse, 4000)
3178
3184
 
3179
3185
  def test_a_break_in_a_match_case_skips_the_else(self, tmp_path):
3180
3186
  """A `break` inside a `case` body skips the loop's `else`, so `x`
@@ -14989,35 +14995,37 @@ class TestTypeScriptCallResolution:
14989
14995
 
14990
14996
  def test_scopes_are_read_in_time_linear_in_the_code(self, tmp_path):
14991
14997
  """A line of thousands of assignments in one sequence, and of
14992
- thousands of nested labelled blocks, is read in a few seconds: no
14993
- token is read back over once per assignment after it."""
14994
- count = 2000
14995
- line = (
14996
- "function f(){var a;"
14997
- + ",".join(["a=1"] * count)
14998
- + ";"
14999
- + "".join(f"l{i}:{{" for i in range(count))
15000
- + "a=2;"
15001
- + "}" * count
15002
- + "}\n"
15003
- )
15004
- started = time.process_time()
15005
- builder = _index(tmp_path, {"a.js": line})
15006
- assert time.process_time() - started < 6
15007
- assert any(n["id"] == "FILE:a.js::f" for n in builder.nodes)
14998
+ thousands of nested labelled blocks, is read in time linear in its
14999
+ length: no token is read back over once per assignment after it."""
15000
+
15001
+ def index(n):
15002
+ line = (
15003
+ "function f(){var a;"
15004
+ + ",".join(["a=1"] * n)
15005
+ + ";"
15006
+ + "".join(f"l{i}:{{" for i in range(n))
15007
+ + "a=2;"
15008
+ + "}" * n
15009
+ + "}\n"
15010
+ )
15011
+ return _index(tmp_path / str(n), {"a.js": line})
15012
+
15013
+ assert_linear(index, 2000)
15014
+ assert any(n["id"] == "FILE:a.js::f" for n in index(2000).nodes)
15008
15015
 
15009
15016
  def test_the_bindings_of_one_name_are_read_in_time_linear_in_the_code(
15010
15017
  self, tmp_path
15011
15018
  ):
15012
15019
  """A line of six thousand assignments of one name in one function
15013
- is indexed in seconds: a read of the name looks only at the
15014
- bindings that can be in scope where it is read."""
15015
- count = 6000
15016
- line = "function f(){var a;" + "a=1," * count + "}\n"
15017
- started = time.process_time()
15018
- builder = _index(tmp_path, {"a.js": line})
15019
- assert time.process_time() - started < 3
15020
- assert any(n["id"] == "FILE:a.js::f" for n in builder.nodes)
15020
+ is indexed in time linear in its length: a read of the name looks
15021
+ only at the bindings that can be in scope where it is read."""
15022
+
15023
+ def index(n):
15024
+ line = "function f(){var a;" + "a=1," * n + "}\n"
15025
+ return _index(tmp_path / str(n), {"a.js": line})
15026
+
15027
+ assert_linear(index, 6000)
15028
+ assert any(n["id"] == "FILE:a.js::f" for n in index(6000).nodes)
15021
15029
 
15022
15030
  def test_a_block_starts_wherever_a_statement_does(self, tmp_path):
15023
15031
  """A `{` is a block after a label's, a `case`'s or `default`'s `:`,
@@ -52,7 +52,10 @@ def services(tmp_path_factory):
52
52
  project_root=root, enable_scip=False, enable_embeddings=False
53
53
  )
54
54
  )
55
- asyncio.run(svc.index())
55
+ with pytest.MonkeyPatch.context() as mp:
56
+ mp.setenv("DESCRY_NO_SCIP", "1")
57
+ mp.setenv("DESCRY_NO_EMBEDDINGS", "1")
58
+ asyncio.run(svc.index())
56
59
  built[language] = svc
57
60
  return built[language]
58
61
 
@@ -381,9 +381,9 @@ class TestSourceRaces:
381
381
  if str(path).endswith("pipe.txt") and not writers:
382
382
  target.unlink()
383
383
  os.mkfifo(target)
384
- # A writer with a full sample pending, so a blocking open and
385
- # read of the FIFO return instead of hanging the test.
386
- writers.append(real_open(target, os.O_RDWR))
384
+ # A writer with data pending, so a blocking open and read of
385
+ # the FIFO return instead of hanging the test.
386
+ writers.append(real_open(target, os.O_RDWR | os.O_NONBLOCK))
387
387
  os.write(writers[0], b"x" * 16384)
388
388
  return real_open(path, flags, *args, **kwargs)
389
389
 
@@ -483,7 +483,7 @@ class TestLoopbackHostFlag:
483
483
  class TestServiceDelegation:
484
484
  """The web layer must not carry its own copy of DescryService's logic.
485
485
 
486
- CLAUDE.md: "DescryService owns all business logic. cli.py, mcp_server.py
486
+ AGENTS.md: "DescryService owns all business logic. cli.py, mcp_server.py
487
487
  and web/server.py are thin wrappers."
488
488
  """
489
489