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.
- {dirsql-0.4.7 → dirsql-0.4.9}/Cargo.lock +1 -1
- {dirsql-0.4.7 → dirsql-0.4.9}/PKG-INFO +9 -1
- {dirsql-0.4.7/packages/python → dirsql-0.4.9}/README.md +8 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/_async.py +8 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/_dirsql.pyi +1 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/.vitepress/config.ts +7 -0
- dirsql-0.4.9/docs/plugins.md +123 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/Cargo.toml +1 -1
- {dirsql-0.4.7 → dirsql-0.4.9/packages/python}/README.md +8 -0
- dirsql-0.4.9/packages/python/changelog.d/2026-08-03-python-no-ignore.md +5 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/.vitepress/config.ts +7 -0
- dirsql-0.4.9/packages/python/docs/plugins.md +123 -0
- dirsql-0.4.9/packages/python/e2e-attestations/feat-745-python-no-ignore.json +7 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/src/lib.rs +3 -1
- dirsql-0.4.9/packages/rust/docs/plugins.md +123 -0
- dirsql-0.4.7/packages/python/e2e-attestations/claude-710-accumulate-onfile.json +0 -7
- dirsql-0.4.7/packages/python/e2e-attestations/claude-714-unify-file-failures.json +0 -7
- dirsql-0.4.7/packages/python/e2e-attestations/claude-715-binding-scan-failures.json +0 -7
- dirsql-0.4.7/packages/python/e2e-attestations/claude-716-drop-regex.json +0 -7
- dirsql-0.4.7/packages/python/e2e-attestations/feat-742-gitignore-by-default.json +0 -7
- {dirsql-0.4.7 → dirsql-0.4.9}/Cargo.toml +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/__init__.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/binary_path.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/discover_plugins/with_discovered_plugins.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/is_windows.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/main.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/cli/resolve_config_extensions.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/py.typed +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/resolve_config_extensions.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/AGENTS.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/explanation.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/getting-started.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/embed.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/persist.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/index.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/migrations.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/package.json +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/cli.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/columns.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/hooks.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/http-api.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/docs/reference/sdk.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/conftest.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/index.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/migrations.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/package.json +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/cli.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/http-api.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/Cargo.toml +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/README.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-batch-ingest-transaction.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-chained-pre-post-query-hooks.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-fan-out-file-table-matching.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-persist-wal.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-repeatable-builder-config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-repeatable-cli-config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-13-subcommand-local-config-flags.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-19-path-table-query-fallback.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-19-path-table-vtab.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-20-path-table-glob-semantics.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-20-schema-inference.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-21-on-file-flag.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-23-init-escalation-example.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-23-query-default-cli.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-07-29-on-file-failures-accumulate.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-08-02-drop-regex.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-08-02-per-file-scan-failures.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-08-03-gitignore-by-default.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/2026-08-03-nested-default-ignores.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/changelog.d/README.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/index.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/migrations.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/cli.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/http-api.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/path-tables.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-fan-out-file-table-matching.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-persist-wal.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-13-subcommand-local-config-flags.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-20-path-table-glob-semantics.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-23-init-escalation-example.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-23-query-default-cli.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-08-02-per-file-scan-failures.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-08-03-gitignore-by-default.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/2026-08-03-nested-default-ignores.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/migrations.d/README.md +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/mod.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/command.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/config.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/db.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/infer.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/lib.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/matcher.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/parsed_vtab.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/path_table.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/scanner.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/vtab.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.4.7 → dirsql-0.4.9}/pyproject.toml +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dirsql
|
|
3
|
-
Version: 0.4.
|
|
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,
|
|
@@ -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
|
+
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).
|
|
@@ -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).
|
|
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
|