dirsql 0.4.7__tar.gz → 0.4.9__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 (227) hide show
  1. {dirsql-0.4.7 → dirsql-0.4.9}/Cargo.lock +1 -1
  2. {dirsql-0.4.7 → dirsql-0.4.9}/PKG-INFO +9 -1
  3. {dirsql-0.4.7/packages/python → dirsql-0.4.9}/README.md +8 -0
  4. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/_async.py +8 -0
  5. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/_dirsql.pyi +1 -0
  6. {dirsql-0.4.7 → dirsql-0.4.9}/docs/.vitepress/config.ts +7 -0
  7. dirsql-0.4.9/docs/plugins.md +123 -0
  8. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/Cargo.toml +1 -1
  9. {dirsql-0.4.7 → dirsql-0.4.9/packages/python}/README.md +8 -0
  10. dirsql-0.4.9/packages/python/changelog.d/2026-08-03-python-no-ignore.md +5 -0
  11. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/.vitepress/config.ts +7 -0
  12. dirsql-0.4.9/packages/python/docs/plugins.md +123 -0
  13. dirsql-0.4.9/packages/python/e2e-attestations/feat-745-python-no-ignore.json +7 -0
  14. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/src/lib.rs +3 -1
  15. dirsql-0.4.9/packages/rust/docs/plugins.md +123 -0
  16. dirsql-0.4.7/packages/python/e2e-attestations/claude-710-accumulate-onfile.json +0 -7
  17. dirsql-0.4.7/packages/python/e2e-attestations/claude-714-unify-file-failures.json +0 -7
  18. dirsql-0.4.7/packages/python/e2e-attestations/claude-715-binding-scan-failures.json +0 -7
  19. dirsql-0.4.7/packages/python/e2e-attestations/claude-716-drop-regex.json +0 -7
  20. dirsql-0.4.7/packages/python/e2e-attestations/feat-742-gitignore-by-default.json +0 -7
  21. {dirsql-0.4.7 → dirsql-0.4.9}/Cargo.toml +0 -0
  22. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/__init__.py +0 -0
  23. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/__init__.py +0 -0
  24. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/binary_path.py +0 -0
  25. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/__init__.py +0 -0
  26. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  27. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  28. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  29. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
  30. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
  31. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/is_windows.py +0 -0
  32. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/main.py +0 -0
  33. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/resolve_config_extensions.py +0 -0
  34. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/py.typed +0 -0
  35. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/resolve_config_extensions.py +0 -0
  36. {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/resolve_extension.py +0 -0
  37. {dirsql-0.4.7 → dirsql-0.4.9}/docs/.claude/CLAUDE.md +0 -0
  38. {dirsql-0.4.7 → dirsql-0.4.9}/docs/.vitepress/theme/index.ts +0 -0
  39. {dirsql-0.4.7 → dirsql-0.4.9}/docs/.vitepress/theme/lang.ts +0 -0
  40. {dirsql-0.4.7 → dirsql-0.4.9}/docs/AGENTS.md +0 -0
  41. {dirsql-0.4.7 → dirsql-0.4.9}/docs/explanation.md +0 -0
  42. {dirsql-0.4.7 → dirsql-0.4.9}/docs/getting-started.md +0 -0
  43. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/columns-from-paths.md +0 -0
  44. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/define-tables.md +0 -0
  45. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/embed.md +0 -0
  46. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/extract-from-contents.md +0 -0
  47. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/load-extension.md +0 -0
  48. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/parse-files-into-columns.md +0 -0
  49. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/persist.md +0 -0
  50. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/query-without-config.md +0 -0
  51. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/react-to-changes.md +0 -0
  52. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/search-by-meaning.md +0 -0
  53. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/skip-files.md +0 -0
  54. {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/write-a-plugin.md +0 -0
  55. {dirsql-0.4.7 → dirsql-0.4.9}/docs/index.md +0 -0
  56. {dirsql-0.4.7 → dirsql-0.4.9}/docs/migrations.md +0 -0
  57. {dirsql-0.4.7 → dirsql-0.4.9}/docs/package.json +0 -0
  58. {dirsql-0.4.7 → dirsql-0.4.9}/docs/pnpm-lock.yaml +0 -0
  59. {dirsql-0.4.7 → dirsql-0.4.9}/docs/pnpm-workspace.yaml +0 -0
  60. {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/cli.md +0 -0
  61. {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/columns.md +0 -0
  62. {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/config.md +0 -0
  63. {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/hooks.md +0 -0
  64. {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/http-api.md +0 -0
  65. {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/path-tables.md +0 -0
  66. {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/sdk.md +0 -0
  67. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/CHANGELOG.md +0 -0
  68. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/MIGRATIONS.md +0 -0
  69. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  70. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  71. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  72. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  73. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  74. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  75. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  76. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  77. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  78. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  79. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  80. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
  81. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/README.md +0 -0
  82. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/conftest.py +0 -0
  83. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/.claude/CLAUDE.md +0 -0
  84. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  85. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  86. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/AGENTS.md +0 -0
  87. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/explanation.md +0 -0
  88. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/getting-started.md +0 -0
  89. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/columns-from-paths.md +0 -0
  90. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/define-tables.md +0 -0
  91. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/embed.md +0 -0
  92. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/extract-from-contents.md +0 -0
  93. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/load-extension.md +0 -0
  94. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  95. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/persist.md +0 -0
  96. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/query-without-config.md +0 -0
  97. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/react-to-changes.md +0 -0
  98. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/search-by-meaning.md +0 -0
  99. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/skip-files.md +0 -0
  100. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/write-a-plugin.md +0 -0
  101. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/index.md +0 -0
  102. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/migrations.md +0 -0
  103. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/package.json +0 -0
  104. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/pnpm-lock.yaml +0 -0
  105. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/pnpm-workspace.yaml +0 -0
  106. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/cli.md +0 -0
  107. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/columns.md +0 -0
  108. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/config.md +0 -0
  109. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/hooks.md +0 -0
  110. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/http-api.md +0 -0
  111. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/path-tables.md +0 -0
  112. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/sdk.md +0 -0
  113. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  114. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  115. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  116. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  117. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  118. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  119. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  120. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  121. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/README.md +0 -0
  122. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/__init__.py +0 -0
  123. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/conftest.py +0 -0
  124. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/e2e/__init__.py +0 -0
  125. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  126. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  127. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/integration/__init__.py +0 -0
  128. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/integration/binding/__init__.py +0 -0
  129. {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  130. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/CHANGELOG.md +0 -0
  131. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/Cargo.toml +0 -0
  132. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/MIGRATIONS.md +0 -0
  133. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/README.md +0 -0
  134. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/benches/db_bench.rs +0 -0
  135. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/benches/differ_bench.rs +0 -0
  136. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/benches/matcher_bench.rs +0 -0
  137. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/benches/scanner_bench.rs +0 -0
  138. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-batch-ingest-transaction.md +0 -0
  139. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-chained-pre-post-query-hooks.md +0 -0
  140. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  141. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-fan-out-file-table-matching.md +0 -0
  142. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-persist-wal.md +0 -0
  143. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  144. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-repeatable-builder-config.md +0 -0
  145. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-repeatable-cli-config.md +0 -0
  146. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  147. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-subcommand-local-config-flags.md +0 -0
  148. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-19-path-table-query-fallback.md +0 -0
  149. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-19-path-table-vtab.md +0 -0
  150. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  151. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-20-path-table-glob-semantics.md +0 -0
  152. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-20-schema-inference.md +0 -0
  153. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-21-on-file-flag.md +0 -0
  154. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  155. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-23-init-escalation-example.md +0 -0
  156. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-23-query-default-cli.md +0 -0
  157. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  158. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  159. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-29-on-file-failures-accumulate.md +0 -0
  160. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-08-02-drop-regex.md +0 -0
  161. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-08-02-per-file-scan-failures.md +0 -0
  162. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-08-02-release-profile.md +0 -0
  163. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-08-03-gitignore-by-default.md +0 -0
  164. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-08-03-nested-default-ignores.md +0 -0
  165. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/README.md +0 -0
  166. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/explanation.md +0 -0
  167. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/getting-started.md +0 -0
  168. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  169. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/define-tables.md +0 -0
  170. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/embed.md +0 -0
  171. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  172. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/load-extension.md +0 -0
  173. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  174. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/persist.md +0 -0
  175. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/query-without-config.md +0 -0
  176. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/react-to-changes.md +0 -0
  177. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  178. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/skip-files.md +0 -0
  179. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  180. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/index.md +0 -0
  181. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/migrations.md +0 -0
  182. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/cli.md +0 -0
  183. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/columns.md +0 -0
  184. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/config.md +0 -0
  185. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/hooks.md +0 -0
  186. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/http-api.md +0 -0
  187. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/path-tables.md +0 -0
  188. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/sdk.md +0 -0
  189. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  190. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-fan-out-file-table-matching.md +0 -0
  191. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-persist-wal.md +0 -0
  192. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  193. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  194. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-subcommand-local-config-flags.md +0 -0
  195. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  196. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-20-path-table-glob-semantics.md +0 -0
  197. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  198. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-23-init-escalation-example.md +0 -0
  199. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-23-query-default-cli.md +0 -0
  200. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  201. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  202. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-08-02-per-file-scan-failures.md +0 -0
  203. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-08-03-gitignore-by-default.md +0 -0
  204. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-08-03-nested-default-ignores.md +0 -0
  205. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/README.md +0 -0
  206. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/bin/dirsql.rs +0 -0
  207. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/execute.rs +0 -0
  208. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/init.rs +0 -0
  209. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/mod.rs +0 -0
  210. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/router.rs +0 -0
  211. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/serialize.rs +0 -0
  212. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/server.rs +0 -0
  213. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/command.rs +0 -0
  214. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/config.rs +0 -0
  215. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/db.rs +0 -0
  216. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/default_config.toml +0 -0
  217. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/differ.rs +0 -0
  218. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/infer.rs +0 -0
  219. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/lib.rs +0 -0
  220. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/matcher.rs +0 -0
  221. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/parsed_vtab.rs +0 -0
  222. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/path_table.rs +0 -0
  223. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/persist.rs +0 -0
  224. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/scanner.rs +0 -0
  225. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/vtab.rs +0 -0
  226. {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/watcher.rs +0 -0
  227. {dirsql-0.4.7 → dirsql-0.4.9}/pyproject.toml +0 -0
@@ -500,7 +500,7 @@ dependencies = [
500
500
 
501
501
  [[package]]
502
502
  name = "dirsql-py-ext"
503
- version = "0.4.7"
503
+ version = "0.4.9"
504
504
  dependencies = [
505
505
  "dirsql",
506
506
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.4.7
3
+ Version: 0.4.9
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
@@ -91,6 +91,14 @@ db = DirSQL(
91
91
  )
92
92
  ```
93
93
 
94
+ Path-table scans (`SELECT ... FROM './'`) respect `.gitignore` files by
95
+ default. Pass `no_ignore=True` to restore the full walk; the built-in
96
+ `node_modules`/`.git` defaults and any `ignore` patterns still apply:
97
+
98
+ ```python
99
+ db = DirSQL("./my-blog", no_ignore=True)
100
+ ```
101
+
94
102
  ## Loading SQLite extensions
95
103
 
96
104
  Pass `extensions` to load SQLite extension shared libraries onto the connection at startup (before any `CREATE TABLE`). Each entry is a dict with a `path` and an optional `entrypoint` init-symbol override:
@@ -80,6 +80,14 @@ db = DirSQL(
80
80
  )
81
81
  ```
82
82
 
83
+ Path-table scans (`SELECT ... FROM './'`) respect `.gitignore` files by
84
+ default. Pass `no_ignore=True` to restore the full walk; the built-in
85
+ `node_modules`/`.git` defaults and any `ignore` patterns still apply:
86
+
87
+ ```python
88
+ db = DirSQL("./my-blog", no_ignore=True)
89
+ ```
90
+
83
91
  ## Loading SQLite extensions
84
92
 
85
93
  Pass `extensions` to load SQLite extension shared libraries onto the connection at startup (before any `CREATE TABLE`). Each entry is a dict with a `path` and an optional `entrypoint` init-symbol override:
@@ -59,6 +59,11 @@ class DirSQL:
59
59
  is no ``[dirsql].root`` config key. Constructing with neither ``root``
60
60
  nor ``config`` roots at the cwd (no error is raised).
61
61
 
62
+ Path-table scans (``SELECT ... FROM './'``) respect ``.gitignore`` files
63
+ by default. Pass ``no_ignore=True`` to restore the full walk; the built-in
64
+ ``node_modules``/``.git`` defaults and any ``ignore`` patterns still
65
+ apply.
66
+
62
67
  Pass ``persist=True`` to keep an on-disk SQLite cache (default location:
63
68
  ``<root>/.dirsql/cache.db``). Override the location with ``persist_path``.
64
69
 
@@ -76,6 +81,7 @@ class DirSQL:
76
81
  *,
77
82
  tables=None,
78
83
  ignore=None,
84
+ no_ignore=False,
79
85
  config=None,
80
86
  persist=False,
81
87
  persist_path=None,
@@ -84,6 +90,7 @@ class DirSQL:
84
90
  self._root = root
85
91
  self._tables = tables
86
92
  self._ignore = ignore
93
+ self._no_ignore = no_ignore
87
94
  self._config = config
88
95
  # A single path or a list of paths; the list merges in order (each
89
96
  # config's [[table]] / ignore / [[dirsql.extension]] accumulate).
@@ -134,6 +141,7 @@ class DirSQL:
134
141
  self._root,
135
142
  tables=self._tables,
136
143
  ignore=self._ignore,
144
+ no_ignore=self._no_ignore,
137
145
  config=self._config_paths or None,
138
146
  persist=self._persist,
139
147
  persist_path=self._persist_path,
@@ -65,6 +65,7 @@ class DirSQL:
65
65
  *,
66
66
  tables: list[Table] | None = None,
67
67
  ignore: list[str] | None = None,
68
+ no_ignore: bool = False,
68
69
  config: list[str] | None = None,
69
70
  persist: bool = False,
70
71
  persist_path: str | PathLike[str] | None = None,
@@ -29,6 +29,7 @@ export default defineConfig({
29
29
  { text: 'How-to Guides', link: '/howto/define-tables' },
30
30
  { text: 'Reference', link: '/reference/cli' },
31
31
  { text: 'Explanation', link: '/explanation' },
32
+ { text: 'Plugins', link: '/plugins' },
32
33
  { text: 'GitHub', link: 'https://github.com/thekevinscott/dirsql' }
33
34
  ],
34
35
 
@@ -80,6 +81,12 @@ export default defineConfig({
80
81
  items: [
81
82
  { text: 'How dirsql thinks', link: '/explanation' }
82
83
  ]
84
+ },
85
+ {
86
+ text: 'Plugins',
87
+ items: [
88
+ { text: 'Available plugins', link: '/plugins' }
89
+ ]
83
90
  }
84
91
  ]
85
92
  },
@@ -0,0 +1,123 @@
1
+ # Plugins
2
+
3
+ A **plugin** is an ordinary Python package that ships a `dirsql.toml` config
4
+ fragment and declares itself via a `dirsql` entry point. Installing it in the
5
+ same environment as `dirsql` activates it: the `pip`/`uvx` launcher discovers
6
+ the package and loads its fragment automatically, with zero config edits. The
7
+ full discovery contract (ordering, opt-out, failure modes) is in the
8
+ [CLI reference](./reference/cli.md#plugins); to build your own, see
9
+ [Write a plugin](./howto/write-a-plugin.md).
10
+
11
+ This page lists the first-party plugins.
12
+
13
+ ## `dirsql-plugin-embeddings`
14
+
15
+ Semantic search over a directory of documents. The plugin embeds every matched
16
+ file — `**/*.{md,markdown,mdx,rst,txt,pdf}` — into a `documents` table through
17
+ any OpenAI-compatible `/v1/embeddings` endpoint, then turns each incoming
18
+ question into nearest-neighbor SQL over that table, ranked by
19
+ [`sqlite-vec`](https://github.com/asg017/sqlite-vec)'s
20
+ `vec_distance_cosine()`.
21
+
22
+ [PyPI](https://pypi.org/project/dirsql-plugin-embeddings/) ·
23
+ [Source](https://github.com/thekevinscott/dirsql/tree/main/plugins/dirsql-plugin-embeddings)
24
+
25
+ It is the packaged form of the
26
+ [Search documents by meaning](./howto/search-by-meaning.md) how-to, with that
27
+ guide's local `model2vec` model swapped for a hosted endpoint.
28
+
29
+ ### Install and launch
30
+
31
+ The plugin is a normal PyPI package; installing it alongside `dirsql` is the
32
+ whole install story (installed = active — there is no enable step). Point the
33
+ three environment variables at any OpenAI-compatible inference server, hosted
34
+ or self-managed:
35
+
36
+ ```sh
37
+ export DIRSQL_EMBEDDINGS_BASE_URL="https://api.openai.com"
38
+ export DIRSQL_EMBEDDINGS_MODEL="text-embedding-3-small"
39
+ export DIRSQL_EMBEDDINGS_API_KEY="sk-…"
40
+
41
+ uvx --with dirsql-plugin-embeddings --with sqlite-vec dirsql server
42
+ ```
43
+
44
+ The launcher finds the package through its `dirsql` entry point and injects
45
+ the shipped `dirsql.toml` fragment as an ordinary `-c` flag, composed after
46
+ your own configs. The fragment declares three things:
47
+
48
+ - the `sqlite-vec` extension (resolved from the installed `sqlite-vec`
49
+ package — hence the second `--with`), for `vec_distance_cosine()`;
50
+ - the `documents` table (`path`, `text`, `embedding`), whose
51
+ [`on-file`](./reference/hooks.md#on-file) hook embeds each matched file at
52
+ index time;
53
+ - a [`pre-query`](./reference/hooks.md#pre-query) hook that embeds each
54
+ incoming question and emits the nearest-neighbor SQL, plus a 300-second
55
+ [`hook-timeout`](./reference/config.md#dirsql-keys) so slow embedding calls
56
+ don't hit the 30-second default.
57
+
58
+ Ask a question as a `{"q": …}` body — via `POST /query` against the server,
59
+ or in one shot from the shell:
60
+
61
+ ```sh
62
+ uvx --with dirsql-plugin-embeddings --with sqlite-vec \
63
+ dirsql query '{"q": "how do I cook spaghetti?"}'
64
+ # [{"path":"pasta.md","distance":0.113}, …]
65
+ ```
66
+
67
+ The result is the three nearest documents, closest first. Discovery can be
68
+ turned off per-invocation with `--no-plugin` or `DIRSQL_NO_PLUGIN=1`
69
+ ([reference](./reference/cli.md#plugins)).
70
+
71
+ ### Configuration
72
+
73
+ The v0.1 configuration surface is environment variables. The hooks run as
74
+ subprocesses, so the variables must be set in the environment `dirsql` itself
75
+ runs in — they are inherited, not read from a file.
76
+
77
+ | Variable | Required | Meaning |
78
+ |---|---|---|
79
+ | `DIRSQL_EMBEDDINGS_BASE_URL` | yes | Base URL of the embeddings server; `/v1/embeddings` is appended. |
80
+ | `DIRSQL_EMBEDDINGS_MODEL` | yes | Model name sent in each request. |
81
+ | `DIRSQL_EMBEDDINGS_API_KEY` | yes | Bearer token for the `Authorization` header. |
82
+ | `DIRSQL_EMBEDDINGS_CACHE_READ` | no | Set to `0` to bypass reads of the on-disk PDF text-extraction cache (see below). Anything else, or unset, leaves the cache on. |
83
+
84
+ PDF text extraction is the expensive step of a scan, and a scan re-reads every
85
+ matched file — so extracted text is cached on disk at
86
+ `~/.cache/dirsql-plugin-embeddings/`, keyed on the file's path and mtime. An
87
+ edited PDF is a cache miss, never a stale hit. `DIRSQL_EMBEDDINGS_CACHE_READ=0`
88
+ forces every call to re-extract; writes still happen, so the cache stays warm
89
+ for the next run that reads it.
90
+
91
+ ### What gets indexed
92
+
93
+ Every file matching `**/*.{md,markdown,mdx,rst,txt,pdf}` under the root.
94
+ Everything except `.pdf` is read as UTF-8 text; a `.pdf` is read with
95
+ [pypdf](https://pypdf.readthedocs.io), its per-page text joined and embedded
96
+ like any other document. The extension check is case-insensitive (`.PDF` is a
97
+ PDF), but the glob itself is not — an uppercase-suffixed file is not matched
98
+ at all.
99
+
100
+ The glob is an allowlist rather than `**/*` on cost, not correctness: every
101
+ matched file costs a hook subprocess, and every file the plugin can decode
102
+ costs a billed embedding call. Widening the list trades money for recall.
103
+
104
+ A *scanned*, image-only PDF is not an error: pypdf yields no text and the file
105
+ is indexed with an empty `text`, exactly like an empty `.md`.
106
+
107
+ ### When a file fails
108
+
109
+ A file the plugin cannot process — an unreadable file, a failed embedding
110
+ call — is skipped, not fatal. Per the
111
+ [`on-file` failure contract](./reference/hooks.md#failure-semantics), the file
112
+ contributes no rows, `dirsql` names it on stderr and keeps indexing the rest,
113
+ and the run exits `23`: a partial index, distinct from `0` (clean) and `1`
114
+ (the run failed). From the SDK the same information is available via
115
+ `scan_failures()` / `scanFailures()`.
116
+
117
+ ### Planned configurability
118
+
119
+ v0.1 is deliberately minimal: one provider shape, one table, one file = one
120
+ row = one embedding (no chunking), and a hardcoded glob. Configurability —
121
+ alternate embedding backends, chunking strategies, choosing which files get
122
+ indexed, cache knobs — is tracked in
123
+ [#619](https://github.com/thekevinscott/dirsql/issues/619).
@@ -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.7"
7
+ version = "0.4.9"
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
@@ -80,6 +80,14 @@ db = DirSQL(
80
80
  )
81
81
  ```
82
82
 
83
+ Path-table scans (`SELECT ... FROM './'`) respect `.gitignore` files by
84
+ default. Pass `no_ignore=True` to restore the full walk; the built-in
85
+ `node_modules`/`.git` defaults and any `ignore` patterns still apply:
86
+
87
+ ```python
88
+ db = DirSQL("./my-blog", no_ignore=True)
89
+ ```
90
+
83
91
  ## Loading SQLite extensions
84
92
 
85
93
  Pass `extensions` to load SQLite extension shared libraries onto the connection at startup (before any `CREATE TABLE`). Each entry is a dict with a `path` and an optional `entrypoint` init-symbol override:
@@ -0,0 +1,5 @@
1
+ **Added** `DirSQL(..., no_ignore=True)`: a constructor opt-out from the
2
+ gitignore-by-default behavior path-table scans gained in #742, matching the
3
+ CLI's `--no-ignore` and the Rust builder's `DirSQLBuilder::no_ignore(bool)`.
4
+ The built-in `node_modules`/`.git` floor and configured `ignore` patterns
5
+ still apply. (#745)
@@ -29,6 +29,7 @@ export default defineConfig({
29
29
  { text: 'How-to Guides', link: '/howto/define-tables' },
30
30
  { text: 'Reference', link: '/reference/cli' },
31
31
  { text: 'Explanation', link: '/explanation' },
32
+ { text: 'Plugins', link: '/plugins' },
32
33
  { text: 'GitHub', link: 'https://github.com/thekevinscott/dirsql' }
33
34
  ],
34
35
 
@@ -80,6 +81,12 @@ export default defineConfig({
80
81
  items: [
81
82
  { text: 'How dirsql thinks', link: '/explanation' }
82
83
  ]
84
+ },
85
+ {
86
+ text: 'Plugins',
87
+ items: [
88
+ { text: 'Available plugins', link: '/plugins' }
89
+ ]
83
90
  }
84
91
  ]
85
92
  },
@@ -0,0 +1,123 @@
1
+ # Plugins
2
+
3
+ A **plugin** is an ordinary Python package that ships a `dirsql.toml` config
4
+ fragment and declares itself via a `dirsql` entry point. Installing it in the
5
+ same environment as `dirsql` activates it: the `pip`/`uvx` launcher discovers
6
+ the package and loads its fragment automatically, with zero config edits. The
7
+ full discovery contract (ordering, opt-out, failure modes) is in the
8
+ [CLI reference](./reference/cli.md#plugins); to build your own, see
9
+ [Write a plugin](./howto/write-a-plugin.md).
10
+
11
+ This page lists the first-party plugins.
12
+
13
+ ## `dirsql-plugin-embeddings`
14
+
15
+ Semantic search over a directory of documents. The plugin embeds every matched
16
+ file — `**/*.{md,markdown,mdx,rst,txt,pdf}` — into a `documents` table through
17
+ any OpenAI-compatible `/v1/embeddings` endpoint, then turns each incoming
18
+ question into nearest-neighbor SQL over that table, ranked by
19
+ [`sqlite-vec`](https://github.com/asg017/sqlite-vec)'s
20
+ `vec_distance_cosine()`.
21
+
22
+ [PyPI](https://pypi.org/project/dirsql-plugin-embeddings/) ·
23
+ [Source](https://github.com/thekevinscott/dirsql/tree/main/plugins/dirsql-plugin-embeddings)
24
+
25
+ It is the packaged form of the
26
+ [Search documents by meaning](./howto/search-by-meaning.md) how-to, with that
27
+ guide's local `model2vec` model swapped for a hosted endpoint.
28
+
29
+ ### Install and launch
30
+
31
+ The plugin is a normal PyPI package; installing it alongside `dirsql` is the
32
+ whole install story (installed = active — there is no enable step). Point the
33
+ three environment variables at any OpenAI-compatible inference server, hosted
34
+ or self-managed:
35
+
36
+ ```sh
37
+ export DIRSQL_EMBEDDINGS_BASE_URL="https://api.openai.com"
38
+ export DIRSQL_EMBEDDINGS_MODEL="text-embedding-3-small"
39
+ export DIRSQL_EMBEDDINGS_API_KEY="sk-…"
40
+
41
+ uvx --with dirsql-plugin-embeddings --with sqlite-vec dirsql server
42
+ ```
43
+
44
+ The launcher finds the package through its `dirsql` entry point and injects
45
+ the shipped `dirsql.toml` fragment as an ordinary `-c` flag, composed after
46
+ your own configs. The fragment declares three things:
47
+
48
+ - the `sqlite-vec` extension (resolved from the installed `sqlite-vec`
49
+ package — hence the second `--with`), for `vec_distance_cosine()`;
50
+ - the `documents` table (`path`, `text`, `embedding`), whose
51
+ [`on-file`](./reference/hooks.md#on-file) hook embeds each matched file at
52
+ index time;
53
+ - a [`pre-query`](./reference/hooks.md#pre-query) hook that embeds each
54
+ incoming question and emits the nearest-neighbor SQL, plus a 300-second
55
+ [`hook-timeout`](./reference/config.md#dirsql-keys) so slow embedding calls
56
+ don't hit the 30-second default.
57
+
58
+ Ask a question as a `{"q": …}` body — via `POST /query` against the server,
59
+ or in one shot from the shell:
60
+
61
+ ```sh
62
+ uvx --with dirsql-plugin-embeddings --with sqlite-vec \
63
+ dirsql query '{"q": "how do I cook spaghetti?"}'
64
+ # [{"path":"pasta.md","distance":0.113}, …]
65
+ ```
66
+
67
+ The result is the three nearest documents, closest first. Discovery can be
68
+ turned off per-invocation with `--no-plugin` or `DIRSQL_NO_PLUGIN=1`
69
+ ([reference](./reference/cli.md#plugins)).
70
+
71
+ ### Configuration
72
+
73
+ The v0.1 configuration surface is environment variables. The hooks run as
74
+ subprocesses, so the variables must be set in the environment `dirsql` itself
75
+ runs in — they are inherited, not read from a file.
76
+
77
+ | Variable | Required | Meaning |
78
+ |---|---|---|
79
+ | `DIRSQL_EMBEDDINGS_BASE_URL` | yes | Base URL of the embeddings server; `/v1/embeddings` is appended. |
80
+ | `DIRSQL_EMBEDDINGS_MODEL` | yes | Model name sent in each request. |
81
+ | `DIRSQL_EMBEDDINGS_API_KEY` | yes | Bearer token for the `Authorization` header. |
82
+ | `DIRSQL_EMBEDDINGS_CACHE_READ` | no | Set to `0` to bypass reads of the on-disk PDF text-extraction cache (see below). Anything else, or unset, leaves the cache on. |
83
+
84
+ PDF text extraction is the expensive step of a scan, and a scan re-reads every
85
+ matched file — so extracted text is cached on disk at
86
+ `~/.cache/dirsql-plugin-embeddings/`, keyed on the file's path and mtime. An
87
+ edited PDF is a cache miss, never a stale hit. `DIRSQL_EMBEDDINGS_CACHE_READ=0`
88
+ forces every call to re-extract; writes still happen, so the cache stays warm
89
+ for the next run that reads it.
90
+
91
+ ### What gets indexed
92
+
93
+ Every file matching `**/*.{md,markdown,mdx,rst,txt,pdf}` under the root.
94
+ Everything except `.pdf` is read as UTF-8 text; a `.pdf` is read with
95
+ [pypdf](https://pypdf.readthedocs.io), its per-page text joined and embedded
96
+ like any other document. The extension check is case-insensitive (`.PDF` is a
97
+ PDF), but the glob itself is not — an uppercase-suffixed file is not matched
98
+ at all.
99
+
100
+ The glob is an allowlist rather than `**/*` on cost, not correctness: every
101
+ matched file costs a hook subprocess, and every file the plugin can decode
102
+ costs a billed embedding call. Widening the list trades money for recall.
103
+
104
+ A *scanned*, image-only PDF is not an error: pypdf yields no text and the file
105
+ is indexed with an empty `text`, exactly like an empty `.md`.
106
+
107
+ ### When a file fails
108
+
109
+ A file the plugin cannot process — an unreadable file, a failed embedding
110
+ call — is skipped, not fatal. Per the
111
+ [`on-file` failure contract](./reference/hooks.md#failure-semantics), the file
112
+ contributes no rows, `dirsql` names it on stderr and keeps indexing the rest,
113
+ and the run exits `23`: a partial index, distinct from `0` (clean) and `1`
114
+ (the run failed). From the SDK the same information is available via
115
+ `scan_failures()` / `scanFailures()`.
116
+
117
+ ### Planned configurability
118
+
119
+ v0.1 is deliberately minimal: one provider shape, one table, one file = one
120
+ row = one embedding (no chunking), and a hardcoded glob. Configurability —
121
+ alternate embedding backends, chunking strategies, choosing which files get
122
+ indexed, cache knobs — is tracked in
123
+ [#619](https://github.com/thekevinscott/dirsql/issues/619).
@@ -0,0 +1,7 @@
1
+ {
2
+ "command": "just test-e2e",
3
+ "ran_at": 1785777931,
4
+ "exit_code": 0,
5
+ "commit": "ef9db367f3a4979a0006e7bd40b0808f433b26ee",
6
+ "branch": "feat/745-python-no-ignore"
7
+ }
@@ -137,12 +137,13 @@ mod python {
137
137
  /// which the core lacks) and passing the resolved literal paths via
138
138
  /// `extensions`, so the entries are not loaded twice.
139
139
  #[new]
140
- #[pyo3(signature = (root=None, *, tables=None, ignore=None, config=None, persist=false, persist_path=None, extensions=None, suppress_config_extensions=false))]
140
+ #[pyo3(signature = (root=None, *, tables=None, ignore=None, no_ignore=false, config=None, persist=false, persist_path=None, extensions=None, suppress_config_extensions=false))]
141
141
  fn new(
142
142
  py: Python<'_>,
143
143
  root: Option<String>,
144
144
  tables: Option<Vec<PyRef<'_, PyTable>>>,
145
145
  ignore: Option<Vec<String>>,
146
+ no_ignore: bool,
146
147
  config: Option<Vec<String>>,
147
148
  persist: bool,
148
149
  persist_path: Option<PathBuf>,
@@ -175,6 +176,7 @@ mod python {
175
176
  if let Some(ig) = ignore {
176
177
  builder = builder.ignore(ig);
177
178
  }
179
+ builder = builder.no_ignore(no_ignore);
178
180
  for c in config.into_iter().flatten() {
179
181
  builder = builder.config(c);
180
182
  }
@@ -0,0 +1,123 @@
1
+ # Plugins
2
+
3
+ A **plugin** is an ordinary Python package that ships a `dirsql.toml` config
4
+ fragment and declares itself via a `dirsql` entry point. Installing it in the
5
+ same environment as `dirsql` activates it: the `pip`/`uvx` launcher discovers
6
+ the package and loads its fragment automatically, with zero config edits. The
7
+ full discovery contract (ordering, opt-out, failure modes) is in the
8
+ [CLI reference](./reference/cli.md#plugins); to build your own, see
9
+ [Write a plugin](./howto/write-a-plugin.md).
10
+
11
+ This page lists the first-party plugins.
12
+
13
+ ## `dirsql-plugin-embeddings`
14
+
15
+ Semantic search over a directory of documents. The plugin embeds every matched
16
+ file — `**/*.{md,markdown,mdx,rst,txt,pdf}` — into a `documents` table through
17
+ any OpenAI-compatible `/v1/embeddings` endpoint, then turns each incoming
18
+ question into nearest-neighbor SQL over that table, ranked by
19
+ [`sqlite-vec`](https://github.com/asg017/sqlite-vec)'s
20
+ `vec_distance_cosine()`.
21
+
22
+ [PyPI](https://pypi.org/project/dirsql-plugin-embeddings/) ·
23
+ [Source](https://github.com/thekevinscott/dirsql/tree/main/plugins/dirsql-plugin-embeddings)
24
+
25
+ It is the packaged form of the
26
+ [Search documents by meaning](./howto/search-by-meaning.md) how-to, with that
27
+ guide's local `model2vec` model swapped for a hosted endpoint.
28
+
29
+ ### Install and launch
30
+
31
+ The plugin is a normal PyPI package; installing it alongside `dirsql` is the
32
+ whole install story (installed = active — there is no enable step). Point the
33
+ three environment variables at any OpenAI-compatible inference server, hosted
34
+ or self-managed:
35
+
36
+ ```sh
37
+ export DIRSQL_EMBEDDINGS_BASE_URL="https://api.openai.com"
38
+ export DIRSQL_EMBEDDINGS_MODEL="text-embedding-3-small"
39
+ export DIRSQL_EMBEDDINGS_API_KEY="sk-…"
40
+
41
+ uvx --with dirsql-plugin-embeddings --with sqlite-vec dirsql server
42
+ ```
43
+
44
+ The launcher finds the package through its `dirsql` entry point and injects
45
+ the shipped `dirsql.toml` fragment as an ordinary `-c` flag, composed after
46
+ your own configs. The fragment declares three things:
47
+
48
+ - the `sqlite-vec` extension (resolved from the installed `sqlite-vec`
49
+ package — hence the second `--with`), for `vec_distance_cosine()`;
50
+ - the `documents` table (`path`, `text`, `embedding`), whose
51
+ [`on-file`](./reference/hooks.md#on-file) hook embeds each matched file at
52
+ index time;
53
+ - a [`pre-query`](./reference/hooks.md#pre-query) hook that embeds each
54
+ incoming question and emits the nearest-neighbor SQL, plus a 300-second
55
+ [`hook-timeout`](./reference/config.md#dirsql-keys) so slow embedding calls
56
+ don't hit the 30-second default.
57
+
58
+ Ask a question as a `{"q": …}` body — via `POST /query` against the server,
59
+ or in one shot from the shell:
60
+
61
+ ```sh
62
+ uvx --with dirsql-plugin-embeddings --with sqlite-vec \
63
+ dirsql query '{"q": "how do I cook spaghetti?"}'
64
+ # [{"path":"pasta.md","distance":0.113}, …]
65
+ ```
66
+
67
+ The result is the three nearest documents, closest first. Discovery can be
68
+ turned off per-invocation with `--no-plugin` or `DIRSQL_NO_PLUGIN=1`
69
+ ([reference](./reference/cli.md#plugins)).
70
+
71
+ ### Configuration
72
+
73
+ The v0.1 configuration surface is environment variables. The hooks run as
74
+ subprocesses, so the variables must be set in the environment `dirsql` itself
75
+ runs in — they are inherited, not read from a file.
76
+
77
+ | Variable | Required | Meaning |
78
+ |---|---|---|
79
+ | `DIRSQL_EMBEDDINGS_BASE_URL` | yes | Base URL of the embeddings server; `/v1/embeddings` is appended. |
80
+ | `DIRSQL_EMBEDDINGS_MODEL` | yes | Model name sent in each request. |
81
+ | `DIRSQL_EMBEDDINGS_API_KEY` | yes | Bearer token for the `Authorization` header. |
82
+ | `DIRSQL_EMBEDDINGS_CACHE_READ` | no | Set to `0` to bypass reads of the on-disk PDF text-extraction cache (see below). Anything else, or unset, leaves the cache on. |
83
+
84
+ PDF text extraction is the expensive step of a scan, and a scan re-reads every
85
+ matched file — so extracted text is cached on disk at
86
+ `~/.cache/dirsql-plugin-embeddings/`, keyed on the file's path and mtime. An
87
+ edited PDF is a cache miss, never a stale hit. `DIRSQL_EMBEDDINGS_CACHE_READ=0`
88
+ forces every call to re-extract; writes still happen, so the cache stays warm
89
+ for the next run that reads it.
90
+
91
+ ### What gets indexed
92
+
93
+ Every file matching `**/*.{md,markdown,mdx,rst,txt,pdf}` under the root.
94
+ Everything except `.pdf` is read as UTF-8 text; a `.pdf` is read with
95
+ [pypdf](https://pypdf.readthedocs.io), its per-page text joined and embedded
96
+ like any other document. The extension check is case-insensitive (`.PDF` is a
97
+ PDF), but the glob itself is not — an uppercase-suffixed file is not matched
98
+ at all.
99
+
100
+ The glob is an allowlist rather than `**/*` on cost, not correctness: every
101
+ matched file costs a hook subprocess, and every file the plugin can decode
102
+ costs a billed embedding call. Widening the list trades money for recall.
103
+
104
+ A *scanned*, image-only PDF is not an error: pypdf yields no text and the file
105
+ is indexed with an empty `text`, exactly like an empty `.md`.
106
+
107
+ ### When a file fails
108
+
109
+ A file the plugin cannot process — an unreadable file, a failed embedding
110
+ call — is skipped, not fatal. Per the
111
+ [`on-file` failure contract](./reference/hooks.md#failure-semantics), the file
112
+ contributes no rows, `dirsql` names it on stderr and keeps indexing the rest,
113
+ and the run exits `23`: a partial index, distinct from `0` (clean) and `1`
114
+ (the run failed). From the SDK the same information is available via
115
+ `scan_failures()` / `scanFailures()`.
116
+
117
+ ### Planned configurability
118
+
119
+ v0.1 is deliberately minimal: one provider shape, one table, one file = one
120
+ row = one embedding (no chunking), and a hardcoded glob. Configurability —
121
+ alternate embedding backends, chunking strategies, choosing which files get
122
+ indexed, cache knobs — is tracked in
123
+ [#619](https://github.com/thekevinscott/dirsql/issues/619).
@@ -1,7 +0,0 @@
1
- {
2
- "command": "uv run python -m pytest tests/e2e/ -x -q",
3
- "ran_at": 1785444370,
4
- "exit_code": 0,
5
- "commit": "287fb980b2380a894543a652a0439f6ab8ea71cf",
6
- "branch": "claude/710-accumulate-onfile"
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "command": "uv run python -m pytest tests/e2e/ -x -q",
3
- "ran_at": 1785673957,
4
- "exit_code": 0,
5
- "commit": "484c89828d5a512f7fd51dc8e5995d498e857c0b",
6
- "branch": "claude/714-unify-file-failures"
7
- }
@@ -1,7 +0,0 @@
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
- }
@@ -1,7 +0,0 @@
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
- }
@@ -1,7 +0,0 @@
1
- {
2
- "command": "just test-e2e",
3
- "ran_at": 1785774560,
4
- "exit_code": 0,
5
- "commit": "3559de42c86374f67ceeb7266a6867193234cec1",
6
- "branch": "feat/742-gitignore-by-default"
7
- }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes