dirsql 0.4.67__tar.gz → 0.4.69__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.67 → dirsql-0.4.69}/Cargo.lock +3 -2
- {dirsql-0.4.67 → dirsql-0.4.69}/PKG-INFO +1 -1
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/cli/discover_plugins/with_discovered_plugins.py +3 -3
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/cli/resolve_config_extensions.py +1 -1
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/.vitepress/config.ts +3 -0
- dirsql-0.4.69/docs/context/.gitattributes +2 -0
- dirsql-0.4.69/docs/context/recipes.md +103 -0
- dirsql-0.4.69/docs/context/troubleshooting.md +64 -0
- dirsql-0.4.69/docs/context/usage.md +54 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/reference/cli.md +13 -1
- {dirsql-0.4.67/packages/rust → dirsql-0.4.69}/docs/reference/http-api.md +1 -1
- {dirsql-0.4.67/packages/python → dirsql-0.4.69}/docs/reference/path-tables.md +23 -13
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/Cargo.toml +1 -1
- dirsql-0.4.69/packages/python/changelog.d/2026-10-05-cli-context.md +3 -0
- dirsql-0.4.69/packages/python/changelog.d/2026-10-05-gitignore-requires-repo.md +5 -0
- dirsql-0.4.69/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +5 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/.vitepress/config.ts +3 -0
- dirsql-0.4.69/packages/python/docs/context/.gitattributes +2 -0
- dirsql-0.4.69/packages/python/docs/context/recipes.md +103 -0
- dirsql-0.4.69/packages/python/docs/context/troubleshooting.md +64 -0
- dirsql-0.4.69/packages/python/docs/context/usage.md +54 -0
- {dirsql-0.4.67/packages/rust → dirsql-0.4.69/packages/python}/docs/reference/cli.md +13 -1
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/reference/http-api.md +1 -1
- {dirsql-0.4.67 → dirsql-0.4.69/packages/python}/docs/reference/path-tables.md +23 -13
- dirsql-0.4.69/packages/python/e2e-attestations/claude-1257-trailing-slash.json +7 -0
- dirsql-0.4.69/packages/python/e2e-attestations/claude-1264-context.json +7 -0
- dirsql-0.4.69/packages/python/e2e-attestations/claude-1269-utf8-chars.json +7 -0
- dirsql-0.4.69/packages/python/e2e-attestations/claude-1272-ancestor-gitignore.json +7 -0
- dirsql-0.4.69/packages/python/e2e-attestations/claude-1273-walk-prune.json +7 -0
- dirsql-0.4.69/packages/python/e2e-attestations/claude-1285-ingest-fast.json +7 -0
- dirsql-0.4.69/packages/python/migrations.d/2026-10-05-cli-context.md +26 -0
- dirsql-0.4.69/packages/python/migrations.d/2026-10-05-gitignore-requires-repo.md +36 -0
- dirsql-0.4.69/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +35 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/Cargo.toml +2 -1
- dirsql-0.4.69/packages/rust/docs/context/.gitattributes +2 -0
- dirsql-0.4.69/packages/rust/docs/context/recipes.md +103 -0
- dirsql-0.4.69/packages/rust/docs/context/troubleshooting.md +64 -0
- dirsql-0.4.69/packages/rust/docs/context/usage.md +54 -0
- {dirsql-0.4.67/packages/python → dirsql-0.4.69/packages/rust}/docs/reference/cli.md +13 -1
- {dirsql-0.4.67 → dirsql-0.4.69/packages/rust}/docs/reference/http-api.md +1 -1
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/reference/path-tables.md +23 -13
- dirsql-0.4.69/packages/rust/src/cli/context.rs +47 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/cli/mod.rs +2 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/cli/run.rs +26 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/db.rs +22 -17
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/lib.rs +228 -22
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/matcher.rs +113 -27
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/on_file.rs +43 -11
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/path_table.rs +81 -3
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/scanner.rs +195 -51
- {dirsql-0.4.67 → dirsql-0.4.69}/Cargo.toml +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/README.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/__init__.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/_async.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/_dirsql.pyi +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/cli/__init__.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/cli/discover_plugins/__init__.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/cli/main.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/plan_entry_path.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/py.typed +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/read_config.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/resolve_configs_extension_specs.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/resolve_extension.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/dirsql/resolve_package.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/AGENTS.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/explanation.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/getting-started.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/embed.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/persist.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/query-json.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/index.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/package.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/plugins.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/reference/columns.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/reference/config.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/reference/hooks.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/docs/reference/sdk.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/CHANGELOG.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/MIGRATIONS.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/README.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/changelog.d/README.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/conftest.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/.claude/CLAUDE.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/.vitepress/theme/index.ts +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/AGENTS.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/explanation.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/getting-started.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/embed.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/persist.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/query-json.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/index.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/package.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/plugins.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/pnpm-lock.yaml +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/pnpm-workspace.yaml +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/reference/columns.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/reference/config.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/reference/hooks.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/docs/reference/sdk.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/migrations.d/README.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/src/lib.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/testing-conventions.toml +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/tests/__init__.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/tests/conftest.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/tests/e2e/__init__.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/tests/e2e/speed_of_light.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/tests/integration/__init__.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/tests/integration/binding/__init__.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/python/tests/integration/hermetic/__init__.py +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/CHANGELOG.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/MIGRATIONS.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/README.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/benches/db_bench.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/benches/differ_bench.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/benches/matcher_bench.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/benches/scanner_bench.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/explanation.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/getting-started.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/columns-from-paths.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/define-tables.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/embed.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/extract-from-contents.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/load-extension.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/persist.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/query-json.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/query-without-config.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/react-to-changes.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/search-by-meaning.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/search-indexes.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/skip-files.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/howto/write-a-plugin.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/index.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/plugins.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/reference/columns.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/reference/config.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/reference/hooks.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/docs/reference/sdk.md +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/bin/dirsql.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/cli/execute.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/cli/init.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/cli/repl.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/cli/router.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/cli/serialize.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/cli/server.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/cli/table.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/command.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/config.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/default_config.toml +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/differ.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/extension_resolution.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/functions.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/infer.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/launcher.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/parsed_vtab.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/persist.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/progress.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/row_event_flat.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/sql_literal.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/vtab.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/vtab_scaffold.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/packages/rust/src/watcher.rs +0 -0
- {dirsql-0.4.67 → dirsql-0.4.69}/pyproject.toml +0 -0
|
@@ -552,7 +552,7 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
|
|
552
552
|
|
|
553
553
|
[[package]]
|
|
554
554
|
name = "dirsql"
|
|
555
|
-
version = "0.4.
|
|
555
|
+
version = "0.4.69"
|
|
556
556
|
dependencies = [
|
|
557
557
|
"assert_cmd",
|
|
558
558
|
"axum",
|
|
@@ -574,6 +574,7 @@ dependencies = [
|
|
|
574
574
|
"notify",
|
|
575
575
|
"predicates",
|
|
576
576
|
"reedline",
|
|
577
|
+
"regex",
|
|
577
578
|
"reqwest",
|
|
578
579
|
"rusqlite",
|
|
579
580
|
"serde",
|
|
@@ -600,7 +601,7 @@ dependencies = [
|
|
|
600
601
|
|
|
601
602
|
[[package]]
|
|
602
603
|
name = "dirsql-py-ext"
|
|
603
|
-
version = "0.4.
|
|
604
|
+
version = "0.4.69"
|
|
604
605
|
dependencies = [
|
|
605
606
|
"dirsql",
|
|
606
607
|
"pyo3",
|
|
@@ -22,8 +22,8 @@ from .user_passed_config import user_passed_config
|
|
|
22
22
|
def with_discovered_plugins(argv: list[str]) -> list[str]:
|
|
23
23
|
"""Return ``argv`` with each installed plugin's fragment appended as ``-c``
|
|
24
24
|
(plus ``--include-default`` when the user passed no ``-c``). ``--no-plugin``
|
|
25
|
-
/ ``DIRSQL_NO_PLUGIN`` skip discovery, consuming the flag. ``init``
|
|
26
|
-
config, so
|
|
25
|
+
/ ``DIRSQL_NO_PLUGIN`` skip discovery, consuming the flag. ``init`` and ``context`` take no
|
|
26
|
+
config, so they are left untouched. Raises if a declared plugin is missing its
|
|
27
27
|
module or fragment (the launcher surfaces a clean error).
|
|
28
28
|
|
|
29
29
|
Appending is safe because config flags are subcommand-local (#609): the
|
|
@@ -34,7 +34,7 @@ def with_discovered_plugins(argv: list[str]) -> list[str]:
|
|
|
34
34
|
"""
|
|
35
35
|
if discovery_disabled(argv):
|
|
36
36
|
return [a for a in argv if a != NO_PLUGIN_FLAG]
|
|
37
|
-
if argv and argv[0]
|
|
37
|
+
if argv and argv[0] in ("init", "context"):
|
|
38
38
|
return argv
|
|
39
39
|
fragments = discovered_fragments()
|
|
40
40
|
if not fragments:
|
|
@@ -27,7 +27,7 @@ def with_resolved_extensions(argv: list[str]) -> list[str]:
|
|
|
27
27
|
"""Return ``argv`` plus ``--extension`` flags when a TOML config names an
|
|
28
28
|
extension by package name; otherwise return ``argv`` unchanged. Raises if a
|
|
29
29
|
package name cannot be resolved (the launcher surfaces a clean error)."""
|
|
30
|
-
if argv and argv[0]
|
|
30
|
+
if argv and argv[0] in ("init", "context"):
|
|
31
31
|
return argv
|
|
32
32
|
config_paths = [
|
|
33
33
|
p for p in config_paths_from_argv(argv) if not p.endswith(_NATIVE_SUFFIXES)
|
|
@@ -5,6 +5,9 @@ export default defineConfig({
|
|
|
5
5
|
description: 'Ephemeral SQL index over a local directory. Watches a filesystem, ingests structured files into an ephemeral SQLite database, and exposes a SQL query interface.',
|
|
6
6
|
base: '/',
|
|
7
7
|
|
|
8
|
+
// The guide `dirsql context` prints, compiled into the binary; not site pages.
|
|
9
|
+
srcExclude: ['context/**'],
|
|
10
|
+
|
|
8
11
|
// Vite blocks dev-server requests whose Host header isn't allowlisted, so
|
|
9
12
|
// `pnpm dev --host` reached by a network hostname (e.g. a Tailscale
|
|
10
13
|
// `*.ts.net` name) 400s. Allow extra hosts from the environment so a
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
## Recipes
|
|
2
|
+
|
|
3
|
+
Each query runs as written from the directory in question and prints a JSON array of row objects.
|
|
4
|
+
|
|
5
|
+
### Largest files
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
uvx dirsql "SELECT path, size FROM './**' ORDER BY size DESC LIMIT 10" --format json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Count and total size by extension
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
uvx dirsql "SELECT ext, COUNT(*) AS files, SUM(size) AS bytes FROM './**' GROUP BY ext ORDER BY files DESC" --format json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`ext` is `NULL` for files with no extension and keeps its case; group by `LOWER(ext)` to fold `JPG` into `jpg`.
|
|
18
|
+
|
|
19
|
+
### Files per directory
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
uvx dirsql "SELECT dir, COUNT(*) AS files FROM './**' GROUP BY dir ORDER BY files DESC" --format json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`dir` is the empty string for files at the top level.
|
|
26
|
+
|
|
27
|
+
### Stale files
|
|
28
|
+
|
|
29
|
+
Not modified in the last 90 days:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
uvx dirsql "SELECT path, datetime(mtime, 'unixepoch') AS modified FROM './**' WHERE mtime < strftime('%s', 'now') - 90 * 86400 ORDER BY mtime" --format json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Most recently modified markdown:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
uvx dirsql "SELECT path, datetime(mtime, 'unixepoch') AS modified FROM './**/*.md' ORDER BY mtime DESC LIMIT 10" --format json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### The same JSON field from many files
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
uvx dirsql "SELECT path, content ->> 'name' AS name, content ->> 'version' AS version FROM './**/metadata.json' WHERE json_valid(content) ORDER BY name" --format json
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`json_valid(content)` keeps one empty or malformed file from failing the whole query. Nested keys are JSON paths, still quoted: `content ->> '$.runtime.engine'`. Booleans arrive as `1` and `0`:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
uvx dirsql "SELECT path FROM './**/metadata.json' WHERE json_valid(content) AND content ->> 'disabled' = 0" --format json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Count across an array field with `json_each`, guarded the same way:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
uvx dirsql "SELECT t.value AS tag, COUNT(*) AS n FROM './**/metadata.json' AS m, json_each(m.content, '$.tags') AS t WHERE json_valid(m.content) GROUP BY tag ORDER BY n DESC, tag" --format json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Frontmatter
|
|
60
|
+
|
|
61
|
+
Files whose frontmatter contains a given line (`%` matches across newlines):
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
uvx dirsql "SELECT path FROM './**/*.md' WHERE content LIKE '---%status: draft%'" --format json
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
One frontmatter field from every file:
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
uvx dirsql "WITH fm AS (SELECT path, substr(content, instr(content, 'title:') + 6) AS rest FROM './**/*.md' WHERE content LIKE '---%title:%') SELECT path, trim(substr(rest, 1, instr(rest, char(10)) - 1)) AS title FROM fm ORDER BY path" --format json
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Occurrences of a string per file
|
|
74
|
+
|
|
75
|
+
grep stops at matching lines; SQL can count them:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
uvx dirsql "SELECT path, (length(content) - length(replace(content, 'TODO', ''))) / length('TODO') AS todos FROM './**/*.md' WHERE todos > 0 ORDER BY todos DESC" --format json
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Join two directories
|
|
82
|
+
|
|
83
|
+
Source modules with no matching doc page:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
uvx dirsql "SELECT s.path FROM './src/*.py' AS s LEFT JOIN './docs/**/*.md' AS d ON replace(d.basename, '.md', '') = replace(s.basename, '.py', '') WHERE d.path IS NULL ORDER BY s.path" --format json
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Top-k by meaning
|
|
90
|
+
|
|
91
|
+
Needs the embeddings plugin. The first run downloads a model of roughly a hundred megabytes, with progress on stderr:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
uvx --with dirsql-plugin-embeddings dirsql "
|
|
95
|
+
SELECT path,
|
|
96
|
+
vec_distance_cosine(emb, embed('how do I cook pasta?')) AS distance
|
|
97
|
+
FROM (SELECT path, embed(content) AS emb FROM './notes/*.md')
|
|
98
|
+
WHERE emb IS NOT NULL
|
|
99
|
+
ORDER BY distance
|
|
100
|
+
LIMIT 3" --format json
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`WHERE emb IS NOT NULL` matters: an unreadable file embeds to `NULL`, and SQLite sorts `NULL` first. For ranked paths only, `uvx dirsql-plugin-embeddings './notes/*.md' "how do I cook pasta?" -k 3` prints `path<TAB>distance` lines.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
## Troubleshooting
|
|
2
|
+
|
|
3
|
+
Diagnostics go to stderr and the exit code is `1`.
|
|
4
|
+
|
|
5
|
+
### `no such table: **/*.md; did you mean './**/*.md'?`
|
|
6
|
+
|
|
7
|
+
A bare glob. Paths relative to the directory you run in start with `./`:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
uvx dirsql "SELECT path FROM './**/*.md'" --format json
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### `near ".": syntax error` and `hint: paths used as table names must be quoted`
|
|
14
|
+
|
|
15
|
+
`FROM ./` reaches SQLite's parser as punctuation. Quote the path:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
uvx dirsql "SELECT COUNT(*) AS files FROM './'" --format json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### `no such column: disabled`
|
|
22
|
+
|
|
23
|
+
`content ->> disabled` names a column. The key is a string literal:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
uvx dirsql "SELECT path, content ->> 'disabled' AS disabled FROM './**/metadata.json' WHERE json_valid(content)" --format json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### `SQLite error: malformed JSON`
|
|
30
|
+
|
|
31
|
+
One matched file is not valid JSON (an empty file counts), and that fails the whole query. Guard with `json_valid`:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
uvx dirsql "SELECT path, content ->> 'name' AS name FROM './**/*.json' WHERE json_valid(content)" --format json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### `no such table: files; did you mean FROM './**'?`
|
|
38
|
+
|
|
39
|
+
There is no implicit table. Query the tree directly:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
uvx dirsql "SELECT path FROM './**'" --format json
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Empty `[]` for files you can see
|
|
46
|
+
|
|
47
|
+
- **You named a directory**, which lists one level only. `'./**'` and `'./docs/**'` are the recursive forms.
|
|
48
|
+
- **The files are gitignored**, inside a git repo (outside one, no `.gitignore` applies). `--no-ignore` scans them:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
uvx dirsql "SELECT path FROM './**'" --format json --no-ignore
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Naming the directory outright also works: `'./build'` scans `build/` even when it is ignored.
|
|
55
|
+
- **The files are under `node_modules`**, which is skipped unless the path names it: `'./node_modules/**'`.
|
|
56
|
+
- **The files start with a dot, or sit under a directory that does.** Spell the dot: `'./.git/**'`, `'./**/.env'`.
|
|
57
|
+
|
|
58
|
+
### `table ./ may not be modified`
|
|
59
|
+
|
|
60
|
+
dirsql is read-only. Mutations belong in a script that consumes the query's JSON.
|
|
61
|
+
|
|
62
|
+
### A table appeared, not JSON
|
|
63
|
+
|
|
64
|
+
`--format json` was not passed and stdout was a terminal. Pass it.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
## Usage
|
|
2
|
+
|
|
3
|
+
dirsql answers a question about a directory tree with SQL. Nothing to install; run it from the directory in question:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
uvx dirsql "SELECT basename, size FROM './**' ORDER BY size DESC LIMIT 5" --format json
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Always pass `--format json`. Without it the output depends on stdout: a terminal gets a table, a pipe gets JSON, and you cannot know which you have. With it, stdout is one JSON array of row objects. Errors go to stderr with exit code `1`.
|
|
10
|
+
|
|
11
|
+
### Path-tables
|
|
12
|
+
|
|
13
|
+
A quoted path stands in for a table name. Paths are relative to the directory you run in.
|
|
14
|
+
|
|
15
|
+
| You write | dirsql scans |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| `'./'` | files directly here, no deeper |
|
|
18
|
+
| `'./docs'` | files directly inside `docs/`, no deeper |
|
|
19
|
+
| `'./*.md'` | markdown directly here |
|
|
20
|
+
| `'./**'` | every file, any depth |
|
|
21
|
+
| `'./docs/**'` | every file under `docs/`, any depth |
|
|
22
|
+
| `'./**/*.md'` | markdown at any depth |
|
|
23
|
+
| `'./notes/today.md'` | that one file |
|
|
24
|
+
|
|
25
|
+
`*` matches within one directory level and `**` matches any depth. A directory name lists one level, like `ls docs`, so write `'./**'` to scan the whole tree. Rows are files only, never directories. `'/var/log/*.log'`, `'../notes'` and `'~/notes/*.md'` also resolve; those report absolute `path` values.
|
|
26
|
+
|
|
27
|
+
Two mistakes fail every time:
|
|
28
|
+
|
|
29
|
+
1. **The path must be quoted.** `FROM ./` is a syntax error; write `FROM './'`.
|
|
30
|
+
2. **`content ->> 'key'` takes a string literal.** `content ->> key` fails with `no such column: key`.
|
|
31
|
+
|
|
32
|
+
### Columns
|
|
33
|
+
|
|
34
|
+
Every row has `path`, `basename`, `dir`, `ext` (no dot, `NULL` when absent), `size` (bytes), `mtime` and `ctime` (Unix seconds). A hidden `content` column holds the file's text: it is left out of `SELECT *`, read only when you name it, and `NULL` for unreadable or non-UTF-8 files.
|
|
35
|
+
|
|
36
|
+
### What a scan skips
|
|
37
|
+
|
|
38
|
+
- **`.gitignore` is respected inside a git repo**, as git does; outside one (no enclosing `.git`) no `.gitignore` applies. Pass `--no-ignore` to scan gitignored files too, or name the ignored directory outright: `'./build'` scans `build/`.
|
|
39
|
+
- **`node_modules` is skipped** unless the path names it: `'./node_modules/**'`.
|
|
40
|
+
- **`'./**'` does not enter `.git`.** Naming it scans it: `'./.git/**'`.
|
|
41
|
+
- **To match dotfiles, spell the dot:** `'./.github/**'`, `'./**/.env'`.
|
|
42
|
+
|
|
43
|
+
### Escalation
|
|
44
|
+
|
|
45
|
+
1. A path-table, as above. Fits a question you ask once.
|
|
46
|
+
2. The same tree queried repeatedly, or a parser you want to keep: declare a table in a `.dirsql.toml` and pass it with `-c .dirsql.toml`. See [config](https://dirsql.dev/reference/config).
|
|
47
|
+
3. One row per record inside each file, inline: `--on-file <command>` attaches a parser to every path-table in the query, and its output replaces the stat columns. See [hooks](https://dirsql.dev/reference/hooks).
|
|
48
|
+
4. Search by meaning: `uvx --with dirsql-plugin-embeddings dirsql "<sql>" --format json` adds `embed()` and `vec_distance_cosine()`. See [search by meaning](https://dirsql.dev/howto/search-by-meaning).
|
|
49
|
+
|
|
50
|
+
### Read-only
|
|
51
|
+
|
|
52
|
+
dirsql never writes to, moves or changes the files it scans, and it rejects mutating SQL. Do not pass `--persist`: it writes a cache database into the directory.
|
|
53
|
+
|
|
54
|
+
Full docs: [dirsql.dev](https://dirsql.dev/) ([path-tables](https://dirsql.dev/reference/path-tables), [columns](https://dirsql.dev/reference/columns), [CLI](https://dirsql.dev/reference/cli), [query JSON](https://dirsql.dev/howto/query-json)).
|
|
@@ -11,6 +11,7 @@ The `dirsql` binary has these modes:
|
|
|
11
11
|
| `dirsql query "<sql>"` | Explicit synonym for the default one-shot query. |
|
|
12
12
|
| `dirsql server` | Start a long-lived HTTP server exposing a SQL view of a directory. See [HTTP API](./http-api.md). |
|
|
13
13
|
| `dirsql init` | Generate a `.dirsql.toml`. |
|
|
14
|
+
| `dirsql context` | Print the usage guide for this version, for an agent to read. |
|
|
14
15
|
| `dirsql` (bare) | Open a [REPL](#the-repl) over the current directory, reading statements until EOF. |
|
|
15
16
|
|
|
16
17
|
Bare `dirsql` does **not** start the server — that is `dirsql server`.
|
|
@@ -277,7 +278,7 @@ with all seven [stat columns](./columns.md): `path`, `basename`, `dir`, `ext`,
|
|
|
277
278
|
|
|
278
279
|
```bash
|
|
279
280
|
curl -s localhost:7117/query -H 'content-type: application/json' \
|
|
280
|
-
-d
|
|
281
|
+
-d "{\"sql\":\"SELECT basename, size FROM './' ORDER BY size DESC LIMIT 5\"}"
|
|
281
282
|
```
|
|
282
283
|
|
|
283
284
|
Earlier versions served an implicit table named `files` here. It is gone; a
|
|
@@ -441,6 +442,17 @@ All failures exit `1` with a message on stderr:
|
|
|
441
442
|
|
|
442
443
|
On success, `init` exits `0`.
|
|
443
444
|
|
|
445
|
+
## `dirsql context`
|
|
446
|
+
|
|
447
|
+
```sh
|
|
448
|
+
uvx dirsql context
|
|
449
|
+
```
|
|
450
|
+
|
|
451
|
+
Prints a markdown guide for an agent that is about to query files: the
|
|
452
|
+
first line is `dirsql <version>`, then sections on usage, recipes and
|
|
453
|
+
troubleshooting. The guide is compiled into the binary, so it describes the
|
|
454
|
+
version that prints it. It takes no flags and exits `0`.
|
|
455
|
+
|
|
444
456
|
## Plugins
|
|
445
457
|
|
|
446
458
|
A **plugin** is an ordinary Python package that ships a `dirsql.toml` config
|
|
@@ -27,7 +27,7 @@ The `200` response is a JSON array of row objects keyed by column name:
|
|
|
27
27
|
```bash
|
|
28
28
|
curl -s http://localhost:7117/query \
|
|
29
29
|
-H 'content-type: application/json' \
|
|
30
|
-
-d
|
|
30
|
+
-d "{\"sql\":\"SELECT COUNT(*) AS n FROM './'\"}" \
|
|
31
31
|
| jq
|
|
32
32
|
```
|
|
33
33
|
|
|
@@ -37,14 +37,16 @@ indexing, not your shell's working directory.
|
|
|
37
37
|
|
|
38
38
|
**A directory name is one level, like `ls`.** Naming a directory lists the
|
|
39
39
|
files directly inside it and no deeper; `*` matches one level and `**` any
|
|
40
|
-
depth, as in the shell.
|
|
40
|
+
depth, as in the shell. A trailing `/` is `*` appended, so `'./*/'` is
|
|
41
|
+
`'./*/*'`: the files directly inside each top-level directory, like `ls */`.
|
|
41
42
|
|
|
42
43
|
| You write | dirsql scans |
|
|
43
44
|
| --- | --- |
|
|
44
45
|
| `'./'` | files directly inside the index root, and no deeper |
|
|
45
46
|
| `'./docs'`, `'./docs/'` | files directly inside `docs/` |
|
|
46
47
|
| `'./*'` | the same as `'./'` |
|
|
47
|
-
| `'./**'` | every file under the index root, recursively |
|
|
48
|
+
| `'./**'`, `'./**/'` | every file under the index root, recursively |
|
|
49
|
+
| `'./*/'` | the same as `'./*/*'`: files directly inside each top-level directory |
|
|
48
50
|
| `'./docs/*.md'` | markdown files directly inside `docs/` |
|
|
49
51
|
| `'./docs/**/*.md'` | markdown files at any depth under `docs/` |
|
|
50
52
|
| `'./notes/today.md'` | exactly that one file — one file is one row |
|
|
@@ -53,9 +55,10 @@ A path containing `*`, `?`, `[` or `{` is a glob and is used exactly as
|
|
|
53
55
|
written: `*` matches within a single directory, `**` crosses directories.
|
|
54
56
|
|
|
55
57
|
The scan starts at the last directory named outright before the first glob
|
|
56
|
-
component
|
|
57
|
-
|
|
58
|
-
directories beside
|
|
58
|
+
component, and descends only as deep as the pattern can match --
|
|
59
|
+
`'./small/*.md'` lists `small/` and nothing else -- so a query over one
|
|
60
|
+
directory costs what `ls small` costs, however large the directories beside
|
|
61
|
+
or below it. Only `**` walks a whole subtree.
|
|
59
62
|
|
|
60
63
|
A path naming a single file yields exactly one row. dirsql never splits a file
|
|
61
64
|
into rows on its own — that is what a table's `on_file` hook is for.
|
|
@@ -108,7 +111,8 @@ Three other prefixes resolve, with their usual shell meanings:
|
|
|
108
111
|
| `'../notes'` | relative to the index root's parent |
|
|
109
112
|
| `'~/notes/*.md'` | relative to your home directory |
|
|
110
113
|
|
|
111
|
-
A directory named this way is one level too; `'../notes/**'` descends.
|
|
114
|
+
A directory named this way is one level too; `'../notes/**'` descends. The
|
|
115
|
+
trailing-`/` rule holds here as well: `'~/*/'` is `'~/*/*'`.
|
|
112
116
|
`..` is folded out textually, not followed through symlinks, so the directory
|
|
113
117
|
scanned is a function of the string you wrote.
|
|
114
118
|
|
|
@@ -257,15 +261,21 @@ skipped just like one at the top.
|
|
|
257
261
|
|
|
258
262
|
### `.gitignore`
|
|
259
263
|
|
|
260
|
-
Path-table scans also respect `.gitignore` files by default,
|
|
261
|
-
ripgrep do: a `.gitignore`
|
|
264
|
+
Path-table scans also respect `.gitignore` files by default, inside a git
|
|
265
|
+
repo, the way git, fd and ripgrep do: a `.gitignore` applies below its own
|
|
262
266
|
directory, deeper files override shallower ones, `!pattern` re-includes, and
|
|
263
267
|
an ignored directory is pruned rather than walked. In a typical repo this
|
|
264
|
-
excludes build output, virtualenvs, and caches with zero ceremony.
|
|
265
|
-
|
|
266
|
-
the built-in defaults above remain as a floor for directories with no
|
|
268
|
+
excludes build output, virtualenvs, and caches with zero ceremony. The
|
|
269
|
+
built-in defaults above remain as a floor for directories with no
|
|
267
270
|
`.gitignore` at all.
|
|
268
271
|
|
|
272
|
+
A `.gitignore` is in force only when a directory holding `.git` encloses it.
|
|
273
|
+
Outside a repo none applies, at the scan's start, above it or below it: a
|
|
274
|
+
`~/.claude` whose `.gitignore` is `*` still lists its files when `~/.claude`
|
|
275
|
+
is not a repo. Inside one, every `.gitignore` from the repo root down
|
|
276
|
+
applies, including those above the directory a scan starts in, so
|
|
277
|
+
`'./docs/*.log'` and `'./**/*.log'` agree about `docs/`.
|
|
278
|
+
|
|
269
279
|
Pass [`--no-ignore`](./cli.md#flags) to restore the full walk — the
|
|
270
280
|
determinism switch for scripted use, since results otherwise depend on
|
|
271
281
|
`.gitignore` state. It disables only the `.gitignore` respect; the built-in
|
|
@@ -282,8 +292,8 @@ SELECT path FROM './node_modules/*/package.json'; -- scans it anyway
|
|
|
282
292
|
SELECT path FROM './dist'; -- scans dist/ even when gitignored
|
|
283
293
|
```
|
|
284
294
|
|
|
285
|
-
|
|
286
|
-
|
|
295
|
+
The `.gitignore` files in force there, including those above it, still
|
|
296
|
+
filter what lies beneath it.
|
|
287
297
|
|
|
288
298
|
### Hidden files
|
|
289
299
|
|
|
@@ -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.69"
|
|
8
8
|
# abi3 note: the `abi3-py310` pyo3 feature (below) builds ONE stable-ABI
|
|
9
9
|
# `cp310-abi3` wheel per platform that loads on every CPython >= 3.10
|
|
10
10
|
# (matching `pyproject.toml`'s `requires-python = ">=3.10"`), instead of
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
**Added**
|
|
2
|
+
|
|
3
|
+
- **`dirsql context` prints a usage guide for agents.** The first line is `dirsql <version>`, then markdown sections on usage, recipes, and fixes for common errors, matched to the installed version. The launcher passes `context` through without adding plugin or extension flags, as it does for `init`. (#1264)
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
**Changed** A `.gitignore` applies to path-table scans only inside a git
|
|
2
|
+
repo, as in git, fd and ripgrep: one is in force only when a directory
|
|
3
|
+
holding `.git` encloses it. Outside a repo none applies, at the scan's start,
|
|
4
|
+
above it or below it, so a `~/.claude` whose `.gitignore` is `*` lists its
|
|
5
|
+
files. Inside a repo nothing changes. `--no-ignore` is unchanged.
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
**Fixed** A trailing `/` on a path-table is `*` appended. `'./*/'` now lists
|
|
2
|
+
the files directly inside each top-level directory, the same rows as
|
|
3
|
+
`'./*/*'` (like `ls */`); it used to drop the slash and list the top-level
|
|
4
|
+
files. `'./'`, `'./docs/'` and `'./**/'` return the same rows as before. The
|
|
5
|
+
rule applies to absolute, `../` and `~/` path-tables too.
|
|
@@ -5,6 +5,9 @@ export default defineConfig({
|
|
|
5
5
|
description: 'Ephemeral SQL index over a local directory. Watches a filesystem, ingests structured files into an ephemeral SQLite database, and exposes a SQL query interface.',
|
|
6
6
|
base: '/',
|
|
7
7
|
|
|
8
|
+
// The guide `dirsql context` prints, compiled into the binary; not site pages.
|
|
9
|
+
srcExclude: ['context/**'],
|
|
10
|
+
|
|
8
11
|
// Vite blocks dev-server requests whose Host header isn't allowlisted, so
|
|
9
12
|
// `pnpm dev --host` reached by a network hostname (e.g. a Tailscale
|
|
10
13
|
// `*.ts.net` name) 400s. Allow extra hosts from the environment so a
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
## Recipes
|
|
2
|
+
|
|
3
|
+
Each query runs as written from the directory in question and prints a JSON array of row objects.
|
|
4
|
+
|
|
5
|
+
### Largest files
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
uvx dirsql "SELECT path, size FROM './**' ORDER BY size DESC LIMIT 10" --format json
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Count and total size by extension
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
uvx dirsql "SELECT ext, COUNT(*) AS files, SUM(size) AS bytes FROM './**' GROUP BY ext ORDER BY files DESC" --format json
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
`ext` is `NULL` for files with no extension and keeps its case; group by `LOWER(ext)` to fold `JPG` into `jpg`.
|
|
18
|
+
|
|
19
|
+
### Files per directory
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
uvx dirsql "SELECT dir, COUNT(*) AS files FROM './**' GROUP BY dir ORDER BY files DESC" --format json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`dir` is the empty string for files at the top level.
|
|
26
|
+
|
|
27
|
+
### Stale files
|
|
28
|
+
|
|
29
|
+
Not modified in the last 90 days:
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
uvx dirsql "SELECT path, datetime(mtime, 'unixepoch') AS modified FROM './**' WHERE mtime < strftime('%s', 'now') - 90 * 86400 ORDER BY mtime" --format json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Most recently modified markdown:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
uvx dirsql "SELECT path, datetime(mtime, 'unixepoch') AS modified FROM './**/*.md' ORDER BY mtime DESC LIMIT 10" --format json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### The same JSON field from many files
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
uvx dirsql "SELECT path, content ->> 'name' AS name, content ->> 'version' AS version FROM './**/metadata.json' WHERE json_valid(content) ORDER BY name" --format json
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`json_valid(content)` keeps one empty or malformed file from failing the whole query. Nested keys are JSON paths, still quoted: `content ->> '$.runtime.engine'`. Booleans arrive as `1` and `0`:
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
uvx dirsql "SELECT path FROM './**/metadata.json' WHERE json_valid(content) AND content ->> 'disabled' = 0" --format json
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Count across an array field with `json_each`, guarded the same way:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
uvx dirsql "SELECT t.value AS tag, COUNT(*) AS n FROM './**/metadata.json' AS m, json_each(m.content, '$.tags') AS t WHERE json_valid(m.content) GROUP BY tag ORDER BY n DESC, tag" --format json
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Frontmatter
|
|
60
|
+
|
|
61
|
+
Files whose frontmatter contains a given line (`%` matches across newlines):
|
|
62
|
+
|
|
63
|
+
```sh
|
|
64
|
+
uvx dirsql "SELECT path FROM './**/*.md' WHERE content LIKE '---%status: draft%'" --format json
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
One frontmatter field from every file:
|
|
68
|
+
|
|
69
|
+
```sh
|
|
70
|
+
uvx dirsql "WITH fm AS (SELECT path, substr(content, instr(content, 'title:') + 6) AS rest FROM './**/*.md' WHERE content LIKE '---%title:%') SELECT path, trim(substr(rest, 1, instr(rest, char(10)) - 1)) AS title FROM fm ORDER BY path" --format json
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Occurrences of a string per file
|
|
74
|
+
|
|
75
|
+
grep stops at matching lines; SQL can count them:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
uvx dirsql "SELECT path, (length(content) - length(replace(content, 'TODO', ''))) / length('TODO') AS todos FROM './**/*.md' WHERE todos > 0 ORDER BY todos DESC" --format json
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Join two directories
|
|
82
|
+
|
|
83
|
+
Source modules with no matching doc page:
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
uvx dirsql "SELECT s.path FROM './src/*.py' AS s LEFT JOIN './docs/**/*.md' AS d ON replace(d.basename, '.md', '') = replace(s.basename, '.py', '') WHERE d.path IS NULL ORDER BY s.path" --format json
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Top-k by meaning
|
|
90
|
+
|
|
91
|
+
Needs the embeddings plugin. The first run downloads a model of roughly a hundred megabytes, with progress on stderr:
|
|
92
|
+
|
|
93
|
+
```sh
|
|
94
|
+
uvx --with dirsql-plugin-embeddings dirsql "
|
|
95
|
+
SELECT path,
|
|
96
|
+
vec_distance_cosine(emb, embed('how do I cook pasta?')) AS distance
|
|
97
|
+
FROM (SELECT path, embed(content) AS emb FROM './notes/*.md')
|
|
98
|
+
WHERE emb IS NOT NULL
|
|
99
|
+
ORDER BY distance
|
|
100
|
+
LIMIT 3" --format json
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`WHERE emb IS NOT NULL` matters: an unreadable file embeds to `NULL`, and SQLite sorts `NULL` first. For ranked paths only, `uvx dirsql-plugin-embeddings './notes/*.md' "how do I cook pasta?" -k 3` prints `path<TAB>distance` lines.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
## Troubleshooting
|
|
2
|
+
|
|
3
|
+
Diagnostics go to stderr and the exit code is `1`.
|
|
4
|
+
|
|
5
|
+
### `no such table: **/*.md; did you mean './**/*.md'?`
|
|
6
|
+
|
|
7
|
+
A bare glob. Paths relative to the directory you run in start with `./`:
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
uvx dirsql "SELECT path FROM './**/*.md'" --format json
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### `near ".": syntax error` and `hint: paths used as table names must be quoted`
|
|
14
|
+
|
|
15
|
+
`FROM ./` reaches SQLite's parser as punctuation. Quote the path:
|
|
16
|
+
|
|
17
|
+
```sh
|
|
18
|
+
uvx dirsql "SELECT COUNT(*) AS files FROM './'" --format json
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
### `no such column: disabled`
|
|
22
|
+
|
|
23
|
+
`content ->> disabled` names a column. The key is a string literal:
|
|
24
|
+
|
|
25
|
+
```sh
|
|
26
|
+
uvx dirsql "SELECT path, content ->> 'disabled' AS disabled FROM './**/metadata.json' WHERE json_valid(content)" --format json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### `SQLite error: malformed JSON`
|
|
30
|
+
|
|
31
|
+
One matched file is not valid JSON (an empty file counts), and that fails the whole query. Guard with `json_valid`:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
uvx dirsql "SELECT path, content ->> 'name' AS name FROM './**/*.json' WHERE json_valid(content)" --format json
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### `no such table: files; did you mean FROM './**'?`
|
|
38
|
+
|
|
39
|
+
There is no implicit table. Query the tree directly:
|
|
40
|
+
|
|
41
|
+
```sh
|
|
42
|
+
uvx dirsql "SELECT path FROM './**'" --format json
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Empty `[]` for files you can see
|
|
46
|
+
|
|
47
|
+
- **You named a directory**, which lists one level only. `'./**'` and `'./docs/**'` are the recursive forms.
|
|
48
|
+
- **The files are gitignored**, inside a git repo (outside one, no `.gitignore` applies). `--no-ignore` scans them:
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
uvx dirsql "SELECT path FROM './**'" --format json --no-ignore
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Naming the directory outright also works: `'./build'` scans `build/` even when it is ignored.
|
|
55
|
+
- **The files are under `node_modules`**, which is skipped unless the path names it: `'./node_modules/**'`.
|
|
56
|
+
- **The files start with a dot, or sit under a directory that does.** Spell the dot: `'./.git/**'`, `'./**/.env'`.
|
|
57
|
+
|
|
58
|
+
### `table ./ may not be modified`
|
|
59
|
+
|
|
60
|
+
dirsql is read-only. Mutations belong in a script that consumes the query's JSON.
|
|
61
|
+
|
|
62
|
+
### A table appeared, not JSON
|
|
63
|
+
|
|
64
|
+
`--format json` was not passed and stdout was a terminal. Pass it.
|