dirsql 0.4.116__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.116 → dirsql-0.4.118}/Cargo.lock +2 -2
  2. {dirsql-0.4.116 → dirsql-0.4.118}/PKG-INFO +1 -1
  3. {dirsql-0.4.116 → 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.118/packages/python/e2e-attestations/bot-1477-onelevel-speed-1016.json +7 -0
  6. dirsql-0.4.118/packages/python/e2e-attestations/bot-1524-path-eq-1016.json +7 -0
  7. dirsql-0.4.118/packages/python/e2e-attestations/bot-1532-gitignore-fastest-bar-1016.json +7 -0
  8. dirsql-0.4.118/packages/python/e2e-attestations/bot-1534-fm-native-1016.json +7 -0
  9. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/Cargo.toml +1 -1
  10. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/db.rs +71 -51
  11. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/lib.rs +159 -49
  12. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/listing.rs +190 -42
  13. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/scanner.rs +228 -141
  14. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/tree_walk.rs +2 -84
  15. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/vtab_scaffold.rs +96 -11
  16. {dirsql-0.4.116 → dirsql-0.4.118}/Cargo.toml +0 -0
  17. {dirsql-0.4.116 → dirsql-0.4.118}/README.md +0 -0
  18. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/__init__.py +0 -0
  19. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/_async.py +0 -0
  20. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/_dirsql.pyi +0 -0
  21. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/cli/__init__.py +0 -0
  22. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/cli/discover_plugins/__init__.py +0 -0
  23. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  24. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  25. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  26. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
  27. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/cli/main.py +0 -0
  28. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/cli/resolve_config_extensions.py +0 -0
  29. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/plan_entry_path.py +0 -0
  30. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/py.typed +0 -0
  31. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/read_config.py +0 -0
  32. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/resolve_configs_extension_specs.py +0 -0
  33. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/resolve_extension.py +0 -0
  34. {dirsql-0.4.116 → dirsql-0.4.118}/dirsql/resolve_package.py +0 -0
  35. {dirsql-0.4.116 → dirsql-0.4.118}/docs/.claude/CLAUDE.md +0 -0
  36. {dirsql-0.4.116 → dirsql-0.4.118}/docs/.vitepress/config.ts +0 -0
  37. {dirsql-0.4.116 → dirsql-0.4.118}/docs/.vitepress/theme/index.ts +0 -0
  38. {dirsql-0.4.116 → dirsql-0.4.118}/docs/.vitepress/theme/lang.ts +0 -0
  39. {dirsql-0.4.116 → dirsql-0.4.118}/docs/AGENTS.md +0 -0
  40. {dirsql-0.4.116 → dirsql-0.4.118}/docs/context/.gitattributes +0 -0
  41. {dirsql-0.4.116 → dirsql-0.4.118}/docs/context/recipes.md +0 -0
  42. {dirsql-0.4.116 → dirsql-0.4.118}/docs/context/troubleshooting.md +0 -0
  43. {dirsql-0.4.116 → dirsql-0.4.118}/docs/context/usage.md +0 -0
  44. {dirsql-0.4.116 → dirsql-0.4.118}/docs/explanation.md +0 -0
  45. {dirsql-0.4.116 → dirsql-0.4.118}/docs/getting-started.md +0 -0
  46. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/agent-skill.md +0 -0
  47. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/columns-from-paths.md +0 -0
  48. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/define-tables.md +0 -0
  49. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/embed.md +0 -0
  50. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/extract-from-contents.md +0 -0
  51. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/load-extension.md +0 -0
  52. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/parse-files-into-columns.md +0 -0
  53. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/persist.md +0 -0
  54. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/query-json.md +0 -0
  55. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/query-without-config.md +0 -0
  56. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/react-to-changes.md +0 -0
  57. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/search-by-meaning.md +0 -0
  58. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/search-indexes.md +0 -0
  59. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/skip-files.md +0 -0
  60. {dirsql-0.4.116 → dirsql-0.4.118}/docs/howto/write-a-plugin.md +0 -0
  61. {dirsql-0.4.116 → dirsql-0.4.118}/docs/index.md +0 -0
  62. {dirsql-0.4.116 → dirsql-0.4.118}/docs/package.json +0 -0
  63. {dirsql-0.4.116 → dirsql-0.4.118}/docs/plugins.md +0 -0
  64. {dirsql-0.4.116 → dirsql-0.4.118}/docs/pnpm-lock.yaml +0 -0
  65. {dirsql-0.4.116 → dirsql-0.4.118}/docs/pnpm-workspace.yaml +0 -0
  66. {dirsql-0.4.116 → dirsql-0.4.118}/docs/reference/cli.md +0 -0
  67. {dirsql-0.4.116 → dirsql-0.4.118}/docs/reference/columns.md +0 -0
  68. {dirsql-0.4.116 → dirsql-0.4.118}/docs/reference/config.md +0 -0
  69. {dirsql-0.4.116 → dirsql-0.4.118}/docs/reference/glob.md +0 -0
  70. {dirsql-0.4.116 → dirsql-0.4.118}/docs/reference/hooks.md +0 -0
  71. {dirsql-0.4.116 → dirsql-0.4.118}/docs/reference/http-api.md +0 -0
  72. {dirsql-0.4.116 → dirsql-0.4.118}/docs/reference/path-tables.md +0 -0
  73. {dirsql-0.4.116 → dirsql-0.4.118}/docs/reference/sdk.md +0 -0
  74. {dirsql-0.4.116 → dirsql-0.4.118}/docs/speed.json +0 -0
  75. {dirsql-0.4.116 → dirsql-0.4.118}/docs/speed.md +0 -0
  76. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/CHANGELOG.md +0 -0
  77. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/MIGRATIONS.md +0 -0
  78. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/README.md +0 -0
  79. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  80. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  81. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  82. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  83. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  84. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  85. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  86. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  87. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  88. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  89. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  90. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
  91. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
  92. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
  93. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
  94. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
  95. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
  96. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
  97. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
  98. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
  99. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
  100. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
  101. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
  102. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
  103. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
  104. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
  105. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
  106. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
  107. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  108. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  109. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
  110. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  111. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
  112. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  113. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-brace-groups-follow-bash.md +0 -0
  114. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-cli-context.md +0 -0
  115. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-gitignore-requires-repo.md +0 -0
  116. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-path-table-node-modules-named.md +0 -0
  117. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
  118. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +0 -0
  119. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
  120. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-braces.md +0 -0
  121. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-directory.md +0 -0
  122. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-dotnames.md +0 -0
  123. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-gitignore.md +0 -0
  124. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
  125. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-config-links.md +0 -0
  126. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-one-glob-compiler.md +0 -0
  127. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-plugin-no-default-records.md +0 -0
  128. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-watch-broadcast.md +0 -0
  129. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-06-zero-match-config-table-warning.md +0 -0
  130. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-bracket-slash-literal.md +0 -0
  131. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
  132. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-dotdot-as-written.md +0 -0
  133. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-glob-walks-node-modules.md +0 -0
  134. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-literal-gitignore.md +0 -0
  135. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-on-file-ndjson.md +0 -0
  136. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-parallel-hooks.md +0 -0
  137. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-persist-cache-outside-root.md +0 -0
  138. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-posix-classes-unicode.md +0 -0
  139. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-07-spread-few-large-files.md +0 -0
  140. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
  141. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/2026-10-08-watch-requires-named-table.md +0 -0
  142. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/changelog.d/README.md +0 -0
  143. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/conftest.py +0 -0
  144. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/.claude/CLAUDE.md +0 -0
  145. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/.vitepress/config.ts +0 -0
  146. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  147. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  148. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/AGENTS.md +0 -0
  149. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/context/.gitattributes +0 -0
  150. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/context/recipes.md +0 -0
  151. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/context/troubleshooting.md +0 -0
  152. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/context/usage.md +0 -0
  153. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/explanation.md +0 -0
  154. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/getting-started.md +0 -0
  155. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/agent-skill.md +0 -0
  156. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/columns-from-paths.md +0 -0
  157. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/define-tables.md +0 -0
  158. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/embed.md +0 -0
  159. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/extract-from-contents.md +0 -0
  160. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/load-extension.md +0 -0
  161. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  162. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/persist.md +0 -0
  163. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/query-json.md +0 -0
  164. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/query-without-config.md +0 -0
  165. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/react-to-changes.md +0 -0
  166. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/search-by-meaning.md +0 -0
  167. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/search-indexes.md +0 -0
  168. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/skip-files.md +0 -0
  169. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/howto/write-a-plugin.md +0 -0
  170. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/index.md +0 -0
  171. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/package.json +0 -0
  172. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/plugins.md +0 -0
  173. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/pnpm-lock.yaml +0 -0
  174. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/pnpm-workspace.yaml +0 -0
  175. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/reference/cli.md +0 -0
  176. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/reference/columns.md +0 -0
  177. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/reference/config.md +0 -0
  178. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/reference/glob.md +0 -0
  179. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/reference/hooks.md +0 -0
  180. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/reference/http-api.md +0 -0
  181. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/reference/path-tables.md +0 -0
  182. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/reference/sdk.md +0 -0
  183. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/speed.json +0 -0
  184. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/docs/speed.md +0 -0
  185. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1334-listing-exemptions.json +0 -0
  186. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1397-watch-broadcast.json +0 -0
  187. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1398-inotify-error.json +0 -0
  188. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1399-server-cors.json +0 -0
  189. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1401-watch-scope.json +0 -0
  190. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1406-watch-no-tables-1008.json +0 -0
  191. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1407-child-place-depth.json +0 -0
  192. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1414-stat-speed.json +0 -0
  193. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1415-server-speed.json +0 -0
  194. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1416-watch-speed-1008.json +0 -0
  195. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1418-node-modules.json +0 -0
  196. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1419-dotdot-slashes.json +0 -0
  197. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1420-bracket-slash.json +0 -0
  198. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1421-posix-unicode.json +0 -0
  199. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1422-literal-gitignore.json +0 -0
  200. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1426-walk-spawn-threshold-1008.json +0 -0
  201. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1428-ndjson-hooks.json +0 -0
  202. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1429-parallel-hooks.json +0 -0
  203. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1430-dotdot-as-written.json +0 -0
  204. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1431-persist-cache-dir.json +0 -0
  205. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1437-test-cache-isolation.json +0 -0
  206. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1440-fix-main-build.json +0 -0
  207. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1448-wildcard-ignored-prefix.json +0 -0
  208. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1451-named-dir-never-hidden.json +0 -0
  209. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1454-split-few-files.json +0 -0
  210. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1457-incremental-refresh-1008.json +0 -0
  211. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1459-rescan-on-overflow-1008.json +0 -0
  212. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1461-row-footprint-1008.json +0 -0
  213. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1461-wide-read-1015.json +0 -0
  214. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1462-paired-speed-harness-1008.json +0 -0
  215. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1464-fastest-native-1008.json +0 -0
  216. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1469-ci-speed-sanity-1009.json +0 -0
  217. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1470-perf-suite-1009.json +0 -0
  218. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1470-speed-page-1011.json +0 -0
  219. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1474-vtab-speed-1014.json +0 -0
  220. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1477-onelevel-speed-1015.json +0 -0
  221. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1480-matcher-speed-1015.json +0 -0
  222. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1481-gitrepo-speed-1015.json +0 -0
  223. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1483-fm-speed-1015.json +0 -0
  224. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1484-jsonl-speed-1015.json +0 -0
  225. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1487-frontend-query-1011.json +0 -0
  226. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1488-frontend-metadata-1011.json +0 -0
  227. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1489-frontend-browse-1013.json +0 -0
  228. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1503-bench-watch-1011.json +0 -0
  229. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1504-bench-names-1011.json +0 -0
  230. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1514-watch-rerun-inline-1015.json +0 -0
  231. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-1526-main-red-1016.json +0 -0
  232. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-fix-main-place-depth-20261007.json +0 -0
  233. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-issue-1486-frontend-20261009.json +0 -0
  234. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-gap-childpath-1011.json +0 -0
  235. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-parse-overlap-1011.json +0 -0
  236. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-parse-paths-1009.json +0 -0
  237. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-parse-pragmas-1011.json +0 -0
  238. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-sql-valueref-1013.json +0 -0
  239. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-walk-components-1011.json +0 -0
  240. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-walk-rowpath-1011.json +0 -0
  241. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-walk-rows-1013.json +0 -0
  242. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/bot-speed-walk-sched-1009.json +0 -0
  243. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
  244. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
  245. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
  246. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
  247. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
  248. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
  249. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
  250. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
  251. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
  252. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
  253. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
  254. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
  255. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
  256. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
  257. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
  258. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
  259. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
  260. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
  261. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
  262. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
  263. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
  264. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
  265. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
  266. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
  267. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
  268. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
  269. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
  270. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
  271. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
  272. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
  273. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
  274. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
  275. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
  276. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
  277. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1225-plugin-no-default.json +0 -0
  278. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
  279. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1232-anchor-plumbing.json +0 -0
  280. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1232-config-anchor.json +0 -0
  281. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1232-multi-watch.json +0 -0
  282. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1232-zero-match.json +0 -0
  283. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
  284. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
  285. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
  286. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
  287. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
  288. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1257-trailing-slash.json +0 -0
  289. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-config-braces.json +0 -0
  290. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-config-directory.json +0 -0
  291. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-config-dotnames.json +0 -0
  292. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-config-gitignore.json +0 -0
  293. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-config-links.json +0 -0
  294. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1258-one-pattern.json +0 -0
  295. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1262-brace-literal.json +0 -0
  296. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1264-context.json +0 -0
  297. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1267-posix-classes.json +0 -0
  298. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1268-unbalanced-brackets.json +0 -0
  299. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1269-utf8-chars.json +0 -0
  300. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1271-node-modules-named.json +0 -0
  301. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1272-ancestor-gitignore.json +0 -0
  302. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1273-walk-prune.json +0 -0
  303. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1285-ingest-fast.json +0 -0
  304. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1286-nested-repo.json +0 -0
  305. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1305-glob-speed.json +0 -0
  306. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1308-glob-speed.json +0 -0
  307. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1310-glob-speed.json +0 -0
  308. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1311-glob-speed.json +0 -0
  309. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1312-glob-speed.json +0 -0
  310. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1318-lazy-stat.json +0 -0
  311. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1320-walk-speed.json +0 -0
  312. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1322-walk-readdir.json +0 -0
  313. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1325-parallel-walk.json +0 -0
  314. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1326-stream-rows.json +0 -0
  315. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-python-dirsql-patch.json +0 -0
  316. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-python-extensions-patch.json +0 -0
  317. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-scanner-effects.json +0 -0
  318. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-scanner-gitignore.json +0 -0
  319. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-vtab-prefetch-flag.json +0 -0
  320. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1330-vtab-read.json +0 -0
  321. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-1351-dot-dirs.json +0 -0
  322. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
  323. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
  324. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
  325. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
  326. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
  327. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
  328. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
  329. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
  330. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
  331. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
  332. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
  333. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
  334. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
  335. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
  336. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
  337. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  338. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  339. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  340. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  341. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  342. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  343. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  344. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  345. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
  346. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
  347. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  348. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  349. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
  350. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  351. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
  352. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  353. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-brace-groups-follow-bash.md +0 -0
  354. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-cli-context.md +0 -0
  355. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-gitignore-requires-repo.md +0 -0
  356. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-path-table-node-modules-named.md +0 -0
  357. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
  358. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +0 -0
  359. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-05-unbalanced-brackets-literal.md +0 -0
  360. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-braces.md +0 -0
  361. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-directory.md +0 -0
  362. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-dotnames.md +0 -0
  363. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-gitignore.md +0 -0
  364. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-globs-anchor-at-the-config.md +0 -0
  365. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-config-links.md +0 -0
  366. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-one-glob-compiler.md +0 -0
  367. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-plugin-no-default-records.md +0 -0
  368. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-watch-broadcast.md +0 -0
  369. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-06-zero-match-config-table-warning.md +0 -0
  370. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-bracket-slash-literal.md +0 -0
  371. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-dotdot-and-double-slashes.md +0 -0
  372. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-dotdot-as-written.md +0 -0
  373. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-glob-walks-node-modules.md +0 -0
  374. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-literal-gitignore.md +0 -0
  375. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-on-file-ndjson.md +0 -0
  376. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-parallel-hooks.md +0 -0
  377. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-persist-cache-outside-root.md +0 -0
  378. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-posix-classes-unicode.md +0 -0
  379. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-07-spread-few-large-files.md +0 -0
  380. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-08-small-walks-stay-on-one-thread.md +0 -0
  381. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/2026-10-08-watch-requires-named-table.md +0 -0
  382. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/migrations.d/README.md +0 -0
  383. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/src/lib.rs +0 -0
  384. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/testing-conventions.toml +0 -0
  385. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/__init__.py +0 -0
  386. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/conftest.py +0 -0
  387. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/e2e/__init__.py +0 -0
  388. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/e2e/bench_report.py +0 -0
  389. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/e2e/bench_suite.py +0 -0
  390. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  391. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  392. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/e2e/speed_of_light.py +0 -0
  393. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/integration/__init__.py +0 -0
  394. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/integration/binding/__init__.py +0 -0
  395. {dirsql-0.4.116 → dirsql-0.4.118}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  396. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/CHANGELOG.md +0 -0
  397. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/MIGRATIONS.md +0 -0
  398. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/README.md +0 -0
  399. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/benches/db_bench.rs +0 -0
  400. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/benches/differ_bench.rs +0 -0
  401. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/benches/matcher_bench.rs +0 -0
  402. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/benches/scanner_bench.rs +0 -0
  403. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/context/.gitattributes +0 -0
  404. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/context/recipes.md +0 -0
  405. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/context/troubleshooting.md +0 -0
  406. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/context/usage.md +0 -0
  407. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/explanation.md +0 -0
  408. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/getting-started.md +0 -0
  409. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/agent-skill.md +0 -0
  410. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  411. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/define-tables.md +0 -0
  412. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/embed.md +0 -0
  413. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  414. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/load-extension.md +0 -0
  415. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  416. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/persist.md +0 -0
  417. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/query-json.md +0 -0
  418. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/query-without-config.md +0 -0
  419. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/react-to-changes.md +0 -0
  420. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  421. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/search-indexes.md +0 -0
  422. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/skip-files.md +0 -0
  423. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  424. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/index.md +0 -0
  425. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/plugins.md +0 -0
  426. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/reference/cli.md +0 -0
  427. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/reference/columns.md +0 -0
  428. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/reference/config.md +0 -0
  429. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/reference/glob.md +0 -0
  430. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/reference/hooks.md +0 -0
  431. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/reference/http-api.md +0 -0
  432. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/reference/path-tables.md +0 -0
  433. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/reference/sdk.md +0 -0
  434. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/speed.json +0 -0
  435. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/docs/speed.md +0 -0
  436. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/bin/dirsql.rs +0 -0
  437. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/brace.rs +0 -0
  438. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/context.rs +0 -0
  439. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/execute.rs +0 -0
  440. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/frontend.html +0 -0
  441. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/frontend.js +0 -0
  442. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/init.rs +0 -0
  443. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/mod.rs +0 -0
  444. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/repl.rs +0 -0
  445. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/router.rs +0 -0
  446. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/run.rs +0 -0
  447. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/serialize.rs +0 -0
  448. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/server.rs +0 -0
  449. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/cli/table.rs +0 -0
  450. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/command.rs +0 -0
  451. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/config.rs +0 -0
  452. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/default_config.toml +0 -0
  453. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/differ.rs +0 -0
  454. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/extension_resolution.rs +0 -0
  455. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/functions.rs +0 -0
  456. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/gitignore_frame.rs +0 -0
  457. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/infer.rs +0 -0
  458. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/launcher.rs +0 -0
  459. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/matcher.rs +0 -0
  460. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/on_file.rs +0 -0
  461. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/parsed_vtab.rs +0 -0
  462. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/path_table.rs +0 -0
  463. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/per_thread.rs +0 -0
  464. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/persist.rs +0 -0
  465. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/posix_class.rs +0 -0
  466. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/progress.rs +0 -0
  467. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/row_event_flat.rs +0 -0
  468. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/row_stream.rs +0 -0
  469. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/sql_literal.rs +0 -0
  470. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/vtab.rs +0 -0
  471. {dirsql-0.4.116 → dirsql-0.4.118}/packages/rust/src/watcher.rs +0 -0
  472. {dirsql-0.4.116 → 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.116"
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.116"
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.116
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.116"
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
+ }
@@ -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": 1792409702,
4
+ "exit_code": 0,
5
+ "commit": "f500062c3a69da8d29e351d1a5580cff8f5af696",
6
+ "branch": "bot/1477-onelevel-speed-1016"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/glob_speed_recursive_test.py tests/e2e/use_case_join_test.py -x -q",
3
+ "ran_at": 1792151597,
4
+ "exit_code": 0,
5
+ "commit": "05acaa67201b49a50f43b35cd3f3204d13a6a544",
6
+ "branch": "bot/1524-path-eq-1016"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/glob_speed_gitignore_test.py -x -q -s",
3
+ "ran_at": 1792155745,
4
+ "exit_code": 0,
5
+ "commit": "fb06f3cf1239d66c0cc2fff6a297448cbd12365a",
6
+ "branch": "bot/1532-gitignore-fastest-bar-1016"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/frontmatter_parse_speed_test.py tests/e2e/jsonl_parse_speed_test.py tests/e2e/on_file_query_test.py tests/e2e/fanout_test.py tests/e2e/declared_table_name_test.py tests/e2e/query_contract_test.py tests/e2e/use_case_notebook_test.py tests/e2e/use_case_transcripts_test.py tests/e2e/sigint_interrupt_test.py -q -s",
3
+ "ran_at": 1792158472,
4
+ "exit_code": 0,
5
+ "commit": "4eaa7f0c26fa324fdb9b161e90fdb3fe22b8774f",
6
+ "branch": "bot/1534-fm-native-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.116"
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
@@ -312,6 +312,63 @@ impl ShapedRows {
312
312
  }
313
313
  }
314
314
 
315
+ /// [`Db::shape_rows`] against `columns`, the table's columns in DDL order,
316
+ /// so rows can be shaped off the connection's thread.
317
+ pub(crate) fn shape_json_rows(
318
+ table: &str,
319
+ columns: Vec<String>,
320
+ rows: Vec<JsonRow>,
321
+ strict: bool,
322
+ ) -> Result<ShapedRows> {
323
+ let mut cells = Vec::with_capacity(rows.len());
324
+ for row in rows {
325
+ if strict {
326
+ for (key, _) in &row.0 {
327
+ validate_identifier(key)?;
328
+ }
329
+ let extra: Vec<&str> = row
330
+ .0
331
+ .iter()
332
+ .map(|(key, _)| &**key)
333
+ .filter(|key| !columns.iter().any(|c| c == key))
334
+ .collect();
335
+ if !extra.is_empty() {
336
+ return Err(DbError::SchemaMismatch(format!(
337
+ "extra columns not in table {}: {}",
338
+ table,
339
+ extra.join(", ")
340
+ )));
341
+ }
342
+ let missing: Vec<&str> = columns
343
+ .iter()
344
+ .map(String::as_str)
345
+ .filter(|c| !row.0.iter().any(|(key, _)| **key == **c))
346
+ .collect();
347
+ if !missing.is_empty() {
348
+ return Err(DbError::SchemaMismatch(format!(
349
+ "missing columns for table {}: {}",
350
+ table,
351
+ missing.join(", ")
352
+ )));
353
+ }
354
+ }
355
+ let in_order = row.0.len() == columns.len()
356
+ && row.0.iter().zip(&columns).all(|((key, _), c)| **key == **c);
357
+ if in_order {
358
+ cells.push(row.0.into_iter().map(|(_, v)| json_into_value(v)).collect());
359
+ continue;
360
+ }
361
+ let mut shaped = vec![Value::Null; columns.len()];
362
+ for (key, value) in row.0 {
363
+ if let Some(i) = columns.iter().position(|c| **c == *key) {
364
+ shaped[i] = json_into_value(value);
365
+ }
366
+ }
367
+ cells.push(shaped);
368
+ }
369
+ Ok(ShapedRows { columns, cells })
370
+ }
371
+
315
372
  fn json_into_value(value: serde_json::Value) -> Value {
316
373
  match value {
317
374
  serde_json::Value::String(s) => Value::Text(s),
@@ -566,9 +623,10 @@ impl Db {
566
623
  /// Return the column names declared in `table`'s DDL.
567
624
  pub fn get_table_columns(&self, table: &str) -> Result<Vec<String>> {
568
625
  validate_identifier(table)?;
569
- let mut stmt = self
570
- .conn
571
- .prepare(&format!("PRAGMA table_info({})", table))?;
626
+ let mut stmt = self.conn.prepare(&format!(
627
+ "PRAGMA table_info({})",
628
+ crate::sql_literal::quote_identifier(table)
629
+ ))?;
572
630
  let columns: Vec<String> = stmt
573
631
  .query_map([], |row| row.get::<_, String>(1))?
574
632
  .filter_map(|r| r.ok())
@@ -714,54 +772,7 @@ impl Db {
714
772
  /// a less-actionable "extra columns" mismatch. Every row is shaped before
715
773
  /// any is returned, so a hook that got one row wrong fails as a unit.
716
774
  pub fn shape_rows(&self, table: &str, rows: Vec<JsonRow>, strict: bool) -> Result<ShapedRows> {
717
- let columns = self.get_table_columns(table)?;
718
- let mut cells = Vec::with_capacity(rows.len());
719
- for row in rows {
720
- if strict {
721
- for (key, _) in &row.0 {
722
- validate_identifier(key)?;
723
- }
724
- let extra: Vec<&str> = row
725
- .0
726
- .iter()
727
- .map(|(key, _)| &**key)
728
- .filter(|key| !columns.iter().any(|c| c == key))
729
- .collect();
730
- if !extra.is_empty() {
731
- return Err(DbError::SchemaMismatch(format!(
732
- "extra columns not in table {}: {}",
733
- table,
734
- extra.join(", ")
735
- )));
736
- }
737
- let missing: Vec<&str> = columns
738
- .iter()
739
- .map(String::as_str)
740
- .filter(|c| !row.0.iter().any(|(key, _)| **key == **c))
741
- .collect();
742
- if !missing.is_empty() {
743
- return Err(DbError::SchemaMismatch(format!(
744
- "missing columns for table {}: {}",
745
- table,
746
- missing.join(", ")
747
- )));
748
- }
749
- }
750
- let in_order = row.0.len() == columns.len()
751
- && row.0.iter().zip(&columns).all(|((key, _), c)| **key == **c);
752
- if in_order {
753
- cells.push(row.0.into_iter().map(|(_, v)| json_into_value(v)).collect());
754
- continue;
755
- }
756
- let mut shaped = vec![Value::Null; columns.len()];
757
- for (key, value) in row.0 {
758
- if let Some(i) = columns.iter().position(|c| **c == *key) {
759
- shaped[i] = json_into_value(value);
760
- }
761
- }
762
- cells.push(shaped);
763
- }
764
- Ok(ShapedRows { columns, cells })
775
+ shape_json_rows(table, self.get_table_columns(table)?, rows, strict)
765
776
  }
766
777
 
767
778
  /// Insert every row of `rows` under `file_path`, in order, through one
@@ -2476,6 +2487,15 @@ mod tests {
2476
2487
  assert!(result.is_err());
2477
2488
  }
2478
2489
 
2490
+ #[test]
2491
+ fn get_table_columns_reads_a_table_named_by_a_keyword() {
2492
+ let db = Db::new().unwrap();
2493
+ db.create_table("order", "CREATE TABLE \"order\" (name TEXT)")
2494
+ .unwrap();
2495
+ let cols = db.get_table_columns("order").unwrap();
2496
+ assert!(cols.contains(&"name".to_string()), "{cols:?}");
2497
+ }
2498
+
2479
2499
  #[test]
2480
2500
  fn get_table_columns_nonexistent_table_returns_empty() {
2481
2501
  let db = Db::new().unwrap();
@@ -1288,20 +1288,11 @@ impl DirSQL {
1288
1288
  // (and that pass the racy-window check) are trusted instead of
1289
1289
  // re-parsed.
1290
1290
  let (scanned_files, deleted) = match &persist_ctx {
1291
- None => {
1292
- let files = scanned
1293
- .into_iter()
1294
- .map(|found| ScannedFile {
1295
- abs_path: found.path,
1296
- rel_path: found.rel_path,
1297
- table_name: found.table_name,
1298
- stat: None,
1299
- trusted: false,
1300
- })
1301
- .collect();
1302
- (files, Vec::new())
1291
+ None => (Scanned::Found(scanned), Vec::new()),
1292
+ Some(ctx) => {
1293
+ let (files, deleted) = reconcile_scan(scanned, ctx, &RealFs)?;
1294
+ (Scanned::Files(files), deleted)
1303
1295
  }
1304
- Some(ctx) => reconcile_scan(scanned, ctx, &RealFs)?,
1305
1296
  };
1306
1297
 
1307
1298
  Ok(PreparedBuild {
@@ -1482,17 +1473,22 @@ impl DirSQL {
1482
1473
  let mut batch_files: HashMap<String, Vec<String>> = HashMap::new();
1483
1474
 
1484
1475
  // Grouping walks every scanned file, so it runs beside the early
1485
- // hooks' inserts instead of ahead of them.
1476
+ // hooks' inserts instead of ahead of them, and settles the early
1477
+ // tables' file lists there too.
1478
+ let early_tables: HashSet<String> = early.keys().cloned().collect();
1486
1479
  let (grouped, streamed) = std::thread::scope(|scope| {
1487
- let grouping = scope.spawn(|| group_scanned(scanned_files, &on_file_map));
1480
+ let grouping = scope.spawn(|| {
1481
+ group_scanned(scanned_files.into_files(), &on_file_map)
1482
+ .map(|(per_file, batches)| (per_file, split_streamed(batches, &early_tables)))
1483
+ });
1488
1484
  let streamed = stream_early(&db, early, &strict_map);
1489
1485
  (
1490
1486
  grouping.join().expect("grouping scanned files panicked"),
1491
1487
  streamed,
1492
1488
  )
1493
1489
  });
1494
- let streamed = streamed?;
1495
- let (per_file, batches) = grouped?;
1490
+ streamed?;
1491
+ let (per_file, (batches, streamed)) = grouped?;
1496
1492
 
1497
1493
  // The phase a user actually waits on: one `on_file` round trip per
1498
1494
  // file or per table, plus whatever the table's DDL triggers on insert.
@@ -1501,8 +1497,15 @@ impl DirSQL {
1501
1497
  + batches
1502
1498
  .iter()
1503
1499
  .map(|(_, _, files)| files.len())
1504
- .sum::<usize>()) as u64;
1500
+ .sum::<usize>()
1501
+ + streamed.iter().map(|(_, rel)| rel.len()).sum::<usize>())
1502
+ as u64;
1505
1503
  let mut done: u64 = 0;
1504
+ for (table_name, rel_paths) in streamed {
1505
+ progress.update(done, Some(total_files));
1506
+ done += rel_paths.len() as u64;
1507
+ batch_files.insert(table_name, rel_paths);
1508
+ }
1506
1509
  for (
1507
1510
  ScannedFile {
1508
1511
  rel_path,
@@ -1580,7 +1583,7 @@ impl DirSQL {
1580
1583
  let current = persist_ready.as_ref().is_some_and(|(deleted, _, _)| {
1581
1584
  files.iter().all(|f| f.trusted) && !deleted.iter().any(|(_, t)| *t == table_name)
1582
1585
  });
1583
- if !current && !streamed.contains(&table_name) {
1586
+ if !current {
1584
1587
  let table_root = anchors.of(&table_name);
1585
1588
  let production = start_hook(hook, abs_paths.into_iter());
1586
1589
  let outcome = stream_table_rows(&db, &table_name, production, strict)
@@ -2004,6 +2007,33 @@ pub struct ScannedFile {
2004
2007
  pub trusted: bool,
2005
2008
  }
2006
2009
 
2010
+ /// The files the startup scan found: as the walk found them, or already
2011
+ /// reconciled against the persistent cache.
2012
+ enum Scanned {
2013
+ Found(Vec<Found>),
2014
+ Files(Vec<ScannedFile>),
2015
+ }
2016
+
2017
+ impl Scanned {
2018
+ /// Every file as a [`ScannedFile`]. A fresh walk's are made here rather
2019
+ /// than in prepare, so the copy runs off the thread that inserts rows.
2020
+ fn into_files(self) -> Vec<ScannedFile> {
2021
+ match self {
2022
+ Self::Found(found) => found
2023
+ .into_iter()
2024
+ .map(|found| ScannedFile {
2025
+ abs_path: found.path,
2026
+ rel_path: found.rel_path,
2027
+ table_name: found.table_name,
2028
+ stat: None,
2029
+ trusted: false,
2030
+ })
2031
+ .collect(),
2032
+ Self::Files(files) => files,
2033
+ }
2034
+ }
2035
+ }
2036
+
2007
2037
  /// Intermediate state produced by [`DirSQL::prepare_resolved`] and consumed
2008
2038
  /// by [`DirSQL::finish_build`]. Opaque on purpose; fields are only visible
2009
2039
  /// to the in-workspace bindings.
@@ -2020,7 +2050,7 @@ pub struct PreparedBuild {
2020
2050
  /// The configured skip rules, carried through so path-table scans apply
2021
2051
  /// the same ones declared tables do.
2022
2052
  ignore: Vec<String>,
2023
- scanned_files: Vec<ScannedFile>,
2053
+ scanned_files: Scanned,
2024
2054
  /// Per-table hooks already running over the paths the scan found, by table.
2025
2055
  early: HashMap<String, Production>,
2026
2056
  persist: Option<PreparedPersist>,
@@ -2437,9 +2467,10 @@ fn collect_table_rows(
2437
2467
 
2438
2468
  /// Replace a per-table hook's rows under [`BATCH_OWNER`], storing each chunk
2439
2469
  /// the hook emits while the hook, on its own thread, goes on producing the
2440
- /// next. The caller's open transaction keeps a failure from being seen: the
2441
- /// outer `Err` is SQLite's, the inner one the hook's or a row's. A hook
2442
- /// failure outranks a row that failed to shape.
2470
+ /// next. Chunks are shaped on a thread of their own, in order, so shaping one
2471
+ /// overlaps inserting the last. The caller's open transaction keeps a failure
2472
+ /// from being seen: the outer `Err` is SQLite's, the inner one the hook's or a
2473
+ /// row's. A hook failure outranks a row that failed to shape.
2443
2474
  fn stream_table_rows(
2444
2475
  db: &Db,
2445
2476
  table: &str,
@@ -2447,17 +2478,32 @@ fn stream_table_rows(
2447
2478
  strict: bool,
2448
2479
  ) -> db::Result<std::result::Result<(), String>> {
2449
2480
  db.delete_rows_by_file(table, BATCH_OWNER)?;
2450
- let mut shaped = Ok(());
2451
- for chunk in production.chunks {
2452
- if shaped.is_err() {
2453
- continue;
2481
+ let columns = db.get_table_columns(table)?;
2482
+ let Production { chunks, handle } = production;
2483
+ let (shaped_tx, shaped_rx) = std::sync::mpsc::channel();
2484
+ let shaper = std::thread::spawn({
2485
+ let table = table.to_string();
2486
+ move || {
2487
+ for chunk in chunks {
2488
+ let shaped = db::shape_json_rows(&table, columns.clone(), chunk, strict);
2489
+ if shaped_tx.send(shaped).is_err() {
2490
+ return;
2491
+ }
2492
+ }
2454
2493
  }
2455
- match db.shape_rows(table, chunk, strict) {
2494
+ });
2495
+ let mut shaped = Ok(());
2496
+ for rows in shaped_rx {
2497
+ match rows {
2456
2498
  Ok(rows) => db.insert_rows(table, &rows, BATCH_OWNER)?,
2457
- Err(e) => shaped = Err(e.to_string()),
2499
+ Err(e) => {
2500
+ shaped = Err(e.to_string());
2501
+ break;
2502
+ }
2458
2503
  }
2459
2504
  }
2460
- let produced = production.handle.join().expect("per-table hook panicked");
2505
+ shaper.join().expect("shaping a hook's rows panicked");
2506
+ let produced = handle.join().expect("per-table hook panicked");
2461
2507
  Ok(produced.and(shaped))
2462
2508
  }
2463
2509
 
@@ -2591,14 +2637,12 @@ fn group_scanned(
2591
2637
  Ok((per_file, batches))
2592
2638
  }
2593
2639
 
2594
- /// Insert the rows of every hook started before the scan, returning the
2595
- /// tables streamed.
2640
+ /// Insert the rows of every hook started before the scan.
2596
2641
  fn stream_early(
2597
2642
  db: &Db,
2598
2643
  early: HashMap<String, Production>,
2599
2644
  strict_map: &HashMap<String, bool>,
2600
- ) -> Result<HashSet<String>> {
2601
- let mut streamed = HashSet::new();
2645
+ ) -> Result<()> {
2602
2646
  for (table_name, production) in early {
2603
2647
  let strict = *strict_map.get(&table_name).unwrap_or(&false);
2604
2648
  if let Err(message) =
@@ -2609,9 +2653,30 @@ fn stream_early(
2609
2653
  message,
2610
2654
  });
2611
2655
  }
2612
- streamed.insert(table_name);
2613
2656
  }
2614
- Ok(streamed)
2657
+ Ok(())
2658
+ }
2659
+
2660
+ /// Split off the batches of tables whose hooks already ran, keeping only
2661
+ /// each one's relative paths in scan order.
2662
+ #[allow(clippy::type_complexity)]
2663
+ fn split_streamed(
2664
+ batches: Vec<(String, Arc<OnFilesFn>, Vec<ScannedFile>)>,
2665
+ streamed: &HashSet<String>,
2666
+ ) -> (
2667
+ Vec<(String, Arc<OnFilesFn>, Vec<ScannedFile>)>,
2668
+ Vec<(String, Vec<String>)>,
2669
+ ) {
2670
+ let mut rest = Vec::new();
2671
+ let mut done = Vec::new();
2672
+ for (table_name, hook, mut files) in batches {
2673
+ if streamed.contains(&table_name) {
2674
+ done.push((table_name, batch_paths(&mut files, false).0));
2675
+ } else {
2676
+ rest.push((table_name, hook, files));
2677
+ }
2678
+ }
2679
+ (rest, done)
2615
2680
  }
2616
2681
 
2617
2682
  fn batch_paths(files: &mut [ScannedFile], keep_rel: bool) -> (Vec<String>, Vec<PathBuf>) {
@@ -3154,7 +3219,7 @@ mod internal_tests {
3154
3219
  0,
3155
3220
  "zero tables can match nothing, so the startup walk is pure waste"
3156
3221
  );
3157
- assert!(prepared.scanned_files.is_empty());
3222
+ assert!(prepared.scanned_files.into_files().is_empty());
3158
3223
  }
3159
3224
 
3160
3225
  /// The skip is narrow: one declared table still walks, and prepare still
@@ -3175,10 +3240,11 @@ mod internal_tests {
3175
3240
  .unwrap();
3176
3241
 
3177
3242
  assert_eq!(scan.calls.get(), 1);
3178
- let found: Vec<&str> = prepared
3243
+ let found: Vec<String> = prepared
3179
3244
  .scanned_files
3180
- .iter()
3181
- .map(|f| f.rel_path.as_str())
3245
+ .into_files()
3246
+ .into_iter()
3247
+ .map(|f| f.rel_path)
3182
3248
  .collect();
3183
3249
  assert_eq!(found, vec!["a.txt"]);
3184
3250
  }
@@ -3295,13 +3361,13 @@ mod internal_tests {
3295
3361
  functions: Vec::new(),
3296
3362
  groups: Vec::new(),
3297
3363
  anchors: TableAnchors::at_root(dir.path()),
3298
- scanned_files: vec![ScannedFile {
3364
+ scanned_files: Scanned::Files(vec![ScannedFile {
3299
3365
  abs_path: PathBuf::new(),
3300
3366
  rel_path: "ghost.txt".into(),
3301
3367
  table_name: "ghost".into(),
3302
3368
  stat: None,
3303
3369
  trusted: false,
3304
- }],
3370
+ }]),
3305
3371
  early: HashMap::new(),
3306
3372
  poll_interval: DEFAULT_POLL_INTERVAL,
3307
3373
  persist: None,
@@ -5367,13 +5433,15 @@ mod internal_tests {
5367
5433
  scanned_files: Vec<ScannedFile>,
5368
5434
  persist: Option<PreparedPersist>,
5369
5435
  ) -> PreparedBuild {
5370
- let scanned_files = scanned_files
5371
- .into_iter()
5372
- .map(|mut file| {
5373
- file.abs_path = root.join(&file.rel_path);
5374
- file
5375
- })
5376
- .collect();
5436
+ let scanned_files = Scanned::Files(
5437
+ scanned_files
5438
+ .into_iter()
5439
+ .map(|mut file| {
5440
+ file.abs_path = root.join(&file.rel_path);
5441
+ file
5442
+ })
5443
+ .collect(),
5444
+ );
5377
5445
  PreparedBuild {
5378
5446
  ignore: Vec::new(),
5379
5447
  root: root.to_path_buf(),
@@ -5710,6 +5778,48 @@ mod internal_tests {
5710
5778
  }
5711
5779
  }
5712
5780
 
5781
+ #[test]
5782
+ fn finish_build_counts_the_files_of_a_hook_started_before_the_scan_toward_the_ingest_total() {
5783
+ let dir = TempDir::new().unwrap();
5784
+ let out = Captured::default();
5785
+ let progress = Progress::new(
5786
+ "indexing",
5787
+ "indexed",
5788
+ "files",
5789
+ Box::new(out.clone()),
5790
+ Box::new(progress::SystemClock),
5791
+ progress::Mode::Always,
5792
+ false,
5793
+ );
5794
+ let notes = Table::new("notes", "CREATE TABLE notes (name TEXT)", "*.md", |_| {
5795
+ Vec::new()
5796
+ });
5797
+ let (items, _) = recording_per_table("items", "*.txt");
5798
+ let (feeds, early) = start_per_table_hooks(std::slice::from_ref(&items));
5799
+ for name in ["a.txt", "b.txt"] {
5800
+ feeds["items"].send(dir.path().join(name)).unwrap();
5801
+ }
5802
+ drop(feeds);
5803
+ let scanned = vec![
5804
+ scanned("a.txt", "items", false),
5805
+ scanned("b.txt", "items", false),
5806
+ scanned("n.md", "notes", false),
5807
+ ];
5808
+ let mut prepared = prepared_build(dir.path(), vec![notes, items], scanned, None);
5809
+ prepared.early = early;
5810
+
5811
+ DirSQL::finish_build_with_fs(prepared, Arc::new(FakeFs::default()), progress).unwrap();
5812
+
5813
+ let text = out.text();
5814
+ for line in [
5815
+ "dirsql: indexing 0/3 files (0%)",
5816
+ "dirsql: indexing 2/3 files (66%)",
5817
+ "dirsql: indexed 3 files in",
5818
+ ] {
5819
+ assert!(text.contains(line), "missing {line:?} in {text:?}");
5820
+ }
5821
+ }
5822
+
5713
5823
  #[test]
5714
5824
  fn finish_build_skips_a_per_file_hook_for_a_file_the_cache_holds() {
5715
5825
  let dir = TempDir::new().unwrap();