dirsql 0.4.117__tar.gz → 0.4.118__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 (472) hide show
  1. {dirsql-0.4.117 → dirsql-0.4.118}/Cargo.lock +2 -2
  2. {dirsql-0.4.117 → dirsql-0.4.118}/PKG-INFO +1 -1
  3. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/Cargo.toml +1 -1
  4. dirsql-0.4.118/packages/python/e2e-attestations/bot-1461-chunked-read-1016.json +7 -0
  5. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/Cargo.toml +1 -1
  6. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/listing.rs +190 -42
  7. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/scanner.rs +3 -1
  8. {dirsql-0.4.117 → dirsql-0.4.118}/Cargo.toml +0 -0
  9. {dirsql-0.4.117 → dirsql-0.4.118}/README.md +0 -0
  10. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/__init__.py +0 -0
  11. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/_async.py +0 -0
  12. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/_dirsql.pyi +0 -0
  13. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/cli/__init__.py +0 -0
  14. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/cli/discover_plugins/__init__.py +0 -0
  15. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  16. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  17. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  18. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
  19. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/cli/main.py +0 -0
  20. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/cli/resolve_config_extensions.py +0 -0
  21. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/plan_entry_path.py +0 -0
  22. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/py.typed +0 -0
  23. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/read_config.py +0 -0
  24. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/resolve_configs_extension_specs.py +0 -0
  25. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/resolve_extension.py +0 -0
  26. {dirsql-0.4.117 → dirsql-0.4.118}/dirsql/resolve_package.py +0 -0
  27. {dirsql-0.4.117 → dirsql-0.4.118}/docs/.claude/CLAUDE.md +0 -0
  28. {dirsql-0.4.117 → dirsql-0.4.118}/docs/.vitepress/config.ts +0 -0
  29. {dirsql-0.4.117 → dirsql-0.4.118}/docs/.vitepress/theme/index.ts +0 -0
  30. {dirsql-0.4.117 → dirsql-0.4.118}/docs/.vitepress/theme/lang.ts +0 -0
  31. {dirsql-0.4.117 → dirsql-0.4.118}/docs/AGENTS.md +0 -0
  32. {dirsql-0.4.117 → dirsql-0.4.118}/docs/context/.gitattributes +0 -0
  33. {dirsql-0.4.117 → dirsql-0.4.118}/docs/context/recipes.md +0 -0
  34. {dirsql-0.4.117 → dirsql-0.4.118}/docs/context/troubleshooting.md +0 -0
  35. {dirsql-0.4.117 → dirsql-0.4.118}/docs/context/usage.md +0 -0
  36. {dirsql-0.4.117 → dirsql-0.4.118}/docs/explanation.md +0 -0
  37. {dirsql-0.4.117 → dirsql-0.4.118}/docs/getting-started.md +0 -0
  38. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/agent-skill.md +0 -0
  39. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/columns-from-paths.md +0 -0
  40. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/define-tables.md +0 -0
  41. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/embed.md +0 -0
  42. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/extract-from-contents.md +0 -0
  43. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/load-extension.md +0 -0
  44. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/parse-files-into-columns.md +0 -0
  45. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/persist.md +0 -0
  46. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/query-json.md +0 -0
  47. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/query-without-config.md +0 -0
  48. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/react-to-changes.md +0 -0
  49. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/search-by-meaning.md +0 -0
  50. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/search-indexes.md +0 -0
  51. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/skip-files.md +0 -0
  52. {dirsql-0.4.117 → dirsql-0.4.118}/docs/howto/write-a-plugin.md +0 -0
  53. {dirsql-0.4.117 → dirsql-0.4.118}/docs/index.md +0 -0
  54. {dirsql-0.4.117 → dirsql-0.4.118}/docs/package.json +0 -0
  55. {dirsql-0.4.117 → dirsql-0.4.118}/docs/plugins.md +0 -0
  56. {dirsql-0.4.117 → dirsql-0.4.118}/docs/pnpm-lock.yaml +0 -0
  57. {dirsql-0.4.117 → dirsql-0.4.118}/docs/pnpm-workspace.yaml +0 -0
  58. {dirsql-0.4.117 → dirsql-0.4.118}/docs/reference/cli.md +0 -0
  59. {dirsql-0.4.117 → dirsql-0.4.118}/docs/reference/columns.md +0 -0
  60. {dirsql-0.4.117 → dirsql-0.4.118}/docs/reference/config.md +0 -0
  61. {dirsql-0.4.117 → dirsql-0.4.118}/docs/reference/glob.md +0 -0
  62. {dirsql-0.4.117 → dirsql-0.4.118}/docs/reference/hooks.md +0 -0
  63. {dirsql-0.4.117 → dirsql-0.4.118}/docs/reference/http-api.md +0 -0
  64. {dirsql-0.4.117 → dirsql-0.4.118}/docs/reference/path-tables.md +0 -0
  65. {dirsql-0.4.117 → dirsql-0.4.118}/docs/reference/sdk.md +0 -0
  66. {dirsql-0.4.117 → dirsql-0.4.118}/docs/speed.json +0 -0
  67. {dirsql-0.4.117 → dirsql-0.4.118}/docs/speed.md +0 -0
  68. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/CHANGELOG.md +0 -0
  69. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/MIGRATIONS.md +0 -0
  70. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/README.md +0 -0
  71. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  72. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  73. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  74. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  75. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  76. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  77. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  78. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  79. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  80. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  81. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  82. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
  83. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
  84. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
  85. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
  86. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
  87. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
  88. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
  89. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
  90. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
  91. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
  92. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
  93. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
  94. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
  95. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
  96. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
  97. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
  98. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
  99. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  100. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  101. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
  102. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  103. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
  104. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  105. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-brace-groups-follow-bash.md +0 -0
  106. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-cli-context.md +0 -0
  107. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-gitignore-requires-repo.md +0 -0
  108. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-path-table-node-modules-named.md +0 -0
  109. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
  110. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +0 -0
  111. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
  112. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-braces.md +0 -0
  113. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-directory.md +0 -0
  114. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-dotnames.md +0 -0
  115. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-gitignore.md +0 -0
  116. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
  117. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-links.md +0 -0
  118. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-one-glob-compiler.md +0 -0
  119. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-plugin-no-default-records.md +0 -0
  120. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-watch-broadcast.md +0 -0
  121. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-zero-match-config-table-warning.md +0 -0
  122. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-bracket-slash-literal.md +0 -0
  123. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
  124. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-dotdot-as-written.md +0 -0
  125. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-glob-walks-node-modules.md +0 -0
  126. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-literal-gitignore.md +0 -0
  127. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-on-file-ndjson.md +0 -0
  128. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-parallel-hooks.md +0 -0
  129. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-persist-cache-outside-root.md +0 -0
  130. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-posix-classes-unicode.md +0 -0
  131. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-spread-few-large-files.md +0 -0
  132. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
  133. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-08-watch-requires-named-table.md +0 -0
  134. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/changelog.d/README.md +0 -0
  135. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/conftest.py +0 -0
  136. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/.claude/CLAUDE.md +0 -0
  137. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/.vitepress/config.ts +0 -0
  138. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  139. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  140. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/AGENTS.md +0 -0
  141. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/context/.gitattributes +0 -0
  142. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/context/recipes.md +0 -0
  143. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/context/troubleshooting.md +0 -0
  144. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/context/usage.md +0 -0
  145. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/explanation.md +0 -0
  146. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/getting-started.md +0 -0
  147. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/agent-skill.md +0 -0
  148. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/columns-from-paths.md +0 -0
  149. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/define-tables.md +0 -0
  150. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/embed.md +0 -0
  151. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/extract-from-contents.md +0 -0
  152. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/load-extension.md +0 -0
  153. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  154. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/persist.md +0 -0
  155. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/query-json.md +0 -0
  156. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/query-without-config.md +0 -0
  157. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/react-to-changes.md +0 -0
  158. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/search-by-meaning.md +0 -0
  159. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/search-indexes.md +0 -0
  160. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/skip-files.md +0 -0
  161. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/howto/write-a-plugin.md +0 -0
  162. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/index.md +0 -0
  163. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/package.json +0 -0
  164. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/plugins.md +0 -0
  165. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/pnpm-lock.yaml +0 -0
  166. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/pnpm-workspace.yaml +0 -0
  167. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/reference/cli.md +0 -0
  168. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/reference/columns.md +0 -0
  169. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/reference/config.md +0 -0
  170. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/reference/glob.md +0 -0
  171. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/reference/hooks.md +0 -0
  172. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/reference/http-api.md +0 -0
  173. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/reference/path-tables.md +0 -0
  174. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/reference/sdk.md +0 -0
  175. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/speed.json +0 -0
  176. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/docs/speed.md +0 -0
  177. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1334-listing-exemptions.json +0 -0
  178. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1397-watch-broadcast.json +0 -0
  179. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1398-inotify-error.json +0 -0
  180. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1399-server-cors.json +0 -0
  181. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1401-watch-scope.json +0 -0
  182. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1406-watch-no-tables-1008.json +0 -0
  183. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1407-child-place-depth.json +0 -0
  184. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1414-stat-speed.json +0 -0
  185. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1415-server-speed.json +0 -0
  186. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1416-watch-speed-1008.json +0 -0
  187. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1418-node-modules.json +0 -0
  188. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1419-dotdot-slashes.json +0 -0
  189. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1420-bracket-slash.json +0 -0
  190. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1421-posix-unicode.json +0 -0
  191. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1422-literal-gitignore.json +0 -0
  192. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1426-walk-spawn-threshold-1008.json +0 -0
  193. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1428-ndjson-hooks.json +0 -0
  194. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1429-parallel-hooks.json +0 -0
  195. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1430-dotdot-as-written.json +0 -0
  196. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1431-persist-cache-dir.json +0 -0
  197. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1437-test-cache-isolation.json +0 -0
  198. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1440-fix-main-build.json +0 -0
  199. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1448-wildcard-ignored-prefix.json +0 -0
  200. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1451-named-dir-never-hidden.json +0 -0
  201. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1454-split-few-files.json +0 -0
  202. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1457-incremental-refresh-1008.json +0 -0
  203. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1459-rescan-on-overflow-1008.json +0 -0
  204. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1461-row-footprint-1008.json +0 -0
  205. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1461-wide-read-1015.json +0 -0
  206. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1462-paired-speed-harness-1008.json +0 -0
  207. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1464-fastest-native-1008.json +0 -0
  208. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1469-ci-speed-sanity-1009.json +0 -0
  209. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1470-perf-suite-1009.json +0 -0
  210. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1470-speed-page-1011.json +0 -0
  211. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1474-vtab-speed-1014.json +0 -0
  212. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1477-onelevel-speed-1015.json +0 -0
  213. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1477-onelevel-speed-1016.json +0 -0
  214. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1480-matcher-speed-1015.json +0 -0
  215. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1481-gitrepo-speed-1015.json +0 -0
  216. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1483-fm-speed-1015.json +0 -0
  217. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1484-jsonl-speed-1015.json +0 -0
  218. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1487-frontend-query-1011.json +0 -0
  219. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1488-frontend-metadata-1011.json +0 -0
  220. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1489-frontend-browse-1013.json +0 -0
  221. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1503-bench-watch-1011.json +0 -0
  222. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1504-bench-names-1011.json +0 -0
  223. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1514-watch-rerun-inline-1015.json +0 -0
  224. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1524-path-eq-1016.json +0 -0
  225. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1526-main-red-1016.json +0 -0
  226. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1532-gitignore-fastest-bar-1016.json +0 -0
  227. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1534-fm-native-1016.json +0 -0
  228. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-fix-main-place-depth-20261007.json +0 -0
  229. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-issue-1486-frontend-20261009.json +0 -0
  230. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-gap-childpath-1011.json +0 -0
  231. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-parse-overlap-1011.json +0 -0
  232. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-parse-paths-1009.json +0 -0
  233. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-parse-pragmas-1011.json +0 -0
  234. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-sql-valueref-1013.json +0 -0
  235. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-walk-components-1011.json +0 -0
  236. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-walk-rowpath-1011.json +0 -0
  237. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-walk-rows-1013.json +0 -0
  238. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-walk-sched-1009.json +0 -0
  239. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
  240. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
  241. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
  242. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
  243. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
  244. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
  245. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
  246. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
  247. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
  248. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
  249. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
  250. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
  251. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
  252. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
  253. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
  254. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
  255. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
  256. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
  257. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
  258. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
  259. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
  260. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
  261. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
  262. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
  263. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
  264. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
  265. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
  266. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
  267. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
  268. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
  269. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
  270. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
  271. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
  272. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
  273. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1225-plugin-no-default.json +0 -0
  274. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
  275. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1232-anchor-plumbing.json +0 -0
  276. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1232-config-anchor.json +0 -0
  277. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1232-multi-watch.json +0 -0
  278. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1232-zero-match.json +0 -0
  279. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
  280. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
  281. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
  282. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
  283. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
  284. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1257-trailing-slash.json +0 -0
  285. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-config-braces.json +0 -0
  286. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-config-directory.json +0 -0
  287. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-config-dotnames.json +0 -0
  288. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-config-gitignore.json +0 -0
  289. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-config-links.json +0 -0
  290. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-one-pattern.json +0 -0
  291. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1262-brace-literal.json +0 -0
  292. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1264-context.json +0 -0
  293. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1267-posix-classes.json +0 -0
  294. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +0 -0
  295. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1269-utf8-chars.json +0 -0
  296. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1271-node-modules-named.json +0 -0
  297. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1272-ancestor-gitignore.json +0 -0
  298. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1273-walk-prune.json +0 -0
  299. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1285-ingest-fast.json +0 -0
  300. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1286-nested-repo.json +0 -0
  301. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1305-glob-speed.json +0 -0
  302. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1308-glob-speed.json +0 -0
  303. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1310-glob-speed.json +0 -0
  304. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1311-glob-speed.json +0 -0
  305. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1312-glob-speed.json +0 -0
  306. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1318-lazy-stat.json +0 -0
  307. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1320-walk-speed.json +0 -0
  308. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1322-walk-readdir.json +0 -0
  309. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1325-parallel-walk.json +0 -0
  310. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1326-stream-rows.json +0 -0
  311. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json +0 -0
  312. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-python-extensions-patch.json +0 -0
  313. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-scanner-effects.json +0 -0
  314. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-scanner-gitignore.json +0 -0
  315. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-vtab-prefetch-flag.json +0 -0
  316. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-vtab-read.json +0 -0
  317. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1351-dot-dirs.json +0 -0
  318. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
  319. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
  320. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
  321. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
  322. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
  323. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
  324. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
  325. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
  326. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
  327. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
  328. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
  329. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
  330. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
  331. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
  332. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
  333. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  334. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  335. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  336. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  337. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  338. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  339. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  340. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  341. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
  342. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
  343. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  344. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  345. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
  346. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  347. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
  348. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  349. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-brace-groups-follow-bash.md +0 -0
  350. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-cli-context.md +0 -0
  351. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-gitignore-requires-repo.md +0 -0
  352. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-path-table-node-modules-named.md +0 -0
  353. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
  354. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +0 -0
  355. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
  356. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-braces.md +0 -0
  357. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-directory.md +0 -0
  358. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-dotnames.md +0 -0
  359. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-gitignore.md +0 -0
  360. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
  361. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-links.md +0 -0
  362. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-one-glob-compiler.md +0 -0
  363. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-plugin-no-default-records.md +0 -0
  364. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-watch-broadcast.md +0 -0
  365. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-zero-match-config-table-warning.md +0 -0
  366. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-bracket-slash-literal.md +0 -0
  367. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
  368. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-dotdot-as-written.md +0 -0
  369. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-glob-walks-node-modules.md +0 -0
  370. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-literal-gitignore.md +0 -0
  371. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-on-file-ndjson.md +0 -0
  372. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-parallel-hooks.md +0 -0
  373. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-persist-cache-outside-root.md +0 -0
  374. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-posix-classes-unicode.md +0 -0
  375. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-spread-few-large-files.md +0 -0
  376. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
  377. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-08-watch-requires-named-table.md +0 -0
  378. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/migrations.d/README.md +0 -0
  379. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/src/lib.rs +0 -0
  380. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/testing-conventions.toml +0 -0
  381. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/__init__.py +0 -0
  382. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/conftest.py +0 -0
  383. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/e2e/__init__.py +0 -0
  384. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/e2e/bench_report.py +0 -0
  385. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/e2e/bench_suite.py +0 -0
  386. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  387. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  388. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/e2e/speed_of_light.py +0 -0
  389. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/integration/__init__.py +0 -0
  390. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/integration/binding/__init__.py +0 -0
  391. {dirsql-0.4.117 → dirsql-0.4.118}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  392. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/CHANGELOG.md +0 -0
  393. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/MIGRATIONS.md +0 -0
  394. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/README.md +0 -0
  395. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/benches/db_bench.rs +0 -0
  396. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/benches/differ_bench.rs +0 -0
  397. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/benches/matcher_bench.rs +0 -0
  398. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/benches/scanner_bench.rs +0 -0
  399. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/context/.gitattributes +0 -0
  400. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/context/recipes.md +0 -0
  401. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/context/troubleshooting.md +0 -0
  402. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/context/usage.md +0 -0
  403. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/explanation.md +0 -0
  404. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/getting-started.md +0 -0
  405. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/agent-skill.md +0 -0
  406. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  407. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/define-tables.md +0 -0
  408. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/embed.md +0 -0
  409. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  410. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/load-extension.md +0 -0
  411. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  412. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/persist.md +0 -0
  413. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/query-json.md +0 -0
  414. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/query-without-config.md +0 -0
  415. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/react-to-changes.md +0 -0
  416. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  417. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/search-indexes.md +0 -0
  418. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/skip-files.md +0 -0
  419. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  420. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/index.md +0 -0
  421. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/plugins.md +0 -0
  422. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/reference/cli.md +0 -0
  423. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/reference/columns.md +0 -0
  424. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/reference/config.md +0 -0
  425. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/reference/glob.md +0 -0
  426. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/reference/hooks.md +0 -0
  427. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/reference/http-api.md +0 -0
  428. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/reference/path-tables.md +0 -0
  429. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/reference/sdk.md +0 -0
  430. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/speed.json +0 -0
  431. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/docs/speed.md +0 -0
  432. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/bin/dirsql.rs +0 -0
  433. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/brace.rs +0 -0
  434. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/context.rs +0 -0
  435. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/execute.rs +0 -0
  436. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/frontend.html +0 -0
  437. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/frontend.js +0 -0
  438. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/init.rs +0 -0
  439. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/mod.rs +0 -0
  440. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/repl.rs +0 -0
  441. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/router.rs +0 -0
  442. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/run.rs +0 -0
  443. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/serialize.rs +0 -0
  444. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/server.rs +0 -0
  445. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/cli/table.rs +0 -0
  446. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/command.rs +0 -0
  447. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/config.rs +0 -0
  448. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/db.rs +0 -0
  449. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/default_config.toml +0 -0
  450. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/differ.rs +0 -0
  451. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/extension_resolution.rs +0 -0
  452. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/functions.rs +0 -0
  453. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/gitignore_frame.rs +0 -0
  454. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/infer.rs +0 -0
  455. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/launcher.rs +0 -0
  456. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/lib.rs +0 -0
  457. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/matcher.rs +0 -0
  458. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/on_file.rs +0 -0
  459. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/parsed_vtab.rs +0 -0
  460. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/path_table.rs +0 -0
  461. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/per_thread.rs +0 -0
  462. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/persist.rs +0 -0
  463. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/posix_class.rs +0 -0
  464. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/progress.rs +0 -0
  465. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/row_event_flat.rs +0 -0
  466. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/row_stream.rs +0 -0
  467. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/sql_literal.rs +0 -0
  468. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/tree_walk.rs +0 -0
  469. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/vtab.rs +0 -0
  470. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/vtab_scaffold.rs +0 -0
  471. {dirsql-0.4.117 → dirsql-0.4.118}/packages/rust/src/watcher.rs +0 -0
  472. {dirsql-0.4.117 → dirsql-0.4.118}/pyproject.toml +0 -0
@@ -573,7 +573,7 @@ dependencies = [
573
573
 
574
574
  [[package]]
575
575
  name = "dirsql"
576
- version = "0.4.117"
576
+ version = "0.4.118"
577
577
  dependencies = [
578
578
  "assert_cmd",
579
579
  "axum",
@@ -625,7 +625,7 @@ dependencies = [
625
625
 
626
626
  [[package]]
627
627
  name = "dirsql-py-ext"
628
- version = "0.4.117"
628
+ version = "0.4.118"
629
629
  dependencies = [
630
630
  "dirsql",
631
631
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.4.117
3
+ Version: 0.4.118
4
4
  Requires-Dist: bin-shim>=0.1
5
5
  Summary: Ephemeral SQL index over a local directory
6
6
  Keywords: sql,filesystem,directory,sqlite,index
@@ -4,7 +4,7 @@ name = "dirsql-py-ext"
4
4
  # pypi/maturin handler can rewrite it via `write-version` before
5
5
  # `maturin build`. `pyproject.toml` declares `dynamic = ["version"]`
6
6
  # and maturin reads this field. Mirrors `packages/rust/Cargo.toml`.
7
- version = "0.4.117"
7
+ version = "0.4.118"
8
8
  # abi3 note: the `abi3-py310` pyo3 feature (below) builds ONE stable-ABI
9
9
  # `cp310-abi3` wheel per platform that loads on every CPython >= 3.10
10
10
  # (matching `pyproject.toml`'s `requires-python = ">=3.10"`), instead of
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/glob_speed_depth_bound_test.py tests/e2e/glob_speed_one_level_test.py tests/e2e/glob_speed_recursive_test.py tests/e2e/glob_speed_matchers_test.py tests/e2e/glob_speed_dotfiles_test.py tests/e2e/glob_speed_gitignore_test.py tests/e2e/glob_speed_node_modules_test.py tests/e2e/glob_speed_symlink_test.py tests/e2e/query_contract_test.py tests/e2e/fanout_test.py tests/e2e/use_case_join_test.py -q -s",
3
+ "ran_at": 1792413540,
4
+ "exit_code": 0,
5
+ "commit": "0ee771430a40eb21956092c09afab9357d75820e",
6
+ "branch": "bot/1461-chunked-read-1016"
7
+ }
@@ -6,7 +6,7 @@ description = "Ephemeral SQL index over a local directory"
6
6
  # version stays for the binding crates (publish = false). The literal
7
7
  # intentionally lags the published version: putitoutthere rewrites it to
8
8
  # the planned release version at build time and never commits it back.
9
- version = "0.4.117"
9
+ version = "0.4.118"
10
10
  edition.workspace = true
11
11
  # Literal `license` (not `license.workspace = true`) because
12
12
  # putitoutthere's preflight check reads `[package].license` directly
@@ -1,7 +1,7 @@
1
- //! A directory's entries, read in one pass and sorted by name.
1
+ //! A directory's entries, read in chunks and sorted by name.
2
2
  //!
3
- //! The names share one buffer rather than one allocation each, which in a
4
- //! directory of a million files is most of what reading it costs.
3
+ //! Each chunk's names share one buffer rather than one allocation each, which
4
+ //! in a directory of a million files is most of what reading it costs.
5
5
 
6
6
  use std::ffi::OsStr;
7
7
  use std::path::Path;
@@ -18,21 +18,88 @@ pub(crate) enum Seen {
18
18
  Unknown,
19
19
  }
20
20
 
21
- /// One entry of a [`Listing`]: where its name sits, and what it is.
21
+ /// One entry of a [`Listing`]: which chunk's buffer its name sits in and
22
+ /// where, and what it is.
22
23
  #[derive(Debug, Clone, Copy)]
23
24
  pub(crate) struct Listed {
24
25
  prefix: u64,
25
- start: usize,
26
- end: usize,
26
+ chunk: u32,
27
+ start: u32,
28
+ end: u32,
27
29
  pub(crate) seen: Seen,
28
30
  }
29
31
 
32
+ /// The most entries a [`Chunk`] holds, which keeps every offset into its
33
+ /// names within a `u32`.
34
+ const CHUNK_ENTRIES: usize = 8192;
35
+
36
+ /// Entries read in a row, at most [`CHUNK_ENTRIES`] of them, with their names.
30
37
  #[derive(Default)]
31
- pub(crate) struct Listing {
38
+ pub(crate) struct Chunk {
39
+ index: u32,
32
40
  names: Names,
33
41
  entries: Vec<Listed>,
34
42
  }
35
43
 
44
+ impl Chunk {
45
+ fn new(index: u32) -> Chunk {
46
+ Chunk {
47
+ index,
48
+ ..Chunk::default()
49
+ }
50
+ }
51
+
52
+ fn is_full(&self) -> bool {
53
+ self.entries.len() == CHUNK_ENTRIES
54
+ }
55
+
56
+ fn push(&mut self, name: &OsStr, seen: Seen) {
57
+ let start = self.names.add(name);
58
+ self.entries.push(Listed {
59
+ prefix: name_prefix(name),
60
+ chunk: self.index,
61
+ start,
62
+ end: start + span(name),
63
+ seen,
64
+ });
65
+ }
66
+ }
67
+
68
+ /// Gathers entries into chunks, handing each to `emit` once full.
69
+ struct Chunker<'e> {
70
+ chunk: Chunk,
71
+ emit: &'e mut dyn FnMut(Chunk),
72
+ }
73
+
74
+ impl<'e> Chunker<'e> {
75
+ fn new(emit: &'e mut dyn FnMut(Chunk)) -> Chunker<'e> {
76
+ Chunker {
77
+ chunk: Chunk::default(),
78
+ emit,
79
+ }
80
+ }
81
+
82
+ fn push(&mut self, name: &OsStr, seen: Seen) {
83
+ if self.chunk.is_full() {
84
+ let next = Chunk::new(self.chunk.index + 1);
85
+ (self.emit)(std::mem::replace(&mut self.chunk, next));
86
+ }
87
+ self.chunk.push(name, seen);
88
+ }
89
+
90
+ fn finish(self) {
91
+ if !self.chunk.entries.is_empty() {
92
+ (self.emit)(self.chunk);
93
+ }
94
+ }
95
+ }
96
+
97
+ #[derive(Default)]
98
+ pub(crate) struct Listing {
99
+ names: Vec<Names>,
100
+ entries: Vec<Listed>,
101
+ }
102
+
36
103
  /// One buffer holding every name end to end.
37
104
  #[cfg(unix)]
38
105
  #[derive(Default)]
@@ -40,16 +107,16 @@ struct Packed(Vec<u8>);
40
107
 
41
108
  #[cfg(unix)]
42
109
  impl Packed {
43
- fn add(&mut self, name: &OsStr) -> usize {
110
+ fn add(&mut self, name: &OsStr) -> u32 {
44
111
  use std::os::unix::ffi::OsStrExt;
45
- let start = self.0.len();
112
+ let start = offset(self.0.len());
46
113
  self.0.extend_from_slice(name.as_bytes());
47
114
  start
48
115
  }
49
116
 
50
- fn get(&self, start: usize, end: usize) -> &OsStr {
117
+ fn get(&self, start: u32, end: u32) -> &OsStr {
51
118
  use std::os::unix::ffi::OsStrExt;
52
- OsStr::from_bytes(&self.0[start..end])
119
+ OsStr::from_bytes(&self.0[start as usize..end as usize])
53
120
  }
54
121
  }
55
122
 
@@ -61,16 +128,27 @@ struct Owned(Vec<std::ffi::OsString>);
61
128
 
62
129
  #[cfg(any(test, not(unix)))]
63
130
  impl Owned {
64
- fn add(&mut self, name: &OsStr) -> usize {
131
+ fn add(&mut self, name: &OsStr) -> u32 {
65
132
  self.0.push(name.to_os_string());
66
- self.0.len() - 1
133
+ offset(self.0.len() - 1)
67
134
  }
68
135
 
69
- fn get(&self, start: usize, _end: usize) -> &OsStr {
70
- &self.0[start]
136
+ fn get(&self, start: u32, _end: u32) -> &OsStr {
137
+ &self.0[start as usize]
71
138
  }
72
139
  }
73
140
 
141
+ /// `n` as a chunk offset, which a chunk of at most [`CHUNK_ENTRIES`] names of
142
+ /// at most a few hundred bytes each never outgrows.
143
+ fn offset(n: usize) -> u32 {
144
+ u32::try_from(n).expect("a chunk's names fit in u32 offsets")
145
+ }
146
+
147
+ /// How far a name reaches past its start in a chunk's names.
148
+ fn span(name: &OsStr) -> u32 {
149
+ offset(name.len())
150
+ }
151
+
74
152
  #[cfg(unix)]
75
153
  type Names = Packed;
76
154
  #[cfg(not(unix))]
@@ -81,7 +159,7 @@ impl Listing {
81
159
  /// cannot be read.
82
160
  pub(crate) fn read(dir: &Path) -> Listing {
83
161
  let mut listing = Listing::default();
84
- read_into(dir, &mut listing);
162
+ read_chunks(dir, &mut |chunk| listing.add(chunk));
85
163
  listing.sort();
86
164
  listing
87
165
  }
@@ -90,14 +168,11 @@ impl Listing {
90
168
  &self.entries
91
169
  }
92
170
 
93
- pub(crate) fn push(&mut self, name: &OsStr, seen: Seen) {
94
- let start = self.names.add(name);
95
- self.entries.push(Listed {
96
- prefix: name_prefix(name),
97
- start,
98
- end: start + name.len(),
99
- seen,
100
- });
171
+ /// Takes `chunk` in, which must be the next one read.
172
+ fn add(&mut self, chunk: Chunk) {
173
+ debug_assert_eq!(chunk.index as usize, self.names.len());
174
+ self.names.push(chunk.names);
175
+ self.entries.extend(chunk.entries);
101
176
  }
102
177
 
103
178
  /// Whether an entry is named `name`; the listing must be sorted.
@@ -108,7 +183,7 @@ impl Listing {
108
183
  }
109
184
 
110
185
  pub(crate) fn name(&self, listed: &Listed) -> &OsStr {
111
- self.names.get(listed.start, listed.end)
186
+ self.names[listed.chunk as usize].get(listed.start, listed.end)
112
187
  }
113
188
 
114
189
  pub(crate) fn sort(&mut self) {
@@ -145,11 +220,19 @@ fn open_dir(dir: &Path) -> rustix::io::Result<rustix::fd::OwnedFd> {
145
220
  rustix::fs::open(dir, flags, Mode::empty())
146
221
  }
147
222
 
223
+ /// The entries of `dir` in the order the filesystem lists them, handed to
224
+ /// `emit` a chunk at a time as they are read; none when it cannot be read.
225
+ pub(crate) fn read_chunks(dir: &Path, emit: &mut dyn FnMut(Chunk)) {
226
+ let mut chunker = Chunker::new(emit);
227
+ read_into(dir, &mut chunker);
228
+ chunker.finish();
229
+ }
230
+
148
231
  /// Uses `Dir`, not `RawDir`: on a deep tree of small directories the walk ran
149
232
  /// about twice as slow reading through `RawDir`, with no gain on a flat
150
233
  /// directory of a million entries.
151
234
  #[cfg(unix)]
152
- fn read_into(dir: &Path, listing: &mut Listing) {
235
+ fn read_into(dir: &Path, listing: &mut Chunker<'_>) {
153
236
  use rustix::fs::Dir;
154
237
  use std::os::unix::ffi::OsStrExt;
155
238
  let Ok(fd) = open_dir(dir) else {
@@ -168,7 +251,7 @@ fn read_into(dir: &Path, listing: &mut Listing) {
168
251
  }
169
252
 
170
253
  #[cfg(any(test, not(unix)))]
171
- fn read_dir_into(dir: &Path, listing: &mut Listing) {
254
+ fn read_dir_into(dir: &Path, listing: &mut Chunker<'_>) {
172
255
  let Ok(entries) = std::fs::read_dir(dir) else {
173
256
  return;
174
257
  };
@@ -215,12 +298,34 @@ mod tests {
215
298
  .collect()
216
299
  }
217
300
 
218
- #[test]
219
- fn a_listing_sorts_its_names_into_byte_order() {
301
+ fn chunks_of(names: impl IntoIterator<Item = (String, Seen)>) -> Vec<Chunk> {
302
+ let mut chunks = Vec::new();
303
+ let mut emit = |chunk| chunks.push(chunk);
304
+ let mut chunker = Chunker::new(&mut emit);
305
+ for (name, seen) in names {
306
+ chunker.push(OsStr::new(&name), seen);
307
+ }
308
+ chunker.finish();
309
+ chunks
310
+ }
311
+
312
+ fn listing_of(names: &[(&str, Seen)]) -> Listing {
220
313
  let mut listing = Listing::default();
221
- for name in ["abcdefghZ", "b", "abcdefgh", "ab", "abcdefghA", "abc", "B"] {
222
- listing.push(OsStr::new(name), Seen::File);
314
+ let named = names.iter().map(|&(name, seen)| (name.to_string(), seen));
315
+ for chunk in chunks_of(named) {
316
+ listing.add(chunk);
223
317
  }
318
+ listing
319
+ }
320
+
321
+ fn numbered(count: usize) -> impl Iterator<Item = (String, Seen)> {
322
+ (0..count).map(|i| (format!("n{i:05}"), Seen::File))
323
+ }
324
+
325
+ #[test]
326
+ fn a_listing_sorts_its_names_into_byte_order() {
327
+ let pushed = ["abcdefghZ", "b", "abcdefgh", "ab", "abcdefghA", "abc", "B"];
328
+ let mut listing = listing_of(&pushed.map(|name| (name, Seen::File)));
224
329
  listing.sort();
225
330
  assert_eq!(
226
331
  names(&listing),
@@ -230,10 +335,7 @@ mod tests {
230
335
 
231
336
  #[test]
232
337
  fn a_sorted_entry_keeps_what_it_was_seen_as() {
233
- let mut listing = Listing::default();
234
- listing.push(OsStr::new("z"), Seen::Dir);
235
- listing.push(OsStr::new("y"), Seen::Link);
236
- listing.push(OsStr::new("x"), Seen::Unknown);
338
+ let mut listing = listing_of(&[("z", Seen::Dir), ("y", Seen::Link), ("x", Seen::Unknown)]);
237
339
  listing.sort();
238
340
  let seen: Vec<_> = listing.entries().iter().map(|listed| listed.seen).collect();
239
341
  assert_eq!(seen, [Seen::Unknown, Seen::Link, Seen::Dir]);
@@ -241,17 +343,60 @@ mod tests {
241
343
 
242
344
  #[test]
243
345
  fn a_listing_hands_back_each_name_as_pushed() {
244
- let mut listing = Listing::default();
245
- listing.push(OsStr::new("first"), Seen::File);
246
- listing.push(OsStr::new("second"), Seen::Other);
346
+ let listing = listing_of(&[("first", Seen::File), ("second", Seen::Other)]);
247
347
  assert_eq!(names(&listing), ["first", "second"]);
248
348
  }
249
349
 
350
+ #[test]
351
+ fn a_chunk_holds_at_most_chunk_entries_and_the_rest_start_the_next() {
352
+ let chunks = chunks_of(numbered(2 * CHUNK_ENTRIES + 1));
353
+ let shape: Vec<_> = chunks
354
+ .iter()
355
+ .map(|chunk| (chunk.index, chunk.entries.len()))
356
+ .collect();
357
+ assert_eq!(shape, [(0, CHUNK_ENTRIES), (1, CHUNK_ENTRIES), (2, 1)]);
358
+ }
359
+
360
+ #[test]
361
+ fn a_chunker_of_no_entries_hands_out_no_chunk() {
362
+ assert!(chunks_of(numbered(0)).is_empty());
363
+ }
364
+
365
+ #[test]
366
+ fn a_listing_sorts_names_from_every_chunk_together() {
367
+ let count = CHUNK_ENTRIES + 2;
368
+ let mut listing = Listing::default();
369
+ for chunk in chunks_of(numbered(count).collect::<Vec<_>>().into_iter().rev()) {
370
+ listing.add(chunk);
371
+ }
372
+ listing.sort();
373
+ let expected: Vec<_> = numbered(count).map(|(name, _)| name).collect();
374
+ let got: Vec<_> = names(&listing)
375
+ .into_iter()
376
+ .map(|name| name.to_string_lossy().into_owned())
377
+ .collect();
378
+ assert_eq!(got, expected);
379
+ }
380
+
381
+ #[cfg(unix)]
382
+ #[test]
383
+ fn read_chunks_hands_out_a_wide_directory_a_chunk_at_a_time() {
384
+ let dir = tempfile::tempdir().unwrap();
385
+ for i in 0..=CHUNK_ENTRIES {
386
+ std::fs::File::create(dir.path().join(format!("f{i}"))).unwrap();
387
+ }
388
+ let mut sizes = Vec::new();
389
+ read_chunks(dir.path(), &mut |chunk| sizes.push(chunk.entries.len()));
390
+ assert_eq!(sizes, [CHUNK_ENTRIES, 1]);
391
+ }
392
+
250
393
  #[test]
251
394
  fn a_sorted_listing_holds_exactly_the_names_pushed() {
252
395
  let mut listing = Listing::default();
253
- for name in [".gitignore", "b", ".git", "a"] {
254
- listing.push(OsStr::new(name), Seen::File);
396
+ for chunk in
397
+ chunks_of([".gitignore", "b", ".git", "a"].map(|name| (name.to_string(), Seen::File)))
398
+ {
399
+ listing.add(chunk);
255
400
  }
256
401
  listing.sort();
257
402
  assert!(listing.holds(OsStr::new(".git")));
@@ -279,9 +424,12 @@ mod tests {
279
424
  );
280
425
  }
281
426
 
282
- fn read_with(read: fn(&Path, &mut Listing), dir: &Path) -> Vec<(String, Seen)> {
427
+ fn read_with(read: fn(&Path, &mut Chunker<'_>), dir: &Path) -> Vec<(String, Seen)> {
283
428
  let mut listing = Listing::default();
284
- read(dir, &mut listing);
429
+ let mut emit = |chunk| listing.add(chunk);
430
+ let mut chunker = Chunker::new(&mut emit);
431
+ read(dir, &mut chunker);
432
+ chunker.finish();
285
433
  listing.sort();
286
434
  listing
287
435
  .entries()
@@ -712,7 +712,9 @@ impl<'a> Place<'a> {
712
712
  .iter()
713
713
  .map(|listed| {
714
714
  let name = listing.name(listed);
715
- if listed.seen == Seen::File && !keep_name(name) {
715
+ // No entry is named ""; joining one would re-enter this
716
+ // directory without end.
717
+ if name.is_empty() || (listed.seen == Seen::File && !keep_name(name)) {
716
718
  return None;
717
719
  }
718
720
  walk.take(dir, name, listed.seen, rel, states, *linked)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes