dirsql 0.4.67__tar.gz → 0.4.68__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (298) hide show
  1. {dirsql-0.4.67 → dirsql-0.4.68}/Cargo.lock +2 -2
  2. {dirsql-0.4.67 → dirsql-0.4.68}/PKG-INFO +1 -1
  3. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/cli/discover_plugins/with_discovered_plugins.py +3 -3
  4. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/cli/resolve_config_extensions.py +1 -1
  5. {dirsql-0.4.67 → dirsql-0.4.68}/docs/.vitepress/config.ts +3 -0
  6. dirsql-0.4.68/docs/context/.gitattributes +2 -0
  7. dirsql-0.4.68/docs/context/recipes.md +103 -0
  8. dirsql-0.4.68/docs/context/troubleshooting.md +64 -0
  9. dirsql-0.4.68/docs/context/usage.md +54 -0
  10. {dirsql-0.4.67 → dirsql-0.4.68}/docs/reference/cli.md +12 -0
  11. {dirsql-0.4.67/packages/python → dirsql-0.4.68}/docs/reference/path-tables.md +6 -3
  12. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/Cargo.toml +1 -1
  13. dirsql-0.4.68/packages/python/changelog.d/2026-10-05-cli-context.md +3 -0
  14. dirsql-0.4.68/packages/python/changelog.d/2026-10-05-path-table-trailing-slash.md +5 -0
  15. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/.vitepress/config.ts +3 -0
  16. dirsql-0.4.68/packages/python/docs/context/.gitattributes +2 -0
  17. dirsql-0.4.68/packages/python/docs/context/recipes.md +103 -0
  18. dirsql-0.4.68/packages/python/docs/context/troubleshooting.md +64 -0
  19. dirsql-0.4.68/packages/python/docs/context/usage.md +54 -0
  20. {dirsql-0.4.67/packages/rust → dirsql-0.4.68/packages/python}/docs/reference/cli.md +12 -0
  21. {dirsql-0.4.67 → dirsql-0.4.68/packages/python}/docs/reference/path-tables.md +6 -3
  22. dirsql-0.4.68/packages/python/e2e-attestations/claude-1257-trailing-slash.json +7 -0
  23. dirsql-0.4.68/packages/python/e2e-attestations/claude-1264-context.json +7 -0
  24. dirsql-0.4.68/packages/python/migrations.d/2026-10-05-cli-context.md +26 -0
  25. dirsql-0.4.68/packages/python/migrations.d/2026-10-05-path-table-trailing-slash.md +35 -0
  26. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/Cargo.toml +1 -1
  27. dirsql-0.4.68/packages/rust/docs/context/.gitattributes +2 -0
  28. dirsql-0.4.68/packages/rust/docs/context/recipes.md +103 -0
  29. dirsql-0.4.68/packages/rust/docs/context/troubleshooting.md +64 -0
  30. dirsql-0.4.68/packages/rust/docs/context/usage.md +54 -0
  31. {dirsql-0.4.67/packages/python → dirsql-0.4.68/packages/rust}/docs/reference/cli.md +12 -0
  32. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/reference/path-tables.md +6 -3
  33. dirsql-0.4.68/packages/rust/src/cli/context.rs +47 -0
  34. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/cli/mod.rs +2 -0
  35. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/cli/run.rs +26 -0
  36. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/path_table.rs +81 -3
  37. {dirsql-0.4.67 → dirsql-0.4.68}/Cargo.toml +0 -0
  38. {dirsql-0.4.67 → dirsql-0.4.68}/README.md +0 -0
  39. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/__init__.py +0 -0
  40. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/_async.py +0 -0
  41. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/_dirsql.pyi +0 -0
  42. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/cli/__init__.py +0 -0
  43. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/cli/discover_plugins/__init__.py +0 -0
  44. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/cli/discover_plugins/discovered_fragments.py +0 -0
  45. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/cli/discover_plugins/discovery_disabled.py +0 -0
  46. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/cli/discover_plugins/fragment_path.py +0 -0
  47. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/cli/discover_plugins/user_passed_config.py +0 -0
  48. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/cli/main.py +0 -0
  49. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/plan_entry_path.py +0 -0
  50. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/py.typed +0 -0
  51. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/read_config.py +0 -0
  52. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/resolve_configs_extension_specs.py +0 -0
  53. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/resolve_extension.py +0 -0
  54. {dirsql-0.4.67 → dirsql-0.4.68}/dirsql/resolve_package.py +0 -0
  55. {dirsql-0.4.67 → dirsql-0.4.68}/docs/.claude/CLAUDE.md +0 -0
  56. {dirsql-0.4.67 → dirsql-0.4.68}/docs/.vitepress/theme/index.ts +0 -0
  57. {dirsql-0.4.67 → dirsql-0.4.68}/docs/.vitepress/theme/lang.ts +0 -0
  58. {dirsql-0.4.67 → dirsql-0.4.68}/docs/AGENTS.md +0 -0
  59. {dirsql-0.4.67 → dirsql-0.4.68}/docs/explanation.md +0 -0
  60. {dirsql-0.4.67 → dirsql-0.4.68}/docs/getting-started.md +0 -0
  61. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/columns-from-paths.md +0 -0
  62. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/define-tables.md +0 -0
  63. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/embed.md +0 -0
  64. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/extract-from-contents.md +0 -0
  65. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/load-extension.md +0 -0
  66. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/parse-files-into-columns.md +0 -0
  67. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/persist.md +0 -0
  68. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/query-json.md +0 -0
  69. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/query-without-config.md +0 -0
  70. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/react-to-changes.md +0 -0
  71. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/search-by-meaning.md +0 -0
  72. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/search-indexes.md +0 -0
  73. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/skip-files.md +0 -0
  74. {dirsql-0.4.67 → dirsql-0.4.68}/docs/howto/write-a-plugin.md +0 -0
  75. {dirsql-0.4.67 → dirsql-0.4.68}/docs/index.md +0 -0
  76. {dirsql-0.4.67 → dirsql-0.4.68}/docs/package.json +0 -0
  77. {dirsql-0.4.67 → dirsql-0.4.68}/docs/plugins.md +0 -0
  78. {dirsql-0.4.67 → dirsql-0.4.68}/docs/pnpm-lock.yaml +0 -0
  79. {dirsql-0.4.67 → dirsql-0.4.68}/docs/pnpm-workspace.yaml +0 -0
  80. {dirsql-0.4.67 → dirsql-0.4.68}/docs/reference/columns.md +0 -0
  81. {dirsql-0.4.67 → dirsql-0.4.68}/docs/reference/config.md +0 -0
  82. {dirsql-0.4.67 → dirsql-0.4.68}/docs/reference/hooks.md +0 -0
  83. {dirsql-0.4.67 → dirsql-0.4.68}/docs/reference/http-api.md +0 -0
  84. {dirsql-0.4.67 → dirsql-0.4.68}/docs/reference/sdk.md +0 -0
  85. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/CHANGELOG.md +0 -0
  86. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/MIGRATIONS.md +0 -0
  87. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/README.md +0 -0
  88. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  89. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-07-13-plugin-discovery.md +0 -0
  90. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  91. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-07-13-repeatable-config.md +0 -0
  92. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  93. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-07-20-drop-implicit-files-table.md +0 -0
  94. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-07-21-remove-glob-captures.md +0 -0
  95. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-07-24-hookless-table-config-error.md +0 -0
  96. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  97. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-07-29-restore-python-310.md +0 -0
  98. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-08-02-release-profile.md +0 -0
  99. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-08-02-scan-failures.md +0 -0
  100. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-08-03-discovery-ext-resolution.md +0 -0
  101. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-08-03-manylinux-dynamic-binary.md +0 -0
  102. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-08-03-python-no-ignore.md +0 -0
  103. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-08-04-cast-lints.md +0 -0
  104. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-08-04-cli-in-process.md +0 -0
  105. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-08-20-curtaincall-dev-dependency.md +0 -0
  106. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-08-20-declared-table-name.md +0 -0
  107. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-04-config-paths-from-argv-module.md +0 -0
  108. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-05-config-extension-loader-split.md +0 -0
  109. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-05-resolve-config-extensions-split.md +0 -0
  110. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-05-resolve-extension-split.md +0 -0
  111. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-09-launcher-config-path-scan.md +0 -0
  112. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-17-extension-resolution-via-core.md +0 -0
  113. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-18-export-scan-failure.md +0 -0
  114. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-18-flatten-row-event-in-core.md +0 -0
  115. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-18-programmatic-extension-plan.md +0 -0
  116. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  117. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  118. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-10-02-readme-docs-host.md +0 -0
  119. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  120. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-10-03-path-table-directory-one-level.md +0 -0
  121. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  122. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/2026-10-05-path-table-symlinks.md +0 -0
  123. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/changelog.d/README.md +0 -0
  124. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/conftest.py +0 -0
  125. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/.claude/CLAUDE.md +0 -0
  126. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  127. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  128. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/AGENTS.md +0 -0
  129. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/explanation.md +0 -0
  130. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/getting-started.md +0 -0
  131. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/columns-from-paths.md +0 -0
  132. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/define-tables.md +0 -0
  133. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/embed.md +0 -0
  134. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/extract-from-contents.md +0 -0
  135. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/load-extension.md +0 -0
  136. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/parse-files-into-columns.md +0 -0
  137. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/persist.md +0 -0
  138. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/query-json.md +0 -0
  139. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/query-without-config.md +0 -0
  140. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/react-to-changes.md +0 -0
  141. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/search-by-meaning.md +0 -0
  142. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/search-indexes.md +0 -0
  143. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/skip-files.md +0 -0
  144. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/howto/write-a-plugin.md +0 -0
  145. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/index.md +0 -0
  146. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/package.json +0 -0
  147. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/plugins.md +0 -0
  148. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/pnpm-lock.yaml +0 -0
  149. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/pnpm-workspace.yaml +0 -0
  150. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/reference/columns.md +0 -0
  151. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/reference/config.md +0 -0
  152. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/reference/hooks.md +0 -0
  153. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/reference/http-api.md +0 -0
  154. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/docs/reference/sdk.md +0 -0
  155. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/cc-keen-knuth-f11gyq.json +0 -0
  156. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1056-py-ofpf9.json +0 -0
  157. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1066-p1-resolve-extension.json +0 -0
  158. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1078-argv-config-paths-core.json +0 -0
  159. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1079-p2-resolve-config-extensions.json +0 -0
  160. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1080-share-vtab-scaffolding.json +0 -0
  161. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1081-indicatif-progress.json +0 -0
  162. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1096-watch-moved-dir.json +0 -0
  163. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1109-watch-moved-out.json +0 -0
  164. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1119-ext-plan.json +0 -0
  165. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1120-py-ext.json +0 -0
  166. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1122-ext-cleanup.json +0 -0
  167. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1130-codec-crates.json +0 -0
  168. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1131-flatten-row-event.json +0 -0
  169. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1139-sse-flatten.json +0 -0
  170. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1140-scan-failure-export.json +0 -0
  171. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1148-clippy-all-targets.json +0 -0
  172. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1164-sigint-fatal.json +0 -0
  173. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1170-projection-order.json +0 -0
  174. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1172-on-file-path.json +0 -0
  175. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1173-py-projection-order.json +0 -0
  176. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1184-win-rel-paths.json +0 -0
  177. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1185-win-abs-table-names.json +0 -0
  178. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1186-win-test-harness.json +0 -0
  179. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1196-join-index.json +0 -0
  180. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1199-glob-prefix.json +0 -0
  181. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1201-single-walk.json +0 -0
  182. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1204-embed-batch.json +0 -0
  183. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1207-win-argv-quote.json +0 -0
  184. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1208-win-nonverbatim-paths.json +0 -0
  185. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1215-on-file-batch.json +0 -0
  186. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1216-on-file-cleanup.json +0 -0
  187. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1223-config-glob-rule.json +0 -0
  188. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1223-dir-one-level.json +0 -0
  189. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1226-stale-docs.json +0 -0
  190. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1238-parallel-walk.json +0 -0
  191. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1241-content-prefetch.json +0 -0
  192. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1243-ingest-perf.json +0 -0
  193. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1249-dotfiles.json +0 -0
  194. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-1256-symlinks.json +0 -0
  195. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-819-oneshot-timeout.json +0 -0
  196. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-827-unquote-doubled-quotes.json +0 -0
  197. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-epic-953-slice2-reedline.json +0 -0
  198. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-epic-953-slice3-format.json +0 -0
  199. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-epic-953-stacked-prs-x59wm3.json +0 -0
  200. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-github-issue-825-e4mhhp.json +0 -0
  201. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-issue-951-0eease.json +0 -0
  202. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-issue-962-0jjrfv.json +0 -0
  203. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-issue-986-red-test-e7sjrb.json +0 -0
  204. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-tackle-1034-cachesplit.json +0 -0
  205. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-tackle-1042-py12.json +0 -0
  206. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-tackle-956-xzen74.json +0 -0
  207. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6-worker-calls.json +0 -0
  208. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-tackle-957-lrm0z6.json +0 -0
  209. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/e2e-attestations/claude-tackle-975-n8mc2h.json +0 -0
  210. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-07-13-drop-cwd-config-auto-detect.md +0 -0
  211. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-07-13-rename-extract-to-on-file.md +0 -0
  212. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-07-13-sdk-default-baked-in-config.md +0 -0
  213. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-07-20-drop-implicit-files-table.md +0 -0
  214. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-07-21-remove-glob-captures.md +0 -0
  215. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-07-24-hookless-table-config-error.md +0 -0
  216. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-07-24-remove-stat-fact-injection.md +0 -0
  217. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-07-29-restore-python-310.md +0 -0
  218. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-08-04-cli-in-process.md +0 -0
  219. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-08-20-declared-table-name.md +0 -0
  220. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-09-20-sigint-ends-a-run-in-progress.md +0 -0
  221. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-09-24-query-rows-in-projection-order.md +0 -0
  222. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-10-02-readme-docs-host.md +0 -0
  223. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-10-03-one-glob-rule-for-config-globs.md +0 -0
  224. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-10-03-path-table-directory-one-level.md +0 -0
  225. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-10-04-path-table-dotfiles-hidden.md +0 -0
  226. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/2026-10-05-path-table-symlinks.md +0 -0
  227. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/migrations.d/README.md +0 -0
  228. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/src/lib.rs +0 -0
  229. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/testing-conventions.toml +0 -0
  230. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/tests/__init__.py +0 -0
  231. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/tests/conftest.py +0 -0
  232. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/tests/e2e/__init__.py +0 -0
  233. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/__init__.py +0 -0
  234. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/tests/e2e/fixtures/dirsql_plugin_fixture/dirsql.toml +0 -0
  235. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/tests/e2e/speed_of_light.py +0 -0
  236. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/tests/integration/__init__.py +0 -0
  237. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/tests/integration/binding/__init__.py +0 -0
  238. {dirsql-0.4.67 → dirsql-0.4.68}/packages/python/tests/integration/hermetic/__init__.py +0 -0
  239. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/CHANGELOG.md +0 -0
  240. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/MIGRATIONS.md +0 -0
  241. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/README.md +0 -0
  242. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/benches/db_bench.rs +0 -0
  243. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/benches/differ_bench.rs +0 -0
  244. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/benches/matcher_bench.rs +0 -0
  245. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/benches/scanner_bench.rs +0 -0
  246. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/explanation.md +0 -0
  247. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/getting-started.md +0 -0
  248. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/columns-from-paths.md +0 -0
  249. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/define-tables.md +0 -0
  250. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/embed.md +0 -0
  251. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/extract-from-contents.md +0 -0
  252. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/load-extension.md +0 -0
  253. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/parse-files-into-columns.md +0 -0
  254. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/persist.md +0 -0
  255. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/query-json.md +0 -0
  256. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/query-without-config.md +0 -0
  257. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/react-to-changes.md +0 -0
  258. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/search-by-meaning.md +0 -0
  259. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/search-indexes.md +0 -0
  260. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/skip-files.md +0 -0
  261. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/howto/write-a-plugin.md +0 -0
  262. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/index.md +0 -0
  263. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/plugins.md +0 -0
  264. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/reference/columns.md +0 -0
  265. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/reference/config.md +0 -0
  266. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/reference/hooks.md +0 -0
  267. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/reference/http-api.md +0 -0
  268. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/docs/reference/sdk.md +0 -0
  269. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/bin/dirsql.rs +0 -0
  270. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/cli/execute.rs +0 -0
  271. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/cli/init.rs +0 -0
  272. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/cli/repl.rs +0 -0
  273. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/cli/router.rs +0 -0
  274. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/cli/serialize.rs +0 -0
  275. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/cli/server.rs +0 -0
  276. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/cli/table.rs +0 -0
  277. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/command.rs +0 -0
  278. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/config.rs +0 -0
  279. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/db.rs +0 -0
  280. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/default_config.toml +0 -0
  281. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/differ.rs +0 -0
  282. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/extension_resolution.rs +0 -0
  283. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/functions.rs +0 -0
  284. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/infer.rs +0 -0
  285. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/launcher.rs +0 -0
  286. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/lib.rs +0 -0
  287. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/matcher.rs +0 -0
  288. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/on_file.rs +0 -0
  289. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/parsed_vtab.rs +0 -0
  290. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/persist.rs +0 -0
  291. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/progress.rs +0 -0
  292. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/row_event_flat.rs +0 -0
  293. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/scanner.rs +0 -0
  294. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/sql_literal.rs +0 -0
  295. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/vtab.rs +0 -0
  296. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/vtab_scaffold.rs +0 -0
  297. {dirsql-0.4.67 → dirsql-0.4.68}/packages/rust/src/watcher.rs +0 -0
  298. {dirsql-0.4.67 → dirsql-0.4.68}/pyproject.toml +0 -0
@@ -552,7 +552,7 @@ checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
552
552
 
553
553
  [[package]]
554
554
  name = "dirsql"
555
- version = "0.4.67"
555
+ version = "0.4.68"
556
556
  dependencies = [
557
557
  "assert_cmd",
558
558
  "axum",
@@ -600,7 +600,7 @@ dependencies = [
600
600
 
601
601
  [[package]]
602
602
  name = "dirsql-py-ext"
603
- version = "0.4.67"
603
+ version = "0.4.68"
604
604
  dependencies = [
605
605
  "dirsql",
606
606
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.4.67
3
+ Version: 0.4.68
4
4
  Requires-Dist: bin-shim>=0.1
5
5
  Summary: Ephemeral SQL index over a local directory
6
6
  Keywords: sql,filesystem,directory,sqlite,index
@@ -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`` takes no
26
- config, so it is left untouched. Raises if a declared plugin is missing its
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] == "init":
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] == "init":
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,2 @@
1
+ # include_str! embeds these verbatim; a CRLF checkout would print a mixed-ending guide.
2
+ *.md text eol=lf
@@ -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.** `--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.** 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`.
@@ -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
@@ -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 |
@@ -108,7 +110,8 @@ Three other prefixes resolve, with their usual shell meanings:
108
110
  | `'../notes'` | relative to the index root's parent |
109
111
  | `'~/notes/*.md'` | relative to your home directory |
110
112
 
111
- A directory named this way is one level too; `'../notes/**'` descends.
113
+ A directory named this way is one level too; `'../notes/**'` descends. The
114
+ trailing-`/` rule holds here as well: `'~/*/'` is `'~/*/*'`.
112
115
  `..` is folded out textually, not followed through symlinks, so the directory
113
116
  scanned is a function of the string you wrote.
114
117
 
@@ -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.67"
7
+ version = "0.4.68"
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
+ **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,2 @@
1
+ # include_str! embeds these verbatim; a CRLF checkout would print a mixed-ending guide.
2
+ *.md text eol=lf
@@ -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.** `--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.** 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`.
@@ -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