dirsql 0.3.59__tar.gz → 0.3.61__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 (186) hide show
  1. {dirsql-0.3.59 → dirsql-0.3.61}/Cargo.lock +1 -1
  2. {dirsql-0.3.59 → dirsql-0.3.61}/PKG-INFO +1 -1
  3. dirsql-0.3.61/docs/.vitepress/config.ts +86 -0
  4. dirsql-0.3.61/docs/AGENTS.md +98 -0
  5. dirsql-0.3.61/docs/explanation.md +5 -0
  6. dirsql-0.3.61/docs/getting-started.md +257 -0
  7. dirsql-0.3.61/docs/howto/columns-from-paths.md +63 -0
  8. dirsql-0.3.61/docs/howto/define-tables.md +70 -0
  9. dirsql-0.3.61/docs/howto/embed.md +196 -0
  10. dirsql-0.3.61/docs/howto/extract-from-contents.md +90 -0
  11. dirsql-0.3.61/docs/howto/load-extension.md +91 -0
  12. dirsql-0.3.61/docs/howto/persist.md +52 -0
  13. dirsql-0.3.61/docs/howto/react-to-changes.md +67 -0
  14. dirsql-0.3.61/docs/howto/search-by-meaning.md +148 -0
  15. dirsql-0.3.61/docs/howto/skip-files.md +60 -0
  16. {dirsql-0.3.59 → dirsql-0.3.61}/docs/index.md +0 -1
  17. dirsql-0.3.61/docs/migrations.md +5 -0
  18. dirsql-0.3.61/docs/reference/cli.md +132 -0
  19. dirsql-0.3.61/docs/reference/columns.md +68 -0
  20. dirsql-0.3.61/docs/reference/config.md +166 -0
  21. dirsql-0.3.61/docs/reference/hooks.md +141 -0
  22. dirsql-0.3.61/docs/reference/http-api.md +120 -0
  23. dirsql-0.3.61/docs/reference/sdk.md +357 -0
  24. {dirsql-0.3.59 → dirsql-0.3.61}/docs/tests/integration/language-flag.spec.ts +4 -1
  25. dirsql-0.3.61/docs/tests/integration/sidebar.spec.ts +97 -0
  26. dirsql-0.3.61/docs/tests/unit/config.test.ts +102 -0
  27. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/Cargo.toml +1 -1
  28. dirsql-0.3.61/packages/python/docs/.vitepress/config.ts +86 -0
  29. dirsql-0.3.61/packages/python/docs/AGENTS.md +98 -0
  30. dirsql-0.3.61/packages/python/docs/explanation.md +5 -0
  31. dirsql-0.3.61/packages/python/docs/getting-started.md +257 -0
  32. dirsql-0.3.61/packages/python/docs/howto/columns-from-paths.md +63 -0
  33. dirsql-0.3.61/packages/python/docs/howto/define-tables.md +70 -0
  34. dirsql-0.3.61/packages/python/docs/howto/embed.md +196 -0
  35. dirsql-0.3.61/packages/python/docs/howto/extract-from-contents.md +90 -0
  36. dirsql-0.3.61/packages/python/docs/howto/load-extension.md +91 -0
  37. dirsql-0.3.61/packages/python/docs/howto/persist.md +52 -0
  38. dirsql-0.3.61/packages/python/docs/howto/react-to-changes.md +67 -0
  39. dirsql-0.3.61/packages/python/docs/howto/search-by-meaning.md +148 -0
  40. dirsql-0.3.61/packages/python/docs/howto/skip-files.md +60 -0
  41. {dirsql-0.3.59/packages/rust → dirsql-0.3.61/packages/python}/docs/index.md +0 -1
  42. dirsql-0.3.61/packages/python/docs/migrations.md +5 -0
  43. dirsql-0.3.61/packages/python/docs/reference/cli.md +132 -0
  44. dirsql-0.3.61/packages/python/docs/reference/columns.md +68 -0
  45. dirsql-0.3.61/packages/python/docs/reference/config.md +166 -0
  46. dirsql-0.3.61/packages/python/docs/reference/hooks.md +141 -0
  47. dirsql-0.3.61/packages/python/docs/reference/http-api.md +120 -0
  48. dirsql-0.3.61/packages/python/docs/reference/sdk.md +357 -0
  49. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/tests/integration/language-flag.spec.ts +4 -1
  50. dirsql-0.3.61/packages/python/docs/tests/integration/sidebar.spec.ts +97 -0
  51. dirsql-0.3.61/packages/python/docs/tests/unit/config.test.ts +102 -0
  52. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/e2e-attestation.json +2 -2
  53. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/Cargo.toml +1 -1
  54. dirsql-0.3.61/packages/rust/docs/explanation.md +5 -0
  55. dirsql-0.3.61/packages/rust/docs/getting-started.md +257 -0
  56. dirsql-0.3.61/packages/rust/docs/howto/columns-from-paths.md +63 -0
  57. dirsql-0.3.61/packages/rust/docs/howto/define-tables.md +70 -0
  58. dirsql-0.3.61/packages/rust/docs/howto/embed.md +196 -0
  59. dirsql-0.3.61/packages/rust/docs/howto/extract-from-contents.md +90 -0
  60. dirsql-0.3.61/packages/rust/docs/howto/load-extension.md +91 -0
  61. dirsql-0.3.61/packages/rust/docs/howto/persist.md +52 -0
  62. dirsql-0.3.61/packages/rust/docs/howto/react-to-changes.md +67 -0
  63. dirsql-0.3.61/packages/rust/docs/howto/search-by-meaning.md +148 -0
  64. dirsql-0.3.61/packages/rust/docs/howto/skip-files.md +60 -0
  65. {dirsql-0.3.59/packages/python → dirsql-0.3.61/packages/rust}/docs/index.md +0 -1
  66. dirsql-0.3.61/packages/rust/docs/migrations.md +5 -0
  67. dirsql-0.3.61/packages/rust/docs/reference/cli.md +132 -0
  68. dirsql-0.3.61/packages/rust/docs/reference/columns.md +68 -0
  69. dirsql-0.3.61/packages/rust/docs/reference/config.md +166 -0
  70. dirsql-0.3.61/packages/rust/docs/reference/hooks.md +141 -0
  71. dirsql-0.3.61/packages/rust/docs/reference/http-api.md +120 -0
  72. dirsql-0.3.61/packages/rust/docs/reference/sdk.md +357 -0
  73. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/db.rs +198 -371
  74. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/persist.rs +8 -7
  75. dirsql-0.3.59/docs/.vitepress/config.ts +0 -80
  76. dirsql-0.3.59/docs/AGENTS.md +0 -63
  77. dirsql-0.3.59/docs/api/index.md +0 -238
  78. dirsql-0.3.59/docs/cli/config.md +0 -435
  79. dirsql-0.3.59/docs/cli/http-api.md +0 -115
  80. dirsql-0.3.59/docs/cli/index.md +0 -75
  81. dirsql-0.3.59/docs/cli/init.md +0 -84
  82. dirsql-0.3.59/docs/cli/server.md +0 -60
  83. dirsql-0.3.59/docs/getting-started.md +0 -190
  84. dirsql-0.3.59/docs/guide/async.md +0 -268
  85. dirsql-0.3.59/docs/guide/crdt.md +0 -161
  86. dirsql-0.3.59/docs/guide/persistence.md +0 -177
  87. dirsql-0.3.59/docs/guide/querying.md +0 -221
  88. dirsql-0.3.59/docs/guide/tables.md +0 -269
  89. dirsql-0.3.59/docs/guide/watching.md +0 -273
  90. dirsql-0.3.59/docs/migrations.md +0 -8
  91. dirsql-0.3.59/docs/tests/integration/sidebar.spec.ts +0 -46
  92. dirsql-0.3.59/docs/tests/unit/config.test.ts +0 -49
  93. dirsql-0.3.59/packages/python/docs/.vitepress/config.ts +0 -80
  94. dirsql-0.3.59/packages/python/docs/AGENTS.md +0 -63
  95. dirsql-0.3.59/packages/python/docs/api/index.md +0 -238
  96. dirsql-0.3.59/packages/python/docs/cli/config.md +0 -435
  97. dirsql-0.3.59/packages/python/docs/cli/http-api.md +0 -115
  98. dirsql-0.3.59/packages/python/docs/cli/index.md +0 -75
  99. dirsql-0.3.59/packages/python/docs/cli/init.md +0 -84
  100. dirsql-0.3.59/packages/python/docs/cli/server.md +0 -60
  101. dirsql-0.3.59/packages/python/docs/getting-started.md +0 -190
  102. dirsql-0.3.59/packages/python/docs/guide/async.md +0 -268
  103. dirsql-0.3.59/packages/python/docs/guide/crdt.md +0 -161
  104. dirsql-0.3.59/packages/python/docs/guide/persistence.md +0 -177
  105. dirsql-0.3.59/packages/python/docs/guide/querying.md +0 -221
  106. dirsql-0.3.59/packages/python/docs/guide/tables.md +0 -269
  107. dirsql-0.3.59/packages/python/docs/guide/watching.md +0 -273
  108. dirsql-0.3.59/packages/python/docs/migrations.md +0 -8
  109. dirsql-0.3.59/packages/python/docs/tests/integration/sidebar.spec.ts +0 -46
  110. dirsql-0.3.59/packages/python/docs/tests/unit/config.test.ts +0 -49
  111. dirsql-0.3.59/packages/rust/docs/api/index.md +0 -238
  112. dirsql-0.3.59/packages/rust/docs/cli/config.md +0 -435
  113. dirsql-0.3.59/packages/rust/docs/cli/http-api.md +0 -115
  114. dirsql-0.3.59/packages/rust/docs/cli/index.md +0 -75
  115. dirsql-0.3.59/packages/rust/docs/cli/init.md +0 -84
  116. dirsql-0.3.59/packages/rust/docs/cli/server.md +0 -60
  117. dirsql-0.3.59/packages/rust/docs/getting-started.md +0 -190
  118. dirsql-0.3.59/packages/rust/docs/guide/async.md +0 -268
  119. dirsql-0.3.59/packages/rust/docs/guide/crdt.md +0 -161
  120. dirsql-0.3.59/packages/rust/docs/guide/persistence.md +0 -177
  121. dirsql-0.3.59/packages/rust/docs/guide/querying.md +0 -221
  122. dirsql-0.3.59/packages/rust/docs/guide/tables.md +0 -269
  123. dirsql-0.3.59/packages/rust/docs/guide/watching.md +0 -273
  124. dirsql-0.3.59/packages/rust/docs/migrations.md +0 -8
  125. {dirsql-0.3.59 → dirsql-0.3.61}/Cargo.toml +0 -0
  126. {dirsql-0.3.59 → dirsql-0.3.61}/README.md +0 -0
  127. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/__init__.py +0 -0
  128. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/_async.py +0 -0
  129. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/_dirsql.pyi +0 -0
  130. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/__init__.py +0 -0
  131. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/binary_path.py +0 -0
  132. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/interpret/__init__.py +0 -0
  133. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/is_windows.py +0 -0
  134. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/main.py +0 -0
  135. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/cli/resolve_config_extensions.py +0 -0
  136. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/py.typed +0 -0
  137. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/resolve_config_extensions.py +0 -0
  138. {dirsql-0.3.59 → dirsql-0.3.61}/dirsql/resolve_extension.py +0 -0
  139. {dirsql-0.3.59 → dirsql-0.3.61}/docs/.claude/CLAUDE.md +0 -0
  140. {dirsql-0.3.59 → dirsql-0.3.61}/docs/.vitepress/theme/index.ts +0 -0
  141. {dirsql-0.3.59 → dirsql-0.3.61}/docs/.vitepress/theme/lang.ts +0 -0
  142. {dirsql-0.3.59 → dirsql-0.3.61}/docs/package.json +0 -0
  143. {dirsql-0.3.59 → dirsql-0.3.61}/docs/playwright.config.ts +0 -0
  144. {dirsql-0.3.59 → dirsql-0.3.61}/docs/pnpm-lock.yaml +0 -0
  145. {dirsql-0.3.59 → dirsql-0.3.61}/docs/pnpm-workspace.yaml +0 -0
  146. {dirsql-0.3.59 → dirsql-0.3.61}/docs/tests/integration/home.spec.ts +0 -0
  147. {dirsql-0.3.59 → dirsql-0.3.61}/docs/tests/unit/lang.test.ts +0 -0
  148. {dirsql-0.3.59 → dirsql-0.3.61}/docs/vitest.config.ts +0 -0
  149. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/README.md +0 -0
  150. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/conftest.py +0 -0
  151. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/.claude/CLAUDE.md +0 -0
  152. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/.vitepress/theme/index.ts +0 -0
  153. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/.vitepress/theme/lang.ts +0 -0
  154. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/package.json +0 -0
  155. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/playwright.config.ts +0 -0
  156. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/pnpm-lock.yaml +0 -0
  157. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/pnpm-workspace.yaml +0 -0
  158. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/tests/integration/home.spec.ts +0 -0
  159. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/tests/unit/lang.test.ts +0 -0
  160. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/docs/vitest.config.ts +0 -0
  161. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/src/lib.rs +0 -0
  162. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/__init__.py +0 -0
  163. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/binding/__init__.py +0 -0
  164. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/conftest.py +0 -0
  165. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/e2e/__init__.py +0 -0
  166. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/integration/__init__.py +0 -0
  167. {dirsql-0.3.59 → dirsql-0.3.61}/packages/python/tests/smoke/__init__.py +0 -0
  168. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/README.md +0 -0
  169. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/benches/db_bench.rs +0 -0
  170. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/benches/differ_bench.rs +0 -0
  171. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/benches/matcher_bench.rs +0 -0
  172. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/benches/scanner_bench.rs +0 -0
  173. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/bin/dirsql.rs +0 -0
  174. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/cli/init.rs +0 -0
  175. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/cli/mod.rs +0 -0
  176. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/cli/router.rs +0 -0
  177. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/cli/serialize.rs +0 -0
  178. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/cli/server.rs +0 -0
  179. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/command.rs +0 -0
  180. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/config.rs +0 -0
  181. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/differ.rs +0 -0
  182. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/lib.rs +0 -0
  183. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/matcher.rs +0 -0
  184. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/scanner.rs +0 -0
  185. {dirsql-0.3.59 → dirsql-0.3.61}/packages/rust/src/watcher.rs +0 -0
  186. {dirsql-0.3.59 → dirsql-0.3.61}/pyproject.toml +0 -0
@@ -500,7 +500,7 @@ dependencies = [
500
500
 
501
501
  [[package]]
502
502
  name = "dirsql-py-ext"
503
- version = "0.3.59"
503
+ version = "0.3.61"
504
504
  dependencies = [
505
505
  "dirsql",
506
506
  "pyo3",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dirsql
3
- Version: 0.3.59
3
+ Version: 0.3.61
4
4
  Requires-Dist: pytest>=8 ; extra == 'dev'
5
5
  Requires-Dist: pytest-describe>=2 ; extra == 'dev'
6
6
  Requires-Dist: pytest-asyncio>=0.23 ; extra == 'dev'
@@ -0,0 +1,86 @@
1
+ import { defineConfig } from 'vitepress'
2
+
3
+ export default defineConfig({
4
+ title: 'dirsql',
5
+ description: 'Ephemeral SQL index over a local directory. Watches a filesystem, ingests structured files into an in-memory SQLite database, and exposes a SQL query interface.',
6
+ base: '/dirsql/',
7
+
8
+ themeConfig: {
9
+ search: {
10
+ provider: 'local'
11
+ },
12
+
13
+ // The nav mirrors the four Diataxis groups exactly (#353/#387). Type is
14
+ // the only organizational axis -- no product-area tabs (the old `CLI`
15
+ // tab is gone).
16
+ nav: [
17
+ { text: 'Tutorial', link: '/getting-started' },
18
+ { text: 'How-to Guides', link: '/howto/define-tables' },
19
+ { text: 'Reference', link: '/reference/cli' },
20
+ { text: 'Explanation', link: '/explanation' },
21
+ { text: 'GitHub', link: 'https://github.com/thekevinscott/dirsql' }
22
+ ],
23
+
24
+ // A single global sidebar shown on every page, mirroring the four
25
+ // Diataxis groups. There is intentionally no path-scoped (e.g.
26
+ // `/howto/`) key: a path-scoped sidebar swaps the whole tree out, which
27
+ // deletes the other sections when you enter one (see #301). Keep one
28
+ // sidebar.
29
+ sidebar: {
30
+ '/': [
31
+ {
32
+ text: 'Tutorial',
33
+ items: [
34
+ { text: 'Your first dirsql database', link: '/getting-started' }
35
+ ]
36
+ },
37
+ {
38
+ text: 'How-to Guides',
39
+ items: [
40
+ { text: 'Define tables for your files', link: '/howto/define-tables' },
41
+ { text: 'Derive columns from file paths', link: '/howto/columns-from-paths' },
42
+ { text: 'Extract rows from file contents', link: '/howto/extract-from-contents' },
43
+ { text: 'Search documents by meaning', link: '/howto/search-by-meaning' },
44
+ { text: "Skip files you don't want indexed", link: '/howto/skip-files' },
45
+ { text: 'Load a SQLite extension', link: '/howto/load-extension' },
46
+ { text: 'Keep the index across restarts', link: '/howto/persist' },
47
+ { text: 'React to file changes', link: '/howto/react-to-changes' },
48
+ { text: 'Embed dirsql in your application', link: '/howto/embed' }
49
+ ]
50
+ },
51
+ {
52
+ text: 'Reference',
53
+ items: [
54
+ { text: 'CLI', link: '/reference/cli' },
55
+ { text: 'Configuration File', link: '/reference/config' },
56
+ { text: 'Command Hooks', link: '/reference/hooks' },
57
+ { text: 'Virtual Columns & Glob Captures', link: '/reference/columns' },
58
+ { text: 'HTTP API', link: '/reference/http-api' },
59
+ { text: 'SDK', link: '/reference/sdk' },
60
+ { text: 'Migrations', link: '/migrations' }
61
+ ]
62
+ },
63
+ {
64
+ text: 'Explanation',
65
+ items: [
66
+ { text: 'How dirsql thinks', link: '/explanation' }
67
+ ]
68
+ }
69
+ ]
70
+ },
71
+
72
+ outline: {
73
+ level: [2, 3],
74
+ label: 'On this page'
75
+ },
76
+
77
+ socialLinks: [
78
+ { icon: 'github', link: 'https://github.com/thekevinscott/dirsql' }
79
+ ],
80
+
81
+ footer: {
82
+ message: 'Released under the MIT License.',
83
+ copyright: 'Copyright 2024-present'
84
+ }
85
+ }
86
+ })
@@ -0,0 +1,98 @@
1
+ # Documentation Development
2
+
3
+ Instructions for agents working on `dirsql` documentation.
4
+
5
+ ## Stack
6
+
7
+ The docs site uses [VitePress](https://vitepress.dev/). Source files are in `docs/` at the project root.
8
+
9
+ ## Running locally
10
+
11
+ ```bash
12
+ cd docs
13
+ pnpm install
14
+ pnpm dev
15
+ ```
16
+
17
+ This starts a local dev server (default: `http://localhost:5173/dirsql/`). The site hot-reloads on file changes.
18
+
19
+ ## Building
20
+
21
+ ```bash
22
+ cd docs
23
+ pnpm build
24
+ ```
25
+
26
+ The build must succeed before pushing. VitePress will fail on broken links, missing assets, and syntax errors in markdown.
27
+
28
+ ## Testing changes
29
+
30
+ Before pushing any docs changes:
31
+
32
+ 1. Run `pnpm build` in `docs/` and confirm it exits cleanly
33
+ 2. Spot-check the built output with `pnpm preview`
34
+ 3. Verify sidebar navigation, code blocks, and internal links render correctly
35
+
36
+ ## Structure
37
+
38
+ The docs follow the [Diataxis](https://diataxis.fr/) framework. **Type is
39
+ the only organizational axis** -- there are no product-area sections (no
40
+ "CLI" section; #353). The nav and the sidebar mirror the four types exactly.
41
+
42
+ The **primary reader is the CLI user**: someone with a directory of files,
43
+ one command (`uvx` / `npx dirsql`), and a `.dirsql.toml`. The SDKs are the
44
+ secondary audience and appear **only in Reference**, plus the single
45
+ "Embed `dirsql` in your application" how-to.
46
+
47
+ Target tree (the spec for #353; existing pages are *quarried* into it, not
48
+ migrated -- a page survives only if a slot wants its content):
49
+
50
+ - **Tutorial** (`getting-started.md`) -- one lesson: *Your first dirsql
51
+ database*. The reader performs every step and sees output at each one;
52
+ success is author-guaranteed (toy dataset, no branching).
53
+ - **How-to Guides** (`howto/`) -- goal-named recipes: define tables for your files;
54
+ derive columns from file paths; extract rows from file contents
55
+ (`on-file`); search documents by meaning; skip files; load a SQLite
56
+ extension; keep the index across restarts; react to file changes; embed
57
+ `dirsql` in an application.
58
+ - **Reference** (`reference/`) -- CLI flags and defaults; the complete
59
+ `.dirsql.toml` schema; the command hook contract (placeholders, stdout
60
+ protocol, exit codes, timeouts); virtual columns and glob captures; the
61
+ HTTP API; the SDK page (`reference/sdk.md`, one page with
62
+ Python/TypeScript/Rust code-groups -- the sole SDK home); plus the
63
+ Migrations include (`migrations.md`).
64
+ - **Explanation** (`explanation.md`) -- one page: how `dirsql` thinks (the
65
+ filesystem is the source of truth; the database is a derived, ephemeral,
66
+ read-only view; reconcile and diffing). Its canonical home is the root
67
+ `ARCHITECTURE.md`;
68
+ #374 surfaces it via an include page, the same mechanism
69
+ `docs/migrations.md` uses for `MIGRATIONS.md`. Edit the root file, never
70
+ a rendered include.
71
+
72
+ Working rules:
73
+
74
+ - **Facts live once, in Reference.** Tutorials and how-tos link to reference
75
+ material; they never re-list constructor parameters or duplicate API tables.
76
+ - **A how-to opens with a 1-2 line goal/motivation statement.** Deep
77
+ rationale (tradeoffs, alternatives considered, theory) moves to Explanation
78
+ only when it is substantial enough to stand alone and is reused across
79
+ pages. Do not manufacture stub pages for a paragraph of "why".
80
+ - **Tutorial vs how-to:** a tutorial is a lesson along a path the author
81
+ guarantees; a how-to serves a competent reader pursuing their own goal.
82
+ - **One global sidebar.** Never add a path-scoped sidebar key -- it swaps
83
+ out the whole tree and hides every other section while inside one (#301;
84
+ see the comment above `sidebar` in `config.ts`).
85
+
86
+ ## Conventions
87
+
88
+ - **Lead with the use case.** Open each feature description with *why* a
89
+ reader would reach for it before *how* it works. Don't frame a feature
90
+ by what an adjacent feature can't do.
91
+ *Don't:* "Persistence avoids the thing the default mode can't do..."
92
+ *Do:* "Persistence keeps the SQLite index on disk between runs so large
93
+ directories don't re-scan on every startup."
94
+ - Wrap `dirsql` in backticks in all prose text
95
+ - Use VitePress [code group](https://vitepress.dev/guide/markdown#code-groups) syntax (`::: code-group`) for multi-language examples with `Python`, `Rust`, and `TypeScript` tabs
96
+ - Internal links use relative paths (e.g., `./howto/define-tables.md`)
97
+ - The VitePress config is at `docs/.vitepress/config.ts`
98
+ - The site is deployed under the `/dirsql/` base path
@@ -0,0 +1,5 @@
1
+ ---
2
+ title: How dirsql thinks
3
+ ---
4
+
5
+ <!--@include: ../ARCHITECTURE.md-->
@@ -0,0 +1,257 @@
1
+ # Your first dirsql database
2
+
3
+ In this tutorial you will turn a directory of three tiny markdown files into
4
+ a SQL database you can query over HTTP — without writing any code. You will:
5
+
6
+ 1. Create the directory and files.
7
+ 2. Start `dirsql` with zero configuration and query it with `curl`.
8
+ 3. Define your own table in a `.dirsql.toml` and query the new shape.
9
+
10
+ It takes about five minutes.
11
+
12
+ **You need:** a terminal with `curl` and [`jq`](https://jqlang.org/), and
13
+ Node ≥ 20.11 (for `npx`). Every `npx dirsql` step below also has a `uvx`
14
+ tab that behaves identically, if you prefer Python tooling
15
+ ([`uv`](https://docs.astral.sh/uv/)).
16
+
17
+ ## 1. Create three files
18
+
19
+ Make a working directory with two subfolders — one per note author:
20
+
21
+ ```bash
22
+ mkdir -p my-notes/notes/alice my-notes/notes/bob
23
+ cd my-notes
24
+ ```
25
+
26
+ Create the three notes by pasting each block exactly as shown:
27
+
28
+ ```bash
29
+ cat > notes/alice/welcome.md <<'EOF'
30
+ # Welcome
31
+
32
+ Start here. This folder is about to become a database.
33
+ EOF
34
+ ```
35
+
36
+ ```bash
37
+ cat > notes/alice/ideas.md <<'EOF'
38
+ # Ideas
39
+
40
+ - query files with SQL
41
+ - watch for changes
42
+ EOF
43
+ ```
44
+
45
+ ```bash
46
+ cat > notes/bob/reading-list.md <<'EOF'
47
+ # Reading list
48
+
49
+ - The SQLite file format
50
+ EOF
51
+ ```
52
+
53
+ Check that all three files are in place:
54
+
55
+ ```bash
56
+ find notes -type f | sort
57
+ ```
58
+
59
+ ```
60
+ notes/alice/ideas.md
61
+ notes/alice/welcome.md
62
+ notes/bob/reading-list.md
63
+ ```
64
+
65
+ ## 2. Start the server
66
+
67
+ From inside `my-notes`, start `dirsql`:
68
+
69
+ ::: code-group
70
+
71
+ ```bash [npm]
72
+ npx dirsql
73
+ ```
74
+
75
+ ```bash [PyPI]
76
+ uvx dirsql
77
+ ```
78
+
79
+ :::
80
+
81
+ The first run downloads the package (`npx` asks for confirmation — answer
82
+ `y`; `uvx` prints download progress), then the server starts:
83
+
84
+ ```
85
+ Running at localhost:7117
86
+ ```
87
+
88
+ That one command scanned the directory, built an in-memory SQLite database
89
+ with one row per file, and started an HTTP server. Leave it running and
90
+ open a **second terminal** for the next step.
91
+
92
+ ## 3. Query your files
93
+
94
+ You gave `dirsql` no configuration, so it serves a single default table
95
+ named `files` ([zero-config mode](./reference/cli.md#zero-config-mode)).
96
+ Ask it how many rows it has:
97
+
98
+ ```bash
99
+ curl -s http://localhost:7117/query \
100
+ -H 'content-type: application/json' \
101
+ -d '{"sql":"SELECT COUNT(*) AS files FROM files"}'
102
+ ```
103
+
104
+ ```
105
+ [{"files":3}]
106
+ ```
107
+
108
+ Three files, three rows. The response is always a JSON array of row
109
+ objects ([HTTP API](./reference/http-api.md)) — from here on we pipe it
110
+ through `jq` to pretty-print. Now select some columns:
111
+
112
+ ```bash
113
+ curl -s http://localhost:7117/query \
114
+ -H 'content-type: application/json' \
115
+ -d '{"sql":"SELECT _path, _size FROM files ORDER BY _path"}' \
116
+ | jq
117
+ ```
118
+
119
+ ```json
120
+ [
121
+ {
122
+ "_path": "notes/alice/ideas.md",
123
+ "_size": 52
124
+ },
125
+ {
126
+ "_path": "notes/alice/welcome.md",
127
+ "_size": 66
128
+ },
129
+ {
130
+ "_path": "notes/bob/reading-list.md",
131
+ "_size": 41
132
+ }
133
+ ]
134
+ ```
135
+
136
+ `_path` and `_size` are two of the built-in file columns `dirsql` collects
137
+ for every file — see [virtual columns](./reference/columns.md#virtual-columns)
138
+ for the full list. (The `_size` values are byte counts; they match the
139
+ output above because you pasted the files exactly.)
140
+
141
+ You have a working SQL database over your files. Next, teach it the
142
+ structure your folders already encode.
143
+
144
+ ## 4. Define a table
145
+
146
+ Look at the paths again: `notes/alice/ideas.md`, `notes/bob/reading-list.md`
147
+ — the author's name is a directory segment. A config file can capture it as
148
+ a real column.
149
+
150
+ In your second terminal, still inside `my-notes`, create a `.dirsql.toml`:
151
+
152
+ ```bash
153
+ cat > .dirsql.toml <<'EOF'
154
+ [[table]]
155
+ ddl = "CREATE TABLE notes (author TEXT, _basename TEXT, _size INTEGER)"
156
+ glob = "notes/{author}/*.md"
157
+ EOF
158
+ ```
159
+
160
+ Two keys define the table:
161
+
162
+ - `glob` selects which files feed the table, and `{author}` is a
163
+ [glob capture](./reference/columns.md#glob-captures): whatever directory
164
+ name matches that segment becomes the row's `author` value.
165
+ - `ddl` is ordinary `CREATE TABLE` SQL naming the columns you want to keep.
166
+
167
+ ## 5. Restart and query the new shape
168
+
169
+ Config is read at startup, so go back to the **first terminal**, stop the
170
+ server with `Ctrl-C`, and start it again:
171
+
172
+ ::: code-group
173
+
174
+ ```bash [npm]
175
+ npx dirsql
176
+ ```
177
+
178
+ ```bash [PyPI]
179
+ uvx dirsql
180
+ ```
181
+
182
+ :::
183
+
184
+ ```
185
+ Running at localhost:7117
186
+ ```
187
+
188
+ This time `dirsql` found your `.dirsql.toml` and served the `notes` table
189
+ you defined instead of the default `files` table. Query it from the second
190
+ terminal:
191
+
192
+ ```bash
193
+ curl -s http://localhost:7117/query \
194
+ -H 'content-type: application/json' \
195
+ -d '{"sql":"SELECT author, _basename, _size FROM notes ORDER BY author, _basename"}' \
196
+ | jq
197
+ ```
198
+
199
+ ```json
200
+ [
201
+ {
202
+ "_basename": "ideas.md",
203
+ "_size": 52,
204
+ "author": "alice"
205
+ },
206
+ {
207
+ "_basename": "welcome.md",
208
+ "_size": 66,
209
+ "author": "alice"
210
+ },
211
+ {
212
+ "_basename": "reading-list.md",
213
+ "_size": 41,
214
+ "author": "bob"
215
+ }
216
+ ]
217
+ ```
218
+
219
+ Every row now carries an `author` column extracted from its path — no
220
+ extraction code, just a glob. And it is a real SQL column, so you can
221
+ aggregate on it:
222
+
223
+ ```bash
224
+ curl -s http://localhost:7117/query \
225
+ -H 'content-type: application/json' \
226
+ -d '{"sql":"SELECT author, COUNT(*) AS notes FROM notes GROUP BY author"}' \
227
+ | jq
228
+ ```
229
+
230
+ ```json
231
+ [
232
+ {
233
+ "author": "alice",
234
+ "notes": 2
235
+ },
236
+ {
237
+ "author": "bob",
238
+ "notes": 1
239
+ }
240
+ ]
241
+ ```
242
+
243
+ That's the whole loop: files in a directory, a declarative table on top,
244
+ SQL over HTTP.
245
+
246
+ ## Where to go next
247
+
248
+ - [Configuration file](./reference/config.md) — the complete `.dirsql.toml`
249
+ reference: more tables, ignore patterns, persistence, hooks.
250
+ - [CLI](./reference/cli.md) — flags like `--port` and `--config`, plus
251
+ `dirsql init`.
252
+ - [HTTP API](./reference/http-api.md) — `POST /query` in full, plus
253
+ `GET /events`, a live stream of row changes as files change.
254
+ - [SDK](./reference/sdk.md) — embed `dirsql` in a Python, Rust, or
255
+ TypeScript program instead of running the server.
256
+ - Why is the database rebuilt from your files on every startup? See
257
+ [how `dirsql` thinks](./explanation.md).
@@ -0,0 +1,63 @@
1
+ # Derive columns from file paths
2
+
3
+ Directory layouts often encode real data — an author, a year, a thread ID —
4
+ as path segments. A `{name}` capture in a table's glob turns such a segment
5
+ into a queryable column, no extraction code required.
6
+
7
+ ## 1. Name the segment in the glob
8
+
9
+ Suppose photos are filed by year and month:
10
+
11
+ ```
12
+ photos/2024/05/beach.jpg
13
+ photos/2024/11/hike.jpg
14
+ photos/2025/01/snow.jpg
15
+ ```
16
+
17
+ Capture both directory levels in `.dirsql.toml`:
18
+
19
+ ```toml
20
+ [[table]]
21
+ ddl = "CREATE TABLE photos (year TEXT, month TEXT, _basename TEXT)"
22
+ glob = "photos/{year}/{month}/*.jpg"
23
+ ```
24
+
25
+ A capture only populates a column when the DDL declares one with the same
26
+ name — here `year` and `month`. The capture rules (valid names, matching
27
+ within one path segment) are in
28
+ [glob captures](../reference/columns.md#glob-captures).
29
+
30
+ ## 2. Query the captured columns
31
+
32
+ Start the server (`npx dirsql` / `uvx dirsql`) and query:
33
+
34
+ ```bash
35
+ curl -s http://localhost:7117/query \
36
+ -H 'content-type: application/json' \
37
+ -d '{"sql":"SELECT year, month, _basename FROM photos ORDER BY year, month"}'
38
+ ```
39
+
40
+ ```json
41
+ [{"_basename":"beach.jpg","month":"05","year":"2024"},{"_basename":"hike.jpg","month":"11","year":"2024"},{"_basename":"snow.jpg","month":"01","year":"2025"}]
42
+ ```
43
+
44
+ Captures are real SQL columns, so aggregation works:
45
+
46
+ ```bash
47
+ curl -s http://localhost:7117/query \
48
+ -H 'content-type: application/json' \
49
+ -d '{"sql":"SELECT year, COUNT(*) AS photos FROM photos GROUP BY year"}'
50
+ ```
51
+
52
+ ```json
53
+ [{"photos":2,"year":"2024"},{"photos":1,"year":"2025"}]
54
+ ```
55
+
56
+ ## Going further
57
+
58
+ - Captures combine freely with [virtual columns](../reference/columns.md#virtual-columns)
59
+ (`_basename` above) — both are filesystem facts merged onto every row.
60
+ - The [tutorial](../getting-started.md) walks the same idea with an
61
+ `{author}` capture, starting from zero.
62
+ - When the value you need lives inside the file rather than in its path,
63
+ see [Extract rows from file contents](./extract-from-contents.md).
@@ -0,0 +1,70 @@
1
+ # Define tables for your files
2
+
3
+ Map a glob of files to a named SQL table so you query exactly the files you
4
+ care about, with exactly the columns you care about — instead of the
5
+ catch-all `files` table that [zero-config mode](../reference/cli.md#zero-config-mode)
6
+ serves.
7
+
8
+ ## 1. Create a config next to your files
9
+
10
+ Suppose your blog posts live under `posts/`, one markdown file each. In the
11
+ directory you want to index, create a `.dirsql.toml` with one
12
+ [`[[table]]`](../reference/config.md#table) entry:
13
+
14
+ ```toml
15
+ [[table]]
16
+ ddl = "CREATE TABLE posts (_path TEXT, _size INTEGER, _mtime INTEGER)"
17
+ glob = "posts/**/*.md"
18
+ ```
19
+
20
+ - `glob` selects the files: every `.md` under `posts/`, at any depth,
21
+ relative to the directory containing the config.
22
+ - `ddl` is a plain SQLite `CREATE TABLE` naming the columns you want. Here
23
+ all three are [virtual columns](../reference/columns.md#virtual-columns) —
24
+ filesystem facts `dirsql` computes for every file. Facts are opt-in by
25
+ DDL: only the ones you declare become columns.
26
+
27
+ ## 2. Start the server and query
28
+
29
+ ::: code-group
30
+
31
+ ```bash [npm]
32
+ npx dirsql
33
+ ```
34
+
35
+ ```bash [PyPI]
36
+ uvx dirsql
37
+ ```
38
+
39
+ :::
40
+
41
+ Each matched file is one row:
42
+
43
+ ```bash
44
+ curl -s http://localhost:7117/query \
45
+ -H 'content-type: application/json' \
46
+ -d '{"sql":"SELECT _path, _size FROM posts ORDER BY _path"}'
47
+ ```
48
+
49
+ ```json
50
+ [{"_path":"posts/2024/hello.md","_size":21},{"_path":"posts/2025/again.md","_size":55}]
51
+ ```
52
+
53
+ Files that don't match the glob (a `README.txt` next to `posts/`, say) are
54
+ simply not in the table. Once a config file exists, it fully replaces the
55
+ zero-config default — only the tables you define are served.
56
+
57
+ ## Multiple tables
58
+
59
+ Add one `[[table]]` entry per table. When a file matches several globs, the
60
+ first matching table wins — see [`[[table]]`](../reference/config.md#table)
61
+ for that and the remaining keys (`strict`, `on-file`).
62
+
63
+ ## Going further
64
+
65
+ - Your directory layout encodes data (authors, dates, IDs)? Capture path
66
+ segments as columns — [Derive columns from file paths](./columns-from-paths.md).
67
+ - Need columns from *inside* the files? A plain table never reads file
68
+ contents — [Extract rows from file contents](./extract-from-contents.md).
69
+ - Why one row per file, rebuilt from disk? See
70
+ [how `dirsql` thinks](../explanation.md).