dirsql 0.4.43__tar.gz → 0.4.44__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 (234) hide show
  1. {dirsql-0.4.43 → dirsql-0.4.44}/Cargo.lock +2 -2
  2. {dirsql-0.4.43 → dirsql-0.4.44}/PKG-INFO +1 -1
  3. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/Cargo.toml +1 -1
  4. dirsql-0.4.44/packages/python/e2e-attestations/claude-1119-ext-plan.json +7 -0
  5. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/Cargo.toml +1 -1
  6. dirsql-0.4.44/packages/rust/src/extension_resolution.rs +421 -0
  7. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/lib.rs +2 -0
  8. {dirsql-0.4.43 → dirsql-0.4.44}/Cargo.toml +0 -0
  9. {dirsql-0.4.43 → dirsql-0.4.44}/README.md +0 -0
  10. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/__init__.py +0 -0
  11. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/_async.py +0 -0
  12. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/_dirsql.pyi +0 -0
  13. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/__init__.py +0 -0
  14. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/__init__.py +0 -0
  15. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  16. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  17. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  18. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
  19. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
  20. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/main.py +0 -0
  21. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/cli/resolve_config_extensions.py +0 -0
  22. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/has_bare_name.py +0 -0
  23. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/is_bare_name.py +0 -0
  24. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/load_extension_entries.py +0 -0
  25. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/platform_patterns.py +0 -0
  26. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/py.typed +0 -0
  27. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/resolve_config_extensions.py +0 -0
  28. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/resolve_configs_extension_specs.py +0 -0
  29. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/resolve_entries.py +0 -0
  30. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/resolve_extension.py +0 -0
  31. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/resolve_package.py +0 -0
  32. {dirsql-0.4.43 → dirsql-0.4.44}/dirsql/toml_module.py +0 -0
  33. {dirsql-0.4.43 → dirsql-0.4.44}/docs/.claude/CLAUDE.md +0 -0
  34. {dirsql-0.4.43 → dirsql-0.4.44}/docs/.vitepress/config.ts +0 -0
  35. {dirsql-0.4.43 → dirsql-0.4.44}/docs/.vitepress/theme/index.ts +0 -0
  36. {dirsql-0.4.43 → dirsql-0.4.44}/docs/.vitepress/theme/lang.ts +0 -0
  37. {dirsql-0.4.43 → dirsql-0.4.44}/docs/AGENTS.md +0 -0
  38. {dirsql-0.4.43 → dirsql-0.4.44}/docs/explanation.md +0 -0
  39. {dirsql-0.4.43 → dirsql-0.4.44}/docs/getting-started.md +0 -0
  40. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/columns-from-paths.md +0 -0
  41. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/define-tables.md +0 -0
  42. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/embed.md +0 -0
  43. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/extract-from-contents.md +0 -0
  44. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/load-extension.md +0 -0
  45. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/parse-files-into-columns.md +0 -0
  46. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/persist.md +0 -0
  47. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/query-json.md +0 -0
  48. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/query-without-config.md +0 -0
  49. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/react-to-changes.md +0 -0
  50. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/search-by-meaning.md +0 -0
  51. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/search-indexes.md +0 -0
  52. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/skip-files.md +0 -0
  53. {dirsql-0.4.43 → dirsql-0.4.44}/docs/howto/write-a-plugin.md +0 -0
  54. {dirsql-0.4.43 → dirsql-0.4.44}/docs/index.md +0 -0
  55. {dirsql-0.4.43 → dirsql-0.4.44}/docs/package.json +0 -0
  56. {dirsql-0.4.43 → dirsql-0.4.44}/docs/plugins.md +0 -0
  57. {dirsql-0.4.43 → dirsql-0.4.44}/docs/pnpm-lock.yaml +0 -0
  58. {dirsql-0.4.43 → dirsql-0.4.44}/docs/pnpm-workspace.yaml +0 -0
  59. {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/cli.md +0 -0
  60. {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/columns.md +0 -0
  61. {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/config.md +0 -0
  62. {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/hooks.md +0 -0
  63. {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/http-api.md +0 -0
  64. {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/path-tables.md +0 -0
  65. {dirsql-0.4.43 → dirsql-0.4.44}/docs/reference/sdk.md +0 -0
  66. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/CHANGELOG.md +0 -0
  67. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/MIGRATIONS.md +0 -0
  68. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/README.md +0 -0
  69. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  70. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  71. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  72. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  73. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  74. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  75. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  76. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  77. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  78. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  79. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  80. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
  81. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
  82. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
  83. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
  84. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
  85. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
  86. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
  87. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
  88. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
  89. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
  90. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
  91. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
  92. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
  93. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/changelog.d/README.md +0 -0
  94. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/conftest.py +0 -0
  95. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/.claude/CLAUDE.md +0 -0
  96. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/.vitepress/config.ts +0 -0
  97. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  98. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  99. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/AGENTS.md +0 -0
  100. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/explanation.md +0 -0
  101. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/getting-started.md +0 -0
  102. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/columns-from-paths.md +0 -0
  103. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/define-tables.md +0 -0
  104. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/embed.md +0 -0
  105. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/extract-from-contents.md +0 -0
  106. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/load-extension.md +0 -0
  107. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  108. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/persist.md +0 -0
  109. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/query-json.md +0 -0
  110. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/query-without-config.md +0 -0
  111. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/react-to-changes.md +0 -0
  112. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/search-by-meaning.md +0 -0
  113. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/search-indexes.md +0 -0
  114. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/skip-files.md +0 -0
  115. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/howto/write-a-plugin.md +0 -0
  116. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/index.md +0 -0
  117. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/package.json +0 -0
  118. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/plugins.md +0 -0
  119. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/pnpm-lock.yaml +0 -0
  120. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/pnpm-workspace.yaml +0 -0
  121. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/cli.md +0 -0
  122. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/columns.md +0 -0
  123. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/config.md +0 -0
  124. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/hooks.md +0 -0
  125. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/http-api.md +0 -0
  126. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/path-tables.md +0 -0
  127. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/docs/reference/sdk.md +0 -0
  128. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
  129. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
  130. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
  131. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
  132. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
  133. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
  134. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
  135. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
  136. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
  137. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
  138. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
  139. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
  140. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
  141. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
  142. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
  143. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
  144. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
  145. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
  146. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
  147. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
  148. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
  149. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
  150. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
  151. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
  152. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  153. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  154. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  155. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  156. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  157. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  158. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  159. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  160. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
  161. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
  162. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/migrations.d/README.md +0 -0
  163. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/src/lib.rs +0 -0
  164. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/testing-conventions.toml +0 -0
  165. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/__init__.py +0 -0
  166. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/conftest.py +0 -0
  167. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/e2e/__init__.py +0 -0
  168. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  169. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  170. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/integration/__init__.py +0 -0
  171. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/integration/binding/__init__.py +0 -0
  172. {dirsql-0.4.43 → dirsql-0.4.44}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  173. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/CHANGELOG.md +0 -0
  174. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/MIGRATIONS.md +0 -0
  175. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/README.md +0 -0
  176. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/benches/db_bench.rs +0 -0
  177. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/benches/differ_bench.rs +0 -0
  178. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/benches/matcher_bench.rs +0 -0
  179. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/benches/scanner_bench.rs +0 -0
  180. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/explanation.md +0 -0
  181. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/getting-started.md +0 -0
  182. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  183. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/define-tables.md +0 -0
  184. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/embed.md +0 -0
  185. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  186. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/load-extension.md +0 -0
  187. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  188. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/persist.md +0 -0
  189. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/query-json.md +0 -0
  190. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/query-without-config.md +0 -0
  191. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/react-to-changes.md +0 -0
  192. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  193. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/search-indexes.md +0 -0
  194. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/skip-files.md +0 -0
  195. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  196. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/index.md +0 -0
  197. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/plugins.md +0 -0
  198. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/cli.md +0 -0
  199. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/columns.md +0 -0
  200. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/config.md +0 -0
  201. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/hooks.md +0 -0
  202. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/http-api.md +0 -0
  203. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/path-tables.md +0 -0
  204. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/docs/reference/sdk.md +0 -0
  205. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/bin/dirsql.rs +0 -0
  206. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/execute.rs +0 -0
  207. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/init.rs +0 -0
  208. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/mod.rs +0 -0
  209. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/repl.rs +0 -0
  210. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/router.rs +0 -0
  211. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/run.rs +0 -0
  212. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/serialize.rs +0 -0
  213. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/server.rs +0 -0
  214. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/cli/table.rs +0 -0
  215. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/command.rs +0 -0
  216. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/config.rs +0 -0
  217. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/db.rs +0 -0
  218. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/default_config.toml +0 -0
  219. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/differ.rs +0 -0
  220. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/functions.rs +0 -0
  221. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/infer.rs +0 -0
  222. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/launcher.rs +0 -0
  223. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/matcher.rs +0 -0
  224. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/parsed_cache.rs +0 -0
  225. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/parsed_vtab.rs +0 -0
  226. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/path_table.rs +0 -0
  227. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/persist.rs +0 -0
  228. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/progress.rs +0 -0
  229. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/scanner.rs +0 -0
  230. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/sql_literal.rs +0 -0
  231. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/vtab.rs +0 -0
  232. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/vtab_scaffold.rs +0 -0
  233. {dirsql-0.4.43 → dirsql-0.4.44}/packages/rust/src/watcher.rs +0 -0
  234. {dirsql-0.4.43 → dirsql-0.4.44}/pyproject.toml +0 -0
@@ -552,7 +552,7 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
552
552
 
553
553
  [[package]]
554
554
  name = "dirsql"
555
- version = "0.4.43"
555
+ version = "0.4.44"
556
556
  dependencies = [
557
557
  "assert_cmd",
558
558
  "axum",
@@ -597,7 +597,7 @@ dependencies = [
597
597
 
598
598
  [[package]]
599
599
  name = "dirsql-py-ext"
600
- version = "0.4.43"
600
+ version = "0.4.44"
601
601
  dependencies = [
602
602
  "dirsql",
603
603
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.4.43
3
+ Version: 0.4.44
4
4
  Requires-Dist: tomli>=2 ; python_full_version < '3.11'
5
5
  Requires-Dist: bin-shim>=0.1
6
6
  Summary: Ephemeral SQL index over a local directory
@@ -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.43"
7
+ version = "0.4.44"
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": "just test-e2e",
3
+ "ran_at": 1789672718,
4
+ "exit_code": 0,
5
+ "commit": "9f049fb0a4012807ce2b31c220df75b0b33e88e1",
6
+ "branch": "claude/1119-ext-plan"
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.43"
9
+ version = "0.4.44"
10
10
  edition.workspace = true
11
11
  # Literal `license` (not `license.workspace = true`) because
12
12
  # putitoutthere's preflight check reads `[package].license` directly
@@ -0,0 +1,421 @@
1
+ //! Planning the resolution of `[[dirsql.extension]]` entries.
2
+ //!
3
+ //! Each launcher used to carry its own port of this: read the configs, decide
4
+ //! whether any entry names a package rather than a file, resolve the rest
5
+ //! against the config's directory. Only "where is package `X` installed on
6
+ //! this host" is genuinely host-specific (`importlib.util.find_spec` /
7
+ //! `require.resolve`), so that stays with the launcher and comes back here as
8
+ //! a set of directories.
9
+ //!
10
+ //! The suffix list is a parameter because it differs per host: Python counts
11
+ //! `.pyd` as a loadable, Node counts `.node`.
12
+
13
+ use std::fmt;
14
+ use std::path::{Path, PathBuf};
15
+
16
+ use crate::config::{ExtensionSpec, load_config_str};
17
+
18
+ /// One config file's contents, or `None` when it is missing or unreadable.
19
+ ///
20
+ /// `path` must be absolute: entry paths and the bare-name shadow probe resolve
21
+ /// against its parent directory.
22
+ #[derive(Debug, Clone, Copy)]
23
+ pub struct ConfigSource<'a> {
24
+ pub path: &'a Path,
25
+ pub contents: Option<&'a str>,
26
+ }
27
+
28
+ /// One planned extension entry.
29
+ #[derive(Debug, Clone, PartialEq, Eq)]
30
+ pub enum PlanEntry {
31
+ /// A concrete path, already absolute against its config's directory.
32
+ Literal {
33
+ path: PathBuf,
34
+ entrypoint: Option<String>,
35
+ },
36
+ /// A bare package name. Use `shadow` when it is a file on disk; otherwise
37
+ /// locate the package on the host and hand its directories, plus every
38
+ /// file found under them, to [`select_loadable`].
39
+ Package {
40
+ name: String,
41
+ shadow: PathBuf,
42
+ entrypoint: Option<String>,
43
+ },
44
+ }
45
+
46
+ /// Why a package's loadable file could not be picked.
47
+ #[derive(Debug, Clone, PartialEq, Eq)]
48
+ pub enum SelectError {
49
+ NotFound {
50
+ name: String,
51
+ suffixes: Vec<String>,
52
+ dirs: Vec<PathBuf>,
53
+ },
54
+ Ambiguous {
55
+ name: String,
56
+ matches: Vec<PathBuf>,
57
+ },
58
+ }
59
+
60
+ fn join_display(paths: &[PathBuf], sep: &str) -> String {
61
+ paths
62
+ .iter()
63
+ .map(|p| p.display().to_string())
64
+ .collect::<Vec<_>>()
65
+ .join(sep)
66
+ }
67
+
68
+ impl fmt::Display for SelectError {
69
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70
+ match self {
71
+ SelectError::NotFound {
72
+ name,
73
+ suffixes,
74
+ dirs,
75
+ } => {
76
+ let patterns = suffixes
77
+ .iter()
78
+ .map(|s| format!("*{s}"))
79
+ .collect::<Vec<_>>()
80
+ .join(" / ");
81
+ write!(
82
+ f,
83
+ "no loadable extension file ({patterns}) found in package '{name}' (searched {})",
84
+ join_display(dirs, ", ")
85
+ )
86
+ }
87
+ SelectError::Ambiguous { name, matches } => write!(
88
+ f,
89
+ "multiple loadable extension files found in package '{name}': {}; disambiguate with a literal path",
90
+ join_display(matches, ", ")
91
+ ),
92
+ }
93
+ }
94
+ }
95
+
96
+ impl std::error::Error for SelectError {}
97
+
98
+ /// True when `path` names a package rather than a file.
99
+ ///
100
+ /// Both separators count regardless of host, so a Windows-style path is a path
101
+ /// everywhere.
102
+ pub fn is_bare_name(path: &str, suffixes: &[&str]) -> bool {
103
+ if path.contains('/') || path.contains('\\') {
104
+ return false;
105
+ }
106
+ !suffixes.iter().any(|s| path.ends_with(s))
107
+ }
108
+
109
+ /// Plan the extension entries of several configs, in order.
110
+ ///
111
+ /// `None` means "do not intervene": no config names an extension by bare
112
+ /// package name, so the core's own config loading (and its error reporting)
113
+ /// handles every entry. Otherwise **every** config's entries are planned, each
114
+ /// against its own directory, concatenated in `configs` order — once the
115
+ /// caller suppresses the core's config-extension loading it must supply the
116
+ /// literal entries too.
117
+ ///
118
+ /// A config whose contents are absent or do not parse is skipped rather than
119
+ /// reported, leaving the error to the core.
120
+ pub fn plan_config_extensions(
121
+ configs: &[ConfigSource<'_>],
122
+ suffixes: &[&str],
123
+ ) -> Option<Vec<PlanEntry>> {
124
+ let loaded: Vec<(PathBuf, Vec<ExtensionSpec>)> = configs
125
+ .iter()
126
+ .filter_map(|source| {
127
+ let config = load_config_str(source.contents?).ok()?;
128
+ Some((source.path.parent()?.to_path_buf(), config.extensions))
129
+ })
130
+ .collect();
131
+
132
+ if !loaded
133
+ .iter()
134
+ .flat_map(|(_, extensions)| extensions)
135
+ .any(|extension| spec_is_bare_name(extension, suffixes))
136
+ {
137
+ return None;
138
+ }
139
+
140
+ Some(
141
+ loaded
142
+ .into_iter()
143
+ .flat_map(|(base, extensions)| {
144
+ extensions.into_iter().map(move |extension| {
145
+ let name = extension.path.to_string_lossy().into_owned();
146
+ if is_bare_name(&name, suffixes) {
147
+ PlanEntry::Package {
148
+ shadow: base.join(&name),
149
+ name,
150
+ entrypoint: extension.entrypoint,
151
+ }
152
+ } else {
153
+ // `join` already yields an absolute path verbatim.
154
+ PlanEntry::Literal {
155
+ path: base.join(&extension.path),
156
+ entrypoint: extension.entrypoint,
157
+ }
158
+ }
159
+ })
160
+ })
161
+ .collect(),
162
+ )
163
+ }
164
+
165
+ fn spec_is_bare_name(extension: &ExtensionSpec, suffixes: &[&str]) -> bool {
166
+ extension
167
+ .path
168
+ .to_str()
169
+ .is_some_and(|path| is_bare_name(path, suffixes))
170
+ }
171
+
172
+ /// Pick the single loadable file for package `name` out of a host's listing.
173
+ ///
174
+ /// `dirs` are the package's directories (used only for the not-found message);
175
+ /// `candidates` is every file found under them. Zero matches and more than one
176
+ /// are both errors — the user must disambiguate with a literal path.
177
+ pub fn select_loadable(
178
+ name: &str,
179
+ dirs: &[PathBuf],
180
+ candidates: &[PathBuf],
181
+ suffixes: &[&str],
182
+ ) -> Result<PathBuf, SelectError> {
183
+ let mut matches: Vec<PathBuf> = candidates
184
+ .iter()
185
+ .filter(|candidate| {
186
+ candidate
187
+ .to_str()
188
+ .is_some_and(|path| suffixes.iter().any(|suffix| path.ends_with(suffix)))
189
+ })
190
+ .cloned()
191
+ .collect();
192
+ matches.sort();
193
+ matches.dedup();
194
+
195
+ match matches.len() {
196
+ 0 => Err(SelectError::NotFound {
197
+ name: name.to_owned(),
198
+ suffixes: suffixes.iter().map(|s| (*s).to_owned()).collect(),
199
+ dirs: dirs.to_vec(),
200
+ }),
201
+ 1 => Ok(matches.remove(0)),
202
+ _ => Err(SelectError::Ambiguous {
203
+ name: name.to_owned(),
204
+ matches,
205
+ }),
206
+ }
207
+ }
208
+
209
+ #[cfg(test)]
210
+ mod tests {
211
+ use super::{
212
+ ConfigSource, PlanEntry, SelectError, is_bare_name, plan_config_extensions, select_loadable,
213
+ };
214
+ use std::path::{Path, PathBuf};
215
+
216
+ const PY: &[&str] = &[".so", ".dylib", ".dll", ".pyd"];
217
+ const NODE: &[&str] = &[".so", ".dylib", ".dll", ".node"];
218
+
219
+ fn source<'a>(path: &'a Path, contents: &'a str) -> ConfigSource<'a> {
220
+ ConfigSource {
221
+ path,
222
+ contents: Some(contents),
223
+ }
224
+ }
225
+
226
+ #[test]
227
+ fn a_value_with_no_separator_and_no_loadable_suffix_is_a_bare_name() {
228
+ assert!(is_bare_name("sqlite_vec", PY));
229
+ assert!(is_bare_name("vec0", NODE));
230
+ }
231
+
232
+ #[test]
233
+ fn a_value_carrying_either_separator_is_a_path() {
234
+ assert!(!is_bare_name("ext/vec0", PY));
235
+ assert!(!is_bare_name("ext\\vec0", PY));
236
+ assert!(!is_bare_name("/abs/vec0", PY));
237
+ }
238
+
239
+ #[test]
240
+ fn a_value_ending_in_a_loadable_suffix_is_a_path() {
241
+ for suffix in [".so", ".dylib", ".dll"] {
242
+ assert!(!is_bare_name(&format!("vec0{suffix}"), PY));
243
+ assert!(!is_bare_name(&format!("vec0{suffix}"), NODE));
244
+ }
245
+ }
246
+
247
+ #[test]
248
+ fn the_suffix_list_is_the_hosts_own() {
249
+ assert!(!is_bare_name("vec0.pyd", PY));
250
+ assert!(is_bare_name("vec0.pyd", NODE));
251
+ assert!(!is_bare_name("vec0.node", NODE));
252
+ assert!(is_bare_name("vec0.node", PY));
253
+ }
254
+
255
+ #[test]
256
+ fn configs_using_only_literal_paths_are_left_to_the_core() {
257
+ let path = Path::new("/project/.dirsql.toml");
258
+ let config = "[[dirsql.extension]]\npath = \"ext/vec0.so\"\n";
259
+ assert_eq!(plan_config_extensions(&[source(path, config)], PY), None);
260
+ }
261
+
262
+ #[test]
263
+ fn a_config_with_no_extension_array_is_left_to_the_core() {
264
+ let path = Path::new("/project/.dirsql.toml");
265
+ assert_eq!(
266
+ plan_config_extensions(&[source(path, "[dirsql]\nignore = [\"*.tmp\"]\n")], PY),
267
+ None
268
+ );
269
+ }
270
+
271
+ #[test]
272
+ fn an_absent_or_unparseable_config_is_skipped_rather_than_reported() {
273
+ let path = Path::new("/project/.dirsql.toml");
274
+ let missing = ConfigSource {
275
+ path,
276
+ contents: None,
277
+ };
278
+ assert_eq!(plan_config_extensions(&[missing], PY), None);
279
+ assert_eq!(
280
+ plan_config_extensions(&[source(path, "not valid = [")], PY),
281
+ None
282
+ );
283
+ }
284
+
285
+ #[test]
286
+ fn a_bare_name_plans_a_package_lookup_shadowed_by_the_configs_own_directory() {
287
+ let path = Path::new("/project/conf/.dirsql.toml");
288
+ let plan = plan_config_extensions(
289
+ &[source(
290
+ path,
291
+ "[[dirsql.extension]]\npath = \"sqlite_vec\"\n",
292
+ )],
293
+ PY,
294
+ )
295
+ .expect("a bare name makes the SDK intervene");
296
+
297
+ assert_eq!(
298
+ plan,
299
+ vec![PlanEntry::Package {
300
+ name: "sqlite_vec".into(),
301
+ shadow: PathBuf::from("/project/conf/sqlite_vec"),
302
+ entrypoint: None,
303
+ }]
304
+ );
305
+ }
306
+
307
+ #[test]
308
+ fn intervening_plans_the_literal_entries_too_and_keeps_config_order() {
309
+ let first = Path::new("/project/one/.dirsql.toml");
310
+ let second = Path::new("/project/two/.dirsql.toml");
311
+ let plan = plan_config_extensions(
312
+ &[
313
+ source(
314
+ first,
315
+ "[[dirsql.extension]]\npath = \"ext/vec0.so\"\nentrypoint = \"sqlite3_vec_init\"\n",
316
+ ),
317
+ source(second, "[[dirsql.extension]]\npath = \"sqlite_vec\"\n"),
318
+ ],
319
+ PY,
320
+ )
321
+ .expect("a bare name anywhere makes the SDK intervene for the whole set");
322
+
323
+ assert_eq!(
324
+ plan,
325
+ vec![
326
+ PlanEntry::Literal {
327
+ path: PathBuf::from("/project/one/ext/vec0.so"),
328
+ entrypoint: Some("sqlite3_vec_init".into()),
329
+ },
330
+ PlanEntry::Package {
331
+ name: "sqlite_vec".into(),
332
+ shadow: PathBuf::from("/project/two/sqlite_vec"),
333
+ entrypoint: None,
334
+ },
335
+ ]
336
+ );
337
+ }
338
+
339
+ #[test]
340
+ fn an_absolute_entry_path_is_left_alone() {
341
+ let path = Path::new("/project/.dirsql.toml");
342
+ let plan = plan_config_extensions(
343
+ &[source(
344
+ path,
345
+ "[[dirsql.extension]]\npath = \"/opt/vec0.so\"\n\n[[dirsql.extension]]\npath = \"sqlite_vec\"\n",
346
+ )],
347
+ PY,
348
+ )
349
+ .expect("intervening");
350
+
351
+ assert_eq!(
352
+ plan[0],
353
+ PlanEntry::Literal {
354
+ path: PathBuf::from("/opt/vec0.so"),
355
+ entrypoint: None,
356
+ }
357
+ );
358
+ }
359
+
360
+ #[test]
361
+ fn select_loadable_returns_the_single_matching_file() {
362
+ let dir = PathBuf::from("/site-packages/sqlite_vec");
363
+ let found = select_loadable(
364
+ "sqlite_vec",
365
+ std::slice::from_ref(&dir),
366
+ &[
367
+ dir.join("__init__.py"),
368
+ dir.join("vec0.so"),
369
+ dir.join("README.md"),
370
+ ],
371
+ PY,
372
+ );
373
+ assert_eq!(found, Ok(dir.join("vec0.so")));
374
+ }
375
+
376
+ #[test]
377
+ fn select_loadable_dedupes_and_sorts_before_counting() {
378
+ let dir = PathBuf::from("/pkg");
379
+ let found = select_loadable(
380
+ "vec",
381
+ std::slice::from_ref(&dir),
382
+ &[dir.join("vec0.so"), dir.join("vec0.so")],
383
+ PY,
384
+ );
385
+ assert_eq!(found, Ok(dir.join("vec0.so")));
386
+ }
387
+
388
+ #[test]
389
+ fn select_loadable_reports_every_searched_directory_when_nothing_matches() {
390
+ let dirs = vec![PathBuf::from("/a"), PathBuf::from("/b")];
391
+ let err = select_loadable("vec", &dirs, &[PathBuf::from("/a/vec.py")], PY)
392
+ .expect_err("no loadable file");
393
+ assert_eq!(
394
+ err.to_string(),
395
+ "no loadable extension file (*.so / *.dylib / *.dll / *.pyd) found in package 'vec' (searched /a, /b)"
396
+ );
397
+ }
398
+
399
+ #[test]
400
+ fn select_loadable_rejects_an_ambiguous_package_in_sorted_order() {
401
+ let dir = PathBuf::from("/pkg");
402
+ let err = select_loadable(
403
+ "vec",
404
+ std::slice::from_ref(&dir),
405
+ &[dir.join("z.so"), dir.join("a.so")],
406
+ PY,
407
+ )
408
+ .expect_err("two loadable files");
409
+ assert_eq!(
410
+ err,
411
+ SelectError::Ambiguous {
412
+ name: "vec".into(),
413
+ matches: vec![dir.join("a.so"), dir.join("z.so")],
414
+ }
415
+ );
416
+ assert_eq!(
417
+ err.to_string(),
418
+ "multiple loadable extension files found in package 'vec': /pkg/a.so, /pkg/z.so; disambiguate with a literal path"
419
+ );
420
+ }
421
+ }
@@ -16,6 +16,8 @@ pub mod db;
16
16
  #[doc(hidden)]
17
17
  pub mod differ;
18
18
  #[doc(hidden)]
19
+ pub mod extension_resolution;
20
+ #[doc(hidden)]
19
21
  pub mod functions;
20
22
  #[doc(hidden)]
21
23
  pub mod infer;
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