dirsql 0.4.4__tar.gz → 0.4.6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (217) hide show
  1. {dirsql-0.4.4 → dirsql-0.4.6}/Cargo.lock +1 -2
  2. {dirsql-0.4.4 → dirsql-0.4.6}/PKG-INFO +1 -1
  3. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/_async.py +17 -0
  4. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/Cargo.toml +1 -1
  5. dirsql-0.4.6/packages/python/changelog.d/2026-08-02-scan-failures.md +18 -0
  6. dirsql-0.4.6/packages/python/e2e-attestations/claude-715-binding-scan-failures.json +7 -0
  7. dirsql-0.4.6/packages/python/e2e-attestations/claude-716-drop-regex.json +7 -0
  8. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/src/lib.rs +37 -0
  9. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/Cargo.toml +0 -1
  10. dirsql-0.4.6/packages/rust/changelog.d/2026-08-02-drop-regex.md +17 -0
  11. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/matcher.rs +48 -6
  12. {dirsql-0.4.4 → dirsql-0.4.6}/Cargo.toml +0 -0
  13. {dirsql-0.4.4 → dirsql-0.4.6}/README.md +0 -0
  14. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/__init__.py +0 -0
  15. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/_dirsql.pyi +0 -0
  16. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/__init__.py +0 -0
  17. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/binary_path.py +0 -0
  18. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/discover_plugins/__init__.py +0 -0
  19. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  20. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  21. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  22. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
  23. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
  24. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/is_windows.py +0 -0
  25. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/main.py +0 -0
  26. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/cli/resolve_config_extensions.py +0 -0
  27. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/py.typed +0 -0
  28. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/resolve_config_extensions.py +0 -0
  29. {dirsql-0.4.4 → dirsql-0.4.6}/dirsql/resolve_extension.py +0 -0
  30. {dirsql-0.4.4 → dirsql-0.4.6}/docs/.claude/CLAUDE.md +0 -0
  31. {dirsql-0.4.4 → dirsql-0.4.6}/docs/.vitepress/config.ts +0 -0
  32. {dirsql-0.4.4 → dirsql-0.4.6}/docs/.vitepress/theme/index.ts +0 -0
  33. {dirsql-0.4.4 → dirsql-0.4.6}/docs/.vitepress/theme/lang.ts +0 -0
  34. {dirsql-0.4.4 → dirsql-0.4.6}/docs/AGENTS.md +0 -0
  35. {dirsql-0.4.4 → dirsql-0.4.6}/docs/explanation.md +0 -0
  36. {dirsql-0.4.4 → dirsql-0.4.6}/docs/getting-started.md +0 -0
  37. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/columns-from-paths.md +0 -0
  38. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/define-tables.md +0 -0
  39. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/embed.md +0 -0
  40. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/extract-from-contents.md +0 -0
  41. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/load-extension.md +0 -0
  42. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/parse-files-into-columns.md +0 -0
  43. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/persist.md +0 -0
  44. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/query-without-config.md +0 -0
  45. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/react-to-changes.md +0 -0
  46. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/search-by-meaning.md +0 -0
  47. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/skip-files.md +0 -0
  48. {dirsql-0.4.4 → dirsql-0.4.6}/docs/howto/write-a-plugin.md +0 -0
  49. {dirsql-0.4.4 → dirsql-0.4.6}/docs/index.md +0 -0
  50. {dirsql-0.4.4 → dirsql-0.4.6}/docs/migrations.md +0 -0
  51. {dirsql-0.4.4 → dirsql-0.4.6}/docs/package.json +0 -0
  52. {dirsql-0.4.4 → dirsql-0.4.6}/docs/pnpm-lock.yaml +0 -0
  53. {dirsql-0.4.4 → dirsql-0.4.6}/docs/pnpm-workspace.yaml +0 -0
  54. {dirsql-0.4.4 → dirsql-0.4.6}/docs/reference/cli.md +0 -0
  55. {dirsql-0.4.4 → dirsql-0.4.6}/docs/reference/columns.md +0 -0
  56. {dirsql-0.4.4 → dirsql-0.4.6}/docs/reference/config.md +0 -0
  57. {dirsql-0.4.4 → dirsql-0.4.6}/docs/reference/hooks.md +0 -0
  58. {dirsql-0.4.4 → dirsql-0.4.6}/docs/reference/http-api.md +0 -0
  59. {dirsql-0.4.4 → dirsql-0.4.6}/docs/reference/path-tables.md +0 -0
  60. {dirsql-0.4.4 → dirsql-0.4.6}/docs/reference/sdk.md +0 -0
  61. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/CHANGELOG.md +0 -0
  62. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/MIGRATIONS.md +0 -0
  63. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/README.md +0 -0
  64. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  65. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  66. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  67. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  68. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  69. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  70. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  71. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  72. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  73. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  74. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  75. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/changelog.d/README.md +0 -0
  76. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/conftest.py +0 -0
  77. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/.claude/CLAUDE.md +0 -0
  78. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/.vitepress/config.ts +0 -0
  79. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  80. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  81. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/AGENTS.md +0 -0
  82. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/explanation.md +0 -0
  83. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/getting-started.md +0 -0
  84. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/columns-from-paths.md +0 -0
  85. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/define-tables.md +0 -0
  86. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/embed.md +0 -0
  87. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/extract-from-contents.md +0 -0
  88. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/load-extension.md +0 -0
  89. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  90. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/persist.md +0 -0
  91. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/query-without-config.md +0 -0
  92. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/react-to-changes.md +0 -0
  93. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/search-by-meaning.md +0 -0
  94. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/skip-files.md +0 -0
  95. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/howto/write-a-plugin.md +0 -0
  96. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/index.md +0 -0
  97. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/migrations.md +0 -0
  98. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/package.json +0 -0
  99. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/pnpm-lock.yaml +0 -0
  100. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/pnpm-workspace.yaml +0 -0
  101. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/reference/cli.md +0 -0
  102. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/reference/columns.md +0 -0
  103. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/reference/config.md +0 -0
  104. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/reference/hooks.md +0 -0
  105. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/reference/http-api.md +0 -0
  106. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/reference/path-tables.md +0 -0
  107. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/docs/reference/sdk.md +0 -0
  108. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/e2e-attestations/claude-710-accumulate-onfile.json +0 -0
  109. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/e2e-attestations/claude-714-unify-file-failures.json +0 -0
  110. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  111. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  112. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  113. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  114. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  115. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  116. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  117. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  118. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/migrations.d/README.md +0 -0
  119. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/tests/__init__.py +0 -0
  120. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/tests/conftest.py +0 -0
  121. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/tests/e2e/__init__.py +0 -0
  122. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  123. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  124. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/tests/integration/__init__.py +0 -0
  125. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/tests/integration/binding/__init__.py +0 -0
  126. {dirsql-0.4.4 → dirsql-0.4.6}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  127. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/CHANGELOG.md +0 -0
  128. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/MIGRATIONS.md +0 -0
  129. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/README.md +0 -0
  130. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/benches/db_bench.rs +0 -0
  131. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/benches/differ_bench.rs +0 -0
  132. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/benches/matcher_bench.rs +0 -0
  133. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/benches/scanner_bench.rs +0 -0
  134. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-13-batch-ingest-transaction.md +0 -0
  135. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-13-chained-pre-post-query-hooks.md +0 -0
  136. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  137. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-13-fan-out-file-table-matching.md +0 -0
  138. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-13-persist-wal.md +0 -0
  139. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  140. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-13-repeatable-builder-config.md +0 -0
  141. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-13-repeatable-cli-config.md +0 -0
  142. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  143. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-13-subcommand-local-config-flags.md +0 -0
  144. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-19-path-table-query-fallback.md +0 -0
  145. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-19-path-table-vtab.md +0 -0
  146. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  147. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-20-path-table-glob-semantics.md +0 -0
  148. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-20-schema-inference.md +0 -0
  149. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-21-on-file-flag.md +0 -0
  150. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  151. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-23-init-escalation-example.md +0 -0
  152. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-23-query-default-cli.md +0 -0
  153. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  154. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  155. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-07-29-on-file-failures-accumulate.md +0 -0
  156. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-08-02-per-file-scan-failures.md +0 -0
  157. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/2026-08-02-release-profile.md +0 -0
  158. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/changelog.d/README.md +0 -0
  159. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/explanation.md +0 -0
  160. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/getting-started.md +0 -0
  161. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  162. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/define-tables.md +0 -0
  163. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/embed.md +0 -0
  164. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  165. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/load-extension.md +0 -0
  166. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  167. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/persist.md +0 -0
  168. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/query-without-config.md +0 -0
  169. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/react-to-changes.md +0 -0
  170. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  171. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/skip-files.md +0 -0
  172. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  173. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/index.md +0 -0
  174. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/migrations.md +0 -0
  175. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/reference/cli.md +0 -0
  176. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/reference/columns.md +0 -0
  177. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/reference/config.md +0 -0
  178. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/reference/hooks.md +0 -0
  179. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/reference/http-api.md +0 -0
  180. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/reference/path-tables.md +0 -0
  181. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/docs/reference/sdk.md +0 -0
  182. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  183. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-13-fan-out-file-table-matching.md +0 -0
  184. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-13-persist-wal.md +0 -0
  185. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  186. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  187. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-13-subcommand-local-config-flags.md +0 -0
  188. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  189. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-20-path-table-glob-semantics.md +0 -0
  190. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  191. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-23-init-escalation-example.md +0 -0
  192. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-23-query-default-cli.md +0 -0
  193. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  194. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  195. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/2026-08-02-per-file-scan-failures.md +0 -0
  196. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/migrations.d/README.md +0 -0
  197. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/bin/dirsql.rs +0 -0
  198. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/cli/execute.rs +0 -0
  199. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/cli/init.rs +0 -0
  200. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/cli/mod.rs +0 -0
  201. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/cli/router.rs +0 -0
  202. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/cli/serialize.rs +0 -0
  203. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/cli/server.rs +0 -0
  204. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/command.rs +0 -0
  205. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/config.rs +0 -0
  206. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/db.rs +0 -0
  207. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/default_config.toml +0 -0
  208. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/differ.rs +0 -0
  209. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/infer.rs +0 -0
  210. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/lib.rs +0 -0
  211. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/parsed_vtab.rs +0 -0
  212. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/path_table.rs +0 -0
  213. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/persist.rs +0 -0
  214. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/scanner.rs +0 -0
  215. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/vtab.rs +0 -0
  216. {dirsql-0.4.4 → dirsql-0.4.6}/packages/rust/src/watcher.rs +0 -0
  217. {dirsql-0.4.4 → dirsql-0.4.6}/pyproject.toml +0 -0
@@ -473,7 +473,6 @@ dependencies = [
473
473
  "libc",
474
474
  "notify",
475
475
  "predicates",
476
- "regex",
477
476
  "reqwest",
478
477
  "rusqlite",
479
478
  "serde",
@@ -500,7 +499,7 @@ dependencies = [
500
499
 
501
500
  [[package]]
502
501
  name = "dirsql-py-ext"
503
- version = "0.4.4"
502
+ version = "0.4.6"
504
503
  dependencies = [
505
504
  "dirsql",
506
505
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.4.4
3
+ Version: 0.4.6
4
4
  Requires-Dist: tomli>=2 ; python_full_version < '3.11'
5
5
  Summary: Ephemeral SQL index over a local directory
6
6
  Keywords: sql,filesystem,directory,sqlite,index
@@ -182,6 +182,23 @@ class DirSQL:
182
182
  assert db is not None # ready() returned, so _init_bg set _db
183
183
  return await asyncio.to_thread(db.query, sql)
184
184
 
185
+ async def scan_failures(self):
186
+ """The files the initial scan could not index.
187
+
188
+ Each entry carries ``path`` (relative to the root) and ``message``
189
+ (the hook's own error). Empty after a clean scan, which is the signal
190
+ to check: a non-empty list means the index is *incomplete*, not wrong,
191
+ and those files are retried on the next scan.
192
+
193
+ Awaits :meth:`ready` first, so the scan has finished before the answer
194
+ is read -- otherwise a caller could see an empty list simply because
195
+ the scan had not reached the failing file yet.
196
+ """
197
+ await self.ready()
198
+ db = self._db
199
+ assert db is not None # ready() returned, so _init_bg set _db
200
+ return db.scan_failures()
201
+
185
202
  def watch(self):
186
203
  """Start watching for file changes. Returns an async iterable of RowEvent.
187
204
 
@@ -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.4"
7
+ version = "0.4.6"
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,18 @@
1
+ **Added**
2
+
3
+ `await db.scan_failures()` returns the files the initial scan could not index —
4
+ a list of `ScanFailure`, each with `path` (relative to the root) and `message`
5
+ (the hook's own error). Empty after a clean scan (#715).
6
+
7
+ This closes a gap opened by #714. A file whose `on_file` hook raises, or whose
8
+ row the table rejects under `strict`, is skipped rather than failing the scan —
9
+ so a Python caller who previously got an exception got nothing at all: a
10
+ database quietly holding fewer rows, with no way to ask which files were
11
+ dropped. `scan_failures()` is that way.
12
+
13
+ It reports; it does not gate. The rows that did land are unaffected, and a
14
+ skipped file never enters the persistent index, so it is retried on the next
15
+ scan — the index is incomplete, never wrong.
16
+
17
+ Awaits `ready()` first, so an empty list means the scan finished cleanly rather
18
+ than that it had not yet reached the failing file.
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/ -x -q",
3
+ "ran_at": 1785678666,
4
+ "exit_code": 0,
5
+ "commit": "7de7557be856f19685344a4118e1ead9e4bae405",
6
+ "branch": "claude/715-binding-scan-failures"
7
+ }
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "uv run python -m pytest tests/e2e/ -x -q",
3
+ "ran_at": 1785679612,
4
+ "exit_code": 0,
5
+ "commit": "f24a5f661d5538bc5f3ef27a266fac7cc1e955ad",
6
+ "branch": "claude/716-drop-regex"
7
+ }
@@ -97,6 +97,31 @@ mod python {
97
97
  }
98
98
  }
99
99
 
100
+ /// One file the initial scan could not index, with the hook's own error.
101
+ ///
102
+ /// A scan failure is not a scan *error*: the other files are indexed and
103
+ /// the database is usable. This is how a caller learns the index is
104
+ /// incomplete, and which files are missing from it.
105
+ #[pyclass(name = "ScanFailure", frozen)]
106
+ struct PyScanFailure {
107
+ /// Path relative to the scan root.
108
+ #[pyo3(get)]
109
+ path: String,
110
+ /// The hook's error, as it rendered it.
111
+ #[pyo3(get)]
112
+ message: String,
113
+ }
114
+
115
+ #[pymethods]
116
+ impl PyScanFailure {
117
+ fn __repr__(&self) -> String {
118
+ format!(
119
+ "ScanFailure(path={:?}, message={:?})",
120
+ self.path, self.message
121
+ )
122
+ }
123
+ }
124
+
100
125
  /// Synchronous binding class. `dirsql._async.DirSQL` wraps it with
101
126
  /// `asyncio.to_thread` to produce the async public API.
102
127
  #[pyclass(name = "DirSQL")]
@@ -179,6 +204,17 @@ mod python {
179
204
  Ok(list.unbind())
180
205
  }
181
206
 
207
+ fn scan_failures(&self) -> Vec<PyScanFailure> {
208
+ self.inner
209
+ .scan_failures()
210
+ .iter()
211
+ .map(|f| PyScanFailure {
212
+ path: f.path.clone(),
213
+ message: f.message.clone(),
214
+ })
215
+ .collect()
216
+ }
217
+
182
218
  fn _start_watcher(&self, py: Python<'_>) -> PyResult<()> {
183
219
  let db = self.inner.clone();
184
220
  py.detach(move || db.start_watching()).map_err(to_py_err)
@@ -415,6 +451,7 @@ mod python {
415
451
  m.add_class::<PyTable>()?;
416
452
  m.add_class::<PyDirSQL>()?;
417
453
  m.add_class::<PyRowEvent>()?;
454
+ m.add_class::<PyScanFailure>()?;
418
455
  Ok(())
419
456
  }
420
457
 
@@ -56,7 +56,6 @@ futures = { version = "0.3", optional = true }
56
56
  futures-channel.workspace = true
57
57
  globset = "0.4"
58
58
  notify = "7"
59
- regex.workspace = true
60
59
  rusqlite = { version = "0.34", features = ["bundled", "load_extension", "hooks", "vtab"] }
61
60
  serde.workspace = true
62
61
  serde_json.workspace = true
@@ -0,0 +1,17 @@
1
+ **Changed** — the `regex` dependency is gone. `matcher.rs` used it for one
2
+ trivial pattern (`{name}` placeholder extraction in path templates); that is now
3
+ a hand-rolled scan over the same grammar, `{` `[a-zA-Z_][a-zA-Z0-9_]*` `}`.
4
+
5
+ Dropping the `regex` facade lets cargo drop the `regex-automata` features
6
+ `globset` does not need, shrinking every published artifact by ~570 KB
7
+ (CLI 6.14 -> 5.57 MB, pyo3 `.so` 4.99 -> 4.42 MB, napi `.node` 5.05 -> 4.48 MB;
8
+ ~9-11% each, on top of the release-profile change).
9
+
10
+ Matcher construction also gets ~28x faster, since a `TableMatcher` no longer
11
+ compiles two regexes per pattern: 23.8 us -> 0.87 us for one pattern,
12
+ 1.38 ms -> 47.8 us for fifty. Match throughput is unchanged (`globset` does the
13
+ matching).
14
+
15
+ No behavior change: `placeholder_names` keeps its signature and its exact
16
+ grammar, verified against the previous regex over 2,830 inputs with zero
17
+ mismatches.
@@ -1,5 +1,4 @@
1
1
  use globset::{Glob, GlobSet, GlobSetBuilder};
2
- use regex::Regex;
3
2
  use std::path::Path;
4
3
 
5
4
  /// Result of matching a file path against a glob pattern.
@@ -25,19 +24,62 @@ pub struct TableMatcher {
25
24
  ignore_set: GlobSet,
26
25
  }
27
26
 
27
+ /// Byte spans of the `{name}` placeholders in `pattern`, in order: `(start,
28
+ /// end, name)` with `end` past the closing brace.
29
+ ///
30
+ /// The grammar is exactly `{` `[a-zA-Z_][a-zA-Z0-9_]*` `}`. Anything else --
31
+ /// `{}`, `{1a}`, `{a-b}`, an unclosed `{` -- is not a placeholder and is left
32
+ /// alone, matching the leftmost-first, non-overlapping scan the equivalent
33
+ /// regex performed.
34
+ fn placeholder_spans(pattern: &str) -> Vec<(usize, usize, String)> {
35
+ let bytes = pattern.as_bytes();
36
+ let mut spans = Vec::new();
37
+ let mut i = 0;
38
+ while i < bytes.len() {
39
+ if bytes[i] == b'{' {
40
+ let mut j = i + 1;
41
+ if j < bytes.len() && (bytes[j].is_ascii_alphabetic() || bytes[j] == b'_') {
42
+ j += 1;
43
+ while j < bytes.len() && (bytes[j].is_ascii_alphanumeric() || bytes[j] == b'_') {
44
+ j += 1;
45
+ }
46
+ if j < bytes.len() && bytes[j] == b'}' {
47
+ // Every byte in `i..=j` is ASCII, so these are char boundaries.
48
+ spans.push((i, j + 1, pattern[i + 1..j].to_string()));
49
+ i = j + 1;
50
+ continue;
51
+ }
52
+ }
53
+ }
54
+ i += 1;
55
+ }
56
+ spans
57
+ }
58
+
28
59
  /// Names of the `{name}` placeholders in `pattern`, in order of appearance.
29
60
  pub fn placeholder_names(pattern: &str) -> Vec<String> {
30
- let re = Regex::new(r"\{([a-zA-Z_][a-zA-Z0-9_]*)\}").unwrap();
31
- re.captures_iter(pattern)
32
- .map(|cap| cap[1].to_string())
61
+ placeholder_spans(pattern)
62
+ .into_iter()
63
+ .map(|(_, _, name)| name)
33
64
  .collect()
34
65
  }
35
66
 
36
67
  /// Rewrite `{name}` placeholders in a glob to `*`, so they match a single path
37
68
  /// segment without producing any captured value.
38
69
  fn glob_with_placeholders_as_star(pattern: &str) -> String {
39
- let re = Regex::new(r"\{([a-zA-Z_][a-zA-Z0-9_]*)\}").unwrap();
40
- re.replace_all(pattern, "*").into_owned()
70
+ let spans = placeholder_spans(pattern);
71
+ if spans.is_empty() {
72
+ return pattern.to_string();
73
+ }
74
+ let mut out = String::with_capacity(pattern.len());
75
+ let mut last = 0;
76
+ for (start, end, _) in spans {
77
+ out.push_str(&pattern[last..start]);
78
+ out.push('*');
79
+ last = end;
80
+ }
81
+ out.push_str(&pattern[last..]);
82
+ out
41
83
  }
42
84
 
43
85
  impl TableMatcher {
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
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