@dikolab/kbdb 0.4.3 → 0.6.0

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 (224) hide show
  1. package/CLA.md +68 -0
  2. package/LICENSE +676 -12
  3. package/LICENSING.md +58 -0
  4. package/README.md +50 -27
  5. package/README.md.bak +320 -0
  6. package/dist/README.md +320 -0
  7. package/dist/{chunk-BJXEVALU.mjs → chunk-QLJ33C74.mjs} +44 -44
  8. package/dist/chunk-QLJ33C74.mjs.map +7 -0
  9. package/dist/cli.cjs +550 -232
  10. package/dist/cli.cjs.map +4 -4
  11. package/dist/cli.d.ts +0 -8
  12. package/dist/cli.mjs +483 -154
  13. package/dist/cli.mjs.map +4 -4
  14. package/dist/kbdb-worker.cjs +36 -5
  15. package/dist/kbdb-worker.cjs.map +3 -3
  16. package/dist/mod.cjs +89 -30
  17. package/dist/mod.cjs.map +4 -4
  18. package/dist/mod.mjs +88 -30
  19. package/dist/mod.mjs.map +4 -4
  20. package/dist/src/cli.d.ts +0 -8
  21. package/dist/src/shared/cli/constants/defaults.constant.d.ts +1 -1
  22. package/dist/src/shared/cli/constants/recfile-command-field-map.constant.d.ts +8 -0
  23. package/dist/src/shared/cli/constants/recfile-field-maps.constant.d.ts +21 -0
  24. package/dist/src/shared/cli/functions/compute-directory-level.function.d.ts +14 -0
  25. package/dist/src/shared/cli/functions/dispatch-command.function.d.ts +2 -28
  26. package/dist/src/shared/cli/functions/format-command-output.function.d.ts +14 -0
  27. package/dist/src/shared/cli/functions/format-db-not-found.function.d.ts +20 -0
  28. package/dist/src/shared/cli/functions/format-output.function.d.ts +1 -0
  29. package/dist/src/shared/cli/functions/format-recfile-output.function.d.ts +11 -0
  30. package/dist/src/shared/cli/functions/render-recfile-value.function.d.ts +11 -0
  31. package/dist/src/shared/cli/functions/resolve-db-dir.function.d.ts +24 -0
  32. package/dist/src/shared/cli/functions/resolve-recfile-key.function.d.ts +9 -0
  33. package/dist/src/shared/cli/functions/run-db-path.function.d.ts +10 -0
  34. package/dist/src/shared/cli/functions/run-export.function.d.ts +8 -4
  35. package/dist/src/shared/cli/functions/run-import.function.d.ts +4 -0
  36. package/dist/src/shared/cli/functions/run-learn.function.d.ts +12 -0
  37. package/dist/src/shared/cli/index.d.ts +4 -1
  38. package/dist/src/shared/cli/typings/cli-options.interface.d.ts +9 -2
  39. package/dist/src/shared/cli/typings/db-resolution.interface.d.ts +9 -0
  40. package/dist/src/shared/cli/typings/recfile-field-map.type.d.ts +10 -0
  41. package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
  42. package/dist/src/shared/wasm-codec/functions/decode-option-u8.function.d.ts +9 -0
  43. package/dist/src/shared/wasm-codec/functions/decode-section-records.function.d.ts +4 -0
  44. package/dist/src/shared/wasm-codec/functions/encode-add-section-params.function.d.ts +2 -45
  45. package/dist/src/shared/wasm-codec/functions/encode-update-section-params.function.d.ts +10 -1
  46. package/dist/src/shared/wasm-codec/index.d.ts +1 -1
  47. package/dist/src/shared/wasm-codec/typings/add-section-input.model.d.ts +6 -0
  48. package/dist/src/shared/wasm-codec/typings/section-record-trailing.model.d.ts +5 -0
  49. package/dist/src/shared/wasm-codec/typings/section-record.model.d.ts +5 -0
  50. package/dist/src/shared/worker-client/functions/build-deno-permissions.function.d.ts +11 -0
  51. package/dist/src/shared/worker-client/functions/read-crash-reason.function.d.ts +9 -0
  52. package/dist/src/shared/worker-client/functions/resolve-spawn-script.function.d.ts +6 -0
  53. package/dist/src/shared/worker-client/functions/spawn-daemon.function.d.ts +1 -1
  54. package/dist/src/shared/worker-client/typings/section.model.d.ts +5 -0
  55. package/dist/src/shared/worker-client/typings/worker-client-options.interface.d.ts +0 -6
  56. package/dist/src/shared/worker-daemon/functions/count-files.function.d.ts +12 -0
  57. package/dist/src/shared/worker-daemon/functions/handle-import.function.d.ts +2 -0
  58. package/dist/src/shared/worker-daemon/functions/handle-read-ops.function.d.ts +8 -0
  59. package/dist/src/shared/worker-daemon/functions/validate-daemon-path.function.d.ts +15 -0
  60. package/dist/src/worker.d.ts +0 -7
  61. package/dist/wasm/default-embedding/kbdb_default_embedding_bg.wasm +0 -0
  62. package/dist/wasm/default-embedding/package.json +1 -1
  63. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  64. package/dist/wasm/fs-database/package.json +1 -1
  65. package/dist/wasm/fs-migration/kbdb_fs_migration_bg.wasm +0 -0
  66. package/dist/wasm/fs-migration/package.json +1 -1
  67. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  68. package/dist/wasm/kb-worker/package.json +1 -1
  69. package/dist/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
  70. package/dist/wasm/query-parser/package.json +1 -1
  71. package/dist/worker.d.ts +0 -7
  72. package/dist/worker.mjs +37 -6
  73. package/dist/worker.mjs.map +3 -3
  74. package/package.json +13 -12
  75. package/dist/chunk-BJXEVALU.mjs.map +0 -7
  76. package/dist/src/shared/cli/functions/resolve-raw-db-path.function.d.ts +0 -10
  77. package/docs/details/README.md +0 -30
  78. package/docs/details/agent-tooling.md +0 -132
  79. package/docs/details/cli.md +0 -777
  80. package/docs/details/knowledge-base.md +0 -180
  81. package/docs/details/library-api.md +0 -495
  82. package/docs/details/mcp-server.md +0 -482
  83. package/docs/details/search-and-ranking.md +0 -575
  84. package/docs/details/storage.md +0 -531
  85. package/docs/goals/agents.md +0 -751
  86. package/docs/goals/architecture.svg +0 -198
  87. package/docs/goals/auto-capture.md +0 -378
  88. package/docs/goals/benchmarking.md +0 -296
  89. package/docs/goals/cli.md +0 -2654
  90. package/docs/goals/concurrency.md +0 -259
  91. package/docs/goals/content-composer.md +0 -609
  92. package/docs/goals/content-parser.md +0 -279
  93. package/docs/goals/database.md +0 -1679
  94. package/docs/goals/document.md +0 -368
  95. package/docs/goals/hybrid-search.md +0 -465
  96. package/docs/goals/mcp.md +0 -1541
  97. package/docs/goals/overview.md +0 -124
  98. package/docs/goals/query-parser.md +0 -373
  99. package/docs/goals/query-result.md +0 -860
  100. package/docs/goals/semantic-dedup.md +0 -233
  101. package/docs/goals/skills.md +0 -810
  102. package/docs/goals/sync.md +0 -217
  103. package/docs/goals/worker-client.md +0 -1005
  104. package/docs/goals/worker-daemon.md +0 -1547
  105. package/docs/modules/overview.md +0 -319
  106. package/docs/modules/rust/embedding/module.md +0 -91
  107. package/docs/modules/rust/fs-database/functions/document.md +0 -48
  108. package/docs/modules/rust/fs-database/functions/integrity.md +0 -79
  109. package/docs/modules/rust/fs-database/functions/io.md +0 -87
  110. package/docs/modules/rust/fs-database/functions/module.md +0 -22
  111. package/docs/modules/rust/fs-database/functions/query-exec.md +0 -44
  112. package/docs/modules/rust/fs-database/functions/section.md +0 -76
  113. package/docs/modules/rust/fs-database/indexes/btree.md +0 -35
  114. package/docs/modules/rust/fs-database/indexes/corpus.md +0 -61
  115. package/docs/modules/rust/fs-database/indexes/inverted.md +0 -60
  116. package/docs/modules/rust/fs-database/indexes/module.md +0 -64
  117. package/docs/modules/rust/fs-database/indexes/positional.md +0 -39
  118. package/docs/modules/rust/fs-database/indexes/vectors.md +0 -110
  119. package/docs/modules/rust/fs-database/module.md +0 -150
  120. package/docs/modules/rust/fs-database/types/catalog.md +0 -53
  121. package/docs/modules/rust/fs-database/types/module.md +0 -12
  122. package/docs/modules/rust/fs-database/types/section.md +0 -127
  123. package/docs/modules/rust/kb-worker/functions/compose.md +0 -57
  124. package/docs/modules/rust/kb-worker/functions/module.md +0 -20
  125. package/docs/modules/rust/kb-worker/functions/retrieve.md +0 -194
  126. package/docs/modules/rust/kb-worker/functions/search.md +0 -173
  127. package/docs/modules/rust/kb-worker/functions/write.md +0 -172
  128. package/docs/modules/rust/kb-worker/module.md +0 -171
  129. package/docs/modules/rust/kb-worker/types/cache.md +0 -90
  130. package/docs/modules/rust/kb-worker/types/context.md +0 -26
  131. package/docs/modules/rust/kb-worker/types/module.md +0 -16
  132. package/docs/modules/rust/kb-worker/types/status.md +0 -29
  133. package/docs/modules/rust/kb-worker/types/token.md +0 -50
  134. package/docs/modules/rust/overview.md +0 -531
  135. package/docs/modules/rust/query-parser/functions/extract.md +0 -56
  136. package/docs/modules/rust/query-parser/functions/module.md +0 -18
  137. package/docs/modules/rust/query-parser/functions/parse.md +0 -33
  138. package/docs/modules/rust/query-parser/functions/pipeline.md +0 -9
  139. package/docs/modules/rust/query-parser/functions/rank.md +0 -85
  140. package/docs/modules/rust/query-parser/module.md +0 -131
  141. package/docs/modules/rust/query-parser/types/cache.md +0 -39
  142. package/docs/modules/rust/query-parser/types/keyphrase.md +0 -71
  143. package/docs/modules/rust/query-parser/types/module.md +0 -18
  144. package/docs/modules/rust/query-parser/types/token.md +0 -46
  145. package/docs/modules/rust/shared/content-composer/functions.md +0 -114
  146. package/docs/modules/rust/shared/content-composer/module.md +0 -147
  147. package/docs/modules/rust/shared/content-composer/types.md +0 -93
  148. package/docs/modules/rust/shared/content-parser/functions.md +0 -72
  149. package/docs/modules/rust/shared/content-parser/module.md +0 -99
  150. package/docs/modules/rust/shared/content-parser/types.md +0 -71
  151. package/docs/modules/rust/shared/corpus/module.md +0 -24
  152. package/docs/modules/rust/shared/corpus/types.md +0 -141
  153. package/docs/modules/rust/shared/document/module.md +0 -25
  154. package/docs/modules/rust/shared/document/types.md +0 -154
  155. package/docs/modules/rust/shared/encode/module.md +0 -22
  156. package/docs/modules/rust/shared/encode/traits.md +0 -304
  157. package/docs/modules/rust/shared/error/module.md +0 -28
  158. package/docs/modules/rust/shared/error/types.md +0 -302
  159. package/docs/modules/rust/shared/kbid/module.md +0 -24
  160. package/docs/modules/rust/shared/kbid/types.md +0 -147
  161. package/docs/modules/rust/shared/memory/functions.md +0 -209
  162. package/docs/modules/rust/shared/memory/module.md +0 -24
  163. package/docs/modules/rust/shared/module.md +0 -196
  164. package/docs/modules/rust/shared/pipeline/functions.md +0 -141
  165. package/docs/modules/rust/shared/pipeline/module.md +0 -62
  166. package/docs/modules/rust/shared/pipeline/types.md +0 -43
  167. package/docs/modules/rust/shared/query/module.md +0 -27
  168. package/docs/modules/rust/shared/query/types.md +0 -236
  169. package/docs/modules/rust/shared/section/module.md +0 -25
  170. package/docs/modules/rust/shared/section/types.md +0 -294
  171. package/docs/modules/rust/shared/term/module.md +0 -25
  172. package/docs/modules/rust/shared/term/types.md +0 -139
  173. package/docs/modules/typescript/cli.md +0 -131
  174. package/docs/modules/typescript/kbdb-worker.md +0 -150
  175. package/docs/modules/typescript/overview.md +0 -400
  176. package/docs/modules/typescript/shared/auto-capture/module.md +0 -73
  177. package/docs/modules/typescript/shared/cli/constants.md +0 -23
  178. package/docs/modules/typescript/shared/cli/functions.md +0 -809
  179. package/docs/modules/typescript/shared/cli/module.md +0 -138
  180. package/docs/modules/typescript/shared/cli/typings.md +0 -197
  181. package/docs/modules/typescript/shared/embedding/functions.md +0 -200
  182. package/docs/modules/typescript/shared/embedding/module.md +0 -77
  183. package/docs/modules/typescript/shared/embedding/typings.md +0 -124
  184. package/docs/modules/typescript/shared/hash/functions.md +0 -20
  185. package/docs/modules/typescript/shared/hash/module.md +0 -21
  186. package/docs/modules/typescript/shared/log/constants.md +0 -82
  187. package/docs/modules/typescript/shared/log/functions.md +0 -131
  188. package/docs/modules/typescript/shared/log/module.md +0 -153
  189. package/docs/modules/typescript/shared/log/typings.md +0 -82
  190. package/docs/modules/typescript/shared/mcp/classes.md +0 -179
  191. package/docs/modules/typescript/shared/mcp/functions.md +0 -386
  192. package/docs/modules/typescript/shared/mcp/module.md +0 -160
  193. package/docs/modules/typescript/shared/mcp/typings.md +0 -529
  194. package/docs/modules/typescript/shared/module.md +0 -110
  195. package/docs/modules/typescript/shared/platform/functions.md +0 -42
  196. package/docs/modules/typescript/shared/platform/module.md +0 -25
  197. package/docs/modules/typescript/shared/runtime/functions.md +0 -26
  198. package/docs/modules/typescript/shared/runtime/module.md +0 -27
  199. package/docs/modules/typescript/shared/runtime/typings.md +0 -13
  200. package/docs/modules/typescript/shared/version/module.md +0 -27
  201. package/docs/modules/typescript/shared/wasm-codec/functions.md +0 -391
  202. package/docs/modules/typescript/shared/wasm-codec/module.md +0 -98
  203. package/docs/modules/typescript/shared/worker-client/classes.md +0 -264
  204. package/docs/modules/typescript/shared/worker-client/functions.md +0 -175
  205. package/docs/modules/typescript/shared/worker-client/module.md +0 -92
  206. package/docs/modules/typescript/shared/worker-client/typings.md +0 -511
  207. package/docs/modules/typescript/shared/worker-daemon/classes.md +0 -239
  208. package/docs/modules/typescript/shared/worker-daemon/constants.md +0 -37
  209. package/docs/modules/typescript/shared/worker-daemon/functions.md +0 -234
  210. package/docs/modules/typescript/shared/worker-daemon/module.md +0 -118
  211. package/docs/modules/typescript/shared/worker-daemon/typings.md +0 -132
  212. package/docs/overview.md +0 -191
  213. package/docs/release-notes/0.1.0.md +0 -189
  214. package/docs/release-notes/0.1.1.md +0 -46
  215. package/docs/release-notes/0.1.2.md +0 -38
  216. package/docs/release-notes/0.1.3.md +0 -42
  217. package/docs/release-notes/0.2.0.md +0 -147
  218. package/docs/release-notes/0.3.0.md +0 -89
  219. package/docs/release-notes/0.3.1.md +0 -121
  220. package/docs/release-notes/0.3.2.md +0 -64
  221. package/docs/release-notes/0.4.0.md +0 -80
  222. package/docs/release-notes/0.4.1.md +0 -149
  223. package/docs/release-notes/0.4.3.md +0 -60
  224. package/docs/release-notes/README.md +0 -13
package/docs/goals/cli.md DELETED
@@ -1,2654 +0,0 @@
1
- # CLI -- The kbdb Command
2
-
3
- *A globally installed command that manages knowledge
4
- base entries in CLI mode and serves as an MCP server
5
- for AI agents in MCP mode.*
6
-
7
- ## Goal
8
-
9
- The `kbdb` executable is a Deno or Node.js command
10
- that operates in two run modes:
11
-
12
- 1. **CLI mode** (default) -- Short-lived commands for
13
- content management and search.
14
- 2. **MCP mode** (`kbdb mcp`) -- Long-lived MCP server
15
- for AI agent integration.
16
-
17
- The run mode is determined by the first argument. If
18
- the first argument is `mcp`, the executable starts in
19
- MCP mode (see [MCP](mcp.md)). Otherwise, it runs in
20
- CLI mode.
21
-
22
- In CLI mode, the executable is a thin pass-through.
23
- It parses command-line arguments, creates a worker
24
- client (see [Worker Client](worker-client.md)),
25
- delegates all computation to the daemon, prints
26
- results to stdout, and prints errors to stderr. The
27
- CLI does not perform keyword extraction, indexing,
28
- ranking, or database I/O itself -- the daemon and its
29
- WASM modules handle all of it.
30
-
31
- ## Installation
32
-
33
- - **Node.js**: `npm install -g @dikolab/kbdb`
34
- - **Deno**: `deno install` or `deno add @dikolab/kbdb`
35
- (via [jsr.io](https://jsr.io))
36
-
37
- After installation, the `kbdb` command is available
38
- globally in the user's shell.
39
-
40
- ## Synopsis
41
-
42
- ```
43
- kbdb [options]
44
- kbdb <command> [options] ...[parameters]
45
- kbdb <command> <subcommand> [options] ...[parameters]
46
- ```
47
-
48
- All commands and their canonical forms:
49
-
50
- ```
51
- kbdb --help | -h
52
- kbdb --version
53
- kbdb -v <command> (verbose: warnings)
54
- kbdb -vv <command> (verbose: info)
55
- kbdb -vvv <command> (verbose: debug)
56
- kbdb learn [options] <path | ->...
57
- kbdb unlearn [options] <kbid>...
58
- kbdb search [options] <query>...
59
- kbdb recall [options] <kbid>...
60
- kbdb content [options] <id>...
61
- kbdb mcp [options]
62
- kbdb check [options]
63
- kbdb gc [options]
64
- kbdb rebuild [options]
65
- kbdb status [options]
66
- kbdb export [options] [<path>]
67
- kbdb worker stop [options]
68
- kbdb worker restart [options]
69
- kbdb db init [options]
70
- kbdb db migrate [options]
71
- kbdb skill learn [options] --name <n> --body <file|->
72
- kbdb skill list [options]
73
- kbdb skill get [options] <name-or-kbid>
74
- kbdb skill delete [options] <kbid>
75
- kbdb agent create [options] --name <n>
76
- --persona <file|-> --skills <kbid,...>
77
- kbdb agent list [options]
78
- kbdb agent get [options] <docid>
79
- kbdb agent delete [options] <docid>
80
- ```
81
-
82
- The help manual shows `[options]` immediately after
83
- the command or subcommand to emphasise the canonical
84
- form. The parser accepts options at any position in
85
- the command line.
86
-
87
- ## Run Modes
88
-
89
- The `kbdb` executable inspects its first argument to
90
- determine the run mode:
91
-
92
- ```
93
- kbdb mcp [--db <path>] -> MCP server mode
94
- kbdb <command> [options] -> CLI mode (default)
95
- ```
96
-
97
- ### CLI Mode
98
-
99
- All commands except `mcp` run in CLI mode. The
100
- executable parses arguments, delegates to the worker
101
- daemon via the worker client module, prints results,
102
- and exits. Each invocation is a short-lived process.
103
-
104
- ### MCP Mode
105
-
106
- When the first argument is `mcp`, the executable
107
- starts as a long-lived MCP server. It communicates
108
- with the AI agent host over stdio using JSON-RPC 2.0,
109
- and delegates all operations to the worker daemon via
110
- the same worker client module.
111
-
112
- MCP mode accepts `--db <path>` or the `KBDB_DB_DIR`
113
- environment variable. When neither is set, it falls
114
- back to the current working directory.
115
-
116
- See [MCP](mcp.md) for the full MCP mode
117
- specification.
118
-
119
- ## Global Options
120
-
121
- These options apply to all commands.
122
-
123
- | Option | Short | Description |
124
- |--------------------|-------|--------------------------|
125
- | `--help` | `-h` | Print help text and exit |
126
- | `--version` | | Print version and exit |
127
- | `--verbose` | `-v` | Set log level to WARNING (errors + warnings) |
128
- | `--verbose-info` | `-vv` | Set log level to INFO |
129
- | `--verbose-debug` | `-vvv`| Set log level to DEBUG (all messages) |
130
- | `--db <path>` | | Database directory path (optional) |
131
- | `--format <fmt>` | `-f` | Output format (json default; text when stdout is a TTY) |
132
- | `--timeout-ms <ms>`| | Request timeout in ms |
133
- | `--retry <n>` | | Max retries on timeout |
134
- | `--non-interactive` | | Suppress prompts; use defaults |
135
-
136
- ### `--help`, `-h`
137
-
138
- Print the help text and exit immediately. No database
139
- connection is made.
140
-
141
- ```
142
- kbdb --help
143
- kbdb -h
144
- ```
145
-
146
- When no command is given (`kbdb` with no arguments),
147
- the help text is printed as the default behaviour.
148
-
149
- ### `--version`
150
-
151
- Print the package version string and exit. No database
152
- connection is made.
153
-
154
- ```
155
- kbdb --version
156
- ```
157
-
158
- ### `--verbose`, `-v` / `-vv` / `-vvv`
159
-
160
- Increase log verbosity on stderr. Each additional `v`
161
- raises the level by one step.
162
-
163
- ```
164
- kbdb -v <command> # WARNING: errors + warnings
165
- kbdb -vv <command> # INFO: errors, warnings, info
166
- kbdb -vvv <command> # DEBUG: all messages
167
- ```
168
-
169
- The default level is ERROR. The `KBDB_LOG_LEVEL`
170
- environment variable sets the base level; CLI flags
171
- override it. Log lines are prefixed with per-level
172
- icons (✖⚠ℹ▸) and ANSI colors.
173
-
174
- ### `--db <path>`
175
-
176
- Set the path to the directory that contains (or will
177
- contain) the `.kbdb` database folder. The database
178
- directory is always `${path}/.kbdb`.
179
-
180
- ```
181
- kbdb search "query" --db /path/to/project
182
- ```
183
-
184
- When omitted:
185
- - **CLI mode**: falls back to the `KBDB_DB_DIR`
186
- environment variable when `--db` is omitted,
187
- then to the current working directory
188
- (`process.cwd()`).
189
- - **MCP mode**: falls back to the `KBDB_DB_DIR`
190
- environment variable, then to the current
191
- working directory.
192
-
193
- ## Commands
194
-
195
- ### `learn` -- import documents
196
-
197
- ```
198
- kbdb learn [options] <path | ->...
199
- ```
200
-
201
- Import and index documents into the knowledge base.
202
-
203
- **Arguments:**
204
- - `<path | ->...` -- one or more file paths, directory
205
- paths, or `-` for stdin. When a path is a directory,
206
- it is scanned recursively for supported **text**
207
- files only (`.md`, `.txt`, `.rst`, `.adoc`). Dotfiles
208
- and dot-directories are skipped at every level.
209
- Unsupported extensions are silently skipped. Multiple
210
- paths can be specified. When a path is `-`, content
211
- is read from stdin until EOF and ingested as a text
212
- section. The `-` argument can appear alongside
213
- file/directory paths. Stdin is consumed once -- if
214
- `-` appears multiple times, only the first reads
215
- stdin. Subsequent `-` arguments are silently ignored.
216
-
217
- **Options:**
218
- - `--title <title>` -- Section title. Optional for all
219
- section types. Applies to all sections ingested in
220
- this invocation.
221
- - `--description <desc>` -- Section description.
222
- Optional for all section types. Applies to all
223
- sections ingested in this invocation.
224
- - `--docid <docid>` -- Attach imported section(s)
225
- to this document ID. If the document does not
226
- exist, it is created. Applies to all sections
227
- ingested in this invocation.
228
- - `--tags <t,...>` -- Comma-separated tags for scoping
229
- and filtering. Applies to all sections ingested in
230
- this invocation. Example: `--tags auth,api,v2`.
231
- - `--replace` -- Enable supersession. When set, the
232
- system matches each incoming section by source key
233
- (source path + heading). If an existing section has
234
- the same source key, it is superseded: the old
235
- section's document references are transferred to the
236
- new one and the old section becomes eligible for GC.
237
- Without this flag, re-learning edited content creates
238
- a sibling rather than replacing the original.
239
-
240
- **Supported file extensions:**
241
-
242
- | Extension | Directory Scan |
243
- |-----------|----------------|
244
- | `.md` | yes |
245
- | `.txt` | yes |
246
- | `.rst` | yes |
247
- | `.adoc` | yes |
248
-
249
- Extensions are defined in
250
- `src/shared/cli/constants/defaults.constant.ts` as
251
- `SUPPORTED_EXTENSIONS`. Unsupported extensions are
252
- silently skipped. Image files are not supported.
253
-
254
- **Behaviour:**
255
-
256
- The `learn` command collects files from each argument:
257
-
258
- 1. **Directory path** -- Recursive scan picks up
259
- supported text files (`.md`, `.txt`, `.rst`,
260
- `.adoc`). Dotfiles and dot-directories are skipped
261
- at every level.
262
- 2. **Text file path** -- Reads the file as UTF-8. If
263
- the extension is not in `SUPPORTED_EXTENSIONS`, the
264
- file is silently skipped.
265
- 3. **Stdin (`-`)** -- Reads text content from stdin
266
- until EOF. Stdin is consumed only once regardless of
267
- how many `-` arguments appear.
268
-
269
- Each collected file is ingested by calling
270
- `client.addSection()`. The `docid`, `title`, and
271
- `description` options from the CLI apply to all
272
- sections in the same invocation.
273
-
274
- **Output:**
275
- - **stdout**: JSON array of `LearnResult` objects:
276
- ```json
277
- [
278
- {
279
- "kbid": "abcdef1234567890abcdef1234",
280
- "path": "/absolute/path/to/file.md",
281
- "size": 1234,
282
- "skipped": false,
283
- "superseded": null,
284
- "warnings": [],
285
- "near_duplicates": []
286
- }
287
- ]
288
- ```
289
- For stdin input, `path` is `"-"`. The `size` field
290
- is the UTF-8 character count of the content. The
291
- `skipped` field is always `false` for results that
292
- appear in the array -- files that are skipped produce
293
- no entry. `superseded` is the kbid of the section
294
- that was replaced via `--replace` (null when no
295
- supersession occurred). `warnings` is an array of
296
- warning strings (e.g. `"heading_missing"` when no
297
- title is provided). `near_duplicates` lists sections
298
- with similarity >= 0.85 as `{kbid, similarity}`.
299
- - **stderr**: errors only.
300
-
301
- **Exit code:** `0` on success, `1` on error.
302
-
303
- **Delegation chain:**
304
- ```
305
- src/cli.ts parseArgs()
306
- -> findDb() / promptUser() / runDbInit()
307
- -> createWorkerClient({ contextPath })
308
- -> versionGate(client, dbDir)
309
- -> dispatchCommand(client, options)
310
- -> runLearn(client, options, io?)
311
- -> client.addSection({
312
- sectionType, content,
313
- title?, description?, docid? })
314
- -> IPC -> worker daemon
315
- -> kb-worker.wasm
316
- -> query-parser.wasm (tokenize)
317
- -> fs-database.wasm (store + index)
318
- ```
319
-
320
- ### `unlearn` -- remove sections
321
-
322
- ```
323
- kbdb unlearn [options] <kbid>...
324
- ```
325
-
326
- Remove knowledge base sections by their kb-id.
327
-
328
- **Arguments:**
329
- - `<kbid>...` -- one or more 26-character kb-id
330
- strings (or unique prefixes -- kbdb resolves
331
- short prefixes to full identifiers, similar to
332
- git short hashes). Each is processed
333
- independently.
334
-
335
- **Behaviour:**
336
- - The engine removes the referenced content and
337
- cascades the deletion to associated index entries
338
- and ranking data.
339
- - If a kb-id does not exist, the result shows
340
- `"removed": false` rather than throwing an error.
341
-
342
- **Output:**
343
- - **stdout**: JSON array of `UnlearnResult` objects:
344
- ```json
345
- [
346
- {
347
- "kbid": "abcdef1234567890abcdef1234",
348
- "removed": true
349
- }
350
- ]
351
- ```
352
- - **stderr**: errors only.
353
-
354
- **Exit code:** `0` on success, `1` on error.
355
-
356
- **Delegation chain:**
357
- ```
358
- src/cli.ts parseArgs()
359
- -> findDb() / promptUser() / runDbInit()
360
- -> createWorkerClient({ contextPath })
361
- -> versionGate(client, dbDir)
362
- -> dispatchCommand(client, options)
363
- -> runUnlearn(client, options)
364
- -> client.removeSection(kbid)
365
- -> IPC -> worker daemon
366
- -> kb-worker.wasm
367
- -> fs-database.wasm
368
- (delete + re-index)
369
- ```
370
-
371
- ### `search` -- query the knowledge base
372
-
373
- ```
374
- kbdb search [options] <query>...
375
- ```
376
-
377
- Search the knowledge base by keywords or phrases.
378
-
379
- **Arguments:**
380
- - `<query>...` -- one or more query terms. All terms
381
- are joined with spaces into a single query string.
382
- Returns an empty result set if no terms are given.
383
-
384
- **Search options:**
385
-
386
- | Option | Short | Default | Description |
387
- |------------------|-------|------------|--------------------|
388
- | `--mode <mode>` | `-m` | `sections` | Result granularity |
389
- | `--limit <n>` | `-l` | `20` | Max results |
390
- | `--offset <n>` | `-o` | `0` | Result offset |
391
- | `--format <fmt>` | `-f` | `json` | Output format |
392
- | `--content` | `-c` | | Hydrate previews |
393
- | `--algo <algo>` | | `lexical` | Search algorithm |
394
- | `--db <path>` | | cwd | Database directory |
395
-
396
- #### `--mode`, `-m`
397
-
398
- Controls the granularity of search results.
399
-
400
- | Mode | Description |
401
- |-------------|--------------------------------------|
402
- | `sections` | Individual matching sections (default). |
403
- | `documents` | Complete documents containing matches. |
404
- | `stats` | Index statistics and result counts. |
405
-
406
- ```
407
- kbdb search "machine learning" --mode documents
408
- kbdb search "API endpoint" -m stats
409
- ```
410
-
411
- #### `--limit`, `-l`
412
-
413
- Maximum number of results to return. Must be a
414
- positive integer. Non-numeric values fall back to the
415
- default (20).
416
-
417
- ```
418
- kbdb search "query" --limit 50
419
- kbdb search "query" -l 5
420
- ```
421
-
422
- #### `--offset`, `-o`
423
-
424
- Zero-based offset into the ranked result set. Used
425
- for pagination alongside `--limit`. Must be a
426
- non-negative integer. Non-numeric values fall back
427
- to the default (0).
428
-
429
- ```
430
- kbdb search "query" --offset 20
431
- kbdb search "query" -o 40 -l 20
432
- ```
433
-
434
- #### `--format`, `-f`
435
-
436
- Controls the output format printed to stdout.
437
-
438
- | Format | Description |
439
- |--------|-----------------------------------------|
440
- | `json` | Pretty-printed JSON array (default when stdout is piped). |
441
- | `text` | Numbered human-readable list with scores and matched terms (default when stdout is a TTY). |
442
- | `mcp` | JSON envelope for MCP protocol consumers. |
443
-
444
- ```
445
- kbdb search "query" --format text
446
- kbdb search "query" -f mcp
447
- ```
448
-
449
- #### `--content`, `-c`
450
-
451
- When specified, hydrates each result's `preview` field
452
- with the actual section content fetched from the
453
- worker daemon via `client.content()`. Without this
454
- flag, `preview` is an empty string.
455
-
456
- ```
457
- kbdb search "query" --content
458
- kbdb search "query" -c
459
- ```
460
-
461
- Failures to fetch content for individual results are
462
- suppressed -- the result is still returned with an
463
- empty `preview`.
464
-
465
- **Output shape:**
466
-
467
- All search output is formatted from a `SearchDisplay[]`
468
- array (see [SearchDisplay type](#searchdisplay-type)).
469
-
470
- `--format json` (default):
471
- ```json
472
- {
473
- "items": [
474
- {
475
- "kbid": "abcdef1234567890abcdef1234",
476
- "heading": "Machine Learning Basics",
477
- "type": "text/markdown",
478
- "docids": ["doc-intro-ml"],
479
- "score": 8.7432,
480
- "confidence": 1.0,
481
- "snippet": "Machine learning is a subfield...",
482
- "matched_terms": ["machine", "learning"],
483
- "matched_fields": ["heading", "body"],
484
- "created_at": "2026-06-15T10:00:00Z",
485
- "preview": ""
486
- }
487
- ],
488
- "total": 42,
489
- "offset": 0,
490
- "limit": 20,
491
- "has_more": true,
492
- "relaxed": false
493
- }
494
- ```
495
-
496
- When `--content` is used, `preview` contains the
497
- section text:
498
- ```json
499
- {
500
- "items": [
501
- {
502
- "kbid": "abcdef1234567890abcdef1234",
503
- "heading": "Machine Learning Basics",
504
- "type": "text/markdown",
505
- "docids": ["doc-intro-ml"],
506
- "score": 8.7432,
507
- "confidence": 1.0,
508
- "snippet": "Machine learning is a subfield...",
509
- "matched_terms": ["machine", "learning"],
510
- "matched_fields": ["heading", "body"],
511
- "created_at": "2026-06-15T10:00:00Z",
512
- "preview": "Machine learning is a subfield..."
513
- }
514
- ],
515
- "total": 42,
516
- "offset": 0,
517
- "limit": 20,
518
- "has_more": true,
519
- "relaxed": false
520
- }
521
- ```
522
-
523
- `--format text`:
524
- ```
525
- 1. [abcdef1234567890abcdef1234] (score: 8.7432)
526
- Machine Learning Basics [text/markdown]
527
- Machine learning is a subfield...
528
- matches: machine, learning
529
-
530
- 2. [fedcba9876543210fedcba9876] (score: 6.1200)
531
- Neural Networks [text/markdown]
532
- Neural networks are computing systems...
533
- matches: machine
534
-
535
- Showing 1-20 of 42 results
536
- ```
537
-
538
- When `--content` is also used, each entry includes
539
- the preview text between the kbid line and the
540
- matches line.
541
-
542
- `--format mcp`:
543
- ```json
544
- {
545
- "type": "text",
546
- "text": "[abcdef...] score=8.7432 — ..."
547
- }
548
- ```
549
-
550
- **Exit code:** `0` on success, `1` on error.
551
-
552
- **Delegation chain:**
553
- ```
554
- src/cli.ts parseArgs()
555
- -> findDb() / promptUser() / runDbInit()
556
- -> createWorkerClient({ contextPath })
557
- -> versionGate(client, dbDir)
558
- -> dispatchCommand(client, options)
559
- -> runSearch(client, options)
560
- -> client.search({
561
- query, mode, limit, offset })
562
- -> IPC -> worker daemon
563
- -> kb-worker.wasm
564
- -> query-parser.wasm
565
- (parse query)
566
- -> fs-database.wasm
567
- (index lookup)
568
- -> query-parser.wasm
569
- (rank results)
570
- -> hydrateSearchPreviews(client, results)
571
- (only when options.content === true)
572
- -> formatOutput(results, options.format)
573
- -> stdout
574
- ```
575
-
576
- ### `content` -- compose rendered document
577
-
578
- ```
579
- kbdb content [options] <id>...
580
- ```
581
-
582
- Compose a rendered Markdown document from one or
583
- more knowledge base identifiers and output it to
584
- stdout.
585
-
586
- **Arguments:**
587
- - `<id>...` -- one or more kbid or docid identifiers
588
- (or unique prefixes -- kbdb resolves short
589
- prefixes to full identifiers, similar to git
590
- short hashes).
591
-
592
- **Output:**
593
- - **stdout**: JSON envelope containing the composed
594
- Markdown text:
595
- ```json
596
- {
597
- "type": "text/markdown",
598
- "data": "# Rendered Markdown\n\nContent here...",
599
- "total": 42
600
- }
601
- ```
602
- - **stderr**: errors only.
603
-
604
- **Exit code:** `0` on success, `1` on error.
605
-
606
- **Delegation chain:**
607
- ```
608
- src/cli.ts parseArgs()
609
- -> findDb() / promptUser() / runDbInit()
610
- -> createWorkerClient({ contextPath })
611
- -> versionGate(client, dbDir)
612
- -> dispatchCommand(client, options)
613
- -> runContent(client, options)
614
- -> client.content(ids)
615
- -> IPC -> worker daemon
616
- -> kb-worker.wasm
617
- -> fs-database.wasm (fetch)
618
- ```
619
-
620
- See [Content Composer](content-composer.md) for the
621
- full composition specification.
622
-
623
- ### `recall` -- progressive context retrieval
624
-
625
- ```
626
- kbdb recall [options] <kbid>...
627
- ```
628
-
629
- Retrieve full content and progressive context for one
630
- or more sections by kbid. Use after `search` to drill
631
- into relevant results. Returns section text, metadata,
632
- references, and back-references at configurable
633
- expansion depths.
634
-
635
- **Arguments:**
636
- - `<kbid>...` -- one or more 26-character kb-id
637
- strings (or unique prefixes -- kbdb resolves
638
- short prefixes to full identifiers, similar to
639
- git short hashes).
640
-
641
- **Options:**
642
-
643
- | Flag | Alias | Description |
644
- |-----------------|-------|--------------------------------|
645
- | `--depth <n>` | `-d` | Expansion depth (0--3, |
646
- | | | default: 0, clamped to 3) |
647
- | `--db <path>` | | Database directory path |
648
-
649
- **Expansion levels:**
650
-
651
- | Depth | Returns |
652
- |-------|---------------------------------------|
653
- | 0 | Full section content with heading, |
654
- | | type, and docids. |
655
- | 1 | Depth-0 content, plus parent document |
656
- | | manifests (title, all section kbids |
657
- | | with headings and types) for each |
658
- | | docid, plus back-references (sections |
659
- | | that reference this section, from the |
660
- | | reference graph index, each with |
661
- | | marker_type and context_snippet). |
662
- | 2 | Depth-1 content, plus full text of |
663
- | | sibling sections (other sections in |
664
- | | the same documents), plus forward |
665
- | | references from the section's own |
666
- | | content markers. |
667
- | 3 | Depth-2 content, plus full text of |
668
- | | referenced sections (one level deep), |
669
- | | plus their back-references. |
670
-
671
- Depth values above 3 are clamped to 3.
672
-
673
- **Output:**
674
- - **stdout**: JSON `RecallResult` object (single kbid)
675
- or `RecallResult[]` array (multiple kbids).
676
-
677
- Single result shape (depth 0):
678
-
679
- ```json
680
- {
681
- "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3",
682
- "heading": "Architecture Overview",
683
- "type": "text/markdown",
684
- "content": "Full section text...",
685
- "docids": ["doc-5678"]
686
- }
687
- ```
688
-
689
- Single result shape (depth 1+):
690
-
691
- ```json
692
- {
693
- "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3",
694
- "heading": "Architecture Overview",
695
- "type": "text/markdown",
696
- "content": "Full section text...",
697
- "docids": ["doc-5678"],
698
- "documents": [
699
- {
700
- "docid": "doc-5678",
701
- "title": "System Architecture",
702
- "sections": [
703
- {
704
- "kbid": "...",
705
- "heading": "...",
706
- "type": "..."
707
- }
708
- ]
709
- }
710
- ],
711
- "back_references": [
712
- {
713
- "kbid": "ref-section-kbid",
714
- "heading": "Related Section",
715
- "type": "text/markdown",
716
- "marker_type": "link",
717
- "context_snippet": "For details, see ...",
718
- "direction": "back"
719
- }
720
- ],
721
- "siblings": [ ... ],
722
- "references": [ ... ]
723
- }
724
- ```
725
-
726
- Fields beyond `content` and `docids` are present only
727
- at the corresponding depth level. At depth 0,
728
- `documents`, `back_references`, `siblings`, and
729
- `references` are absent. At depth 1, `siblings` and
730
- `references` are absent. And so on.
731
-
732
- - **stderr**: errors only.
733
-
734
- **Exit code:** `0` on success, `1` on error.
735
-
736
- **Delegation chain:**
737
- ```
738
- src/cli.ts parseArgs()
739
- -> findDb() / promptUser() / runDbInit()
740
- -> createWorkerClient({ contextPath })
741
- -> versionGate(client, dbDir)
742
- -> dispatchCommand(client, options)
743
- -> runRecall(client, options)
744
- -> client.recall({ kbids, depth })
745
- -> IPC -> worker daemon
746
- -> kb-worker.wasm
747
- -> fs-database.wasm (fetch)
748
- ```
749
-
750
- ### `mcp` -- start MCP server
751
-
752
- ```
753
- kbdb mcp [options]
754
- ```
755
-
756
- Start a long-lived MCP server on stdio.
757
-
758
- **Behaviour:**
759
- - Communicates with the AI agent host over stdio
760
- using JSON-RPC 2.0.
761
- - Accepts `--db <path>` or the `KBDB_DB_DIR`
762
- environment variable. Falls back to the current
763
- working directory when neither is set.
764
- - Runs a version gate before starting: exits with an
765
- error if the database needs migration or is too new.
766
- - The MCP server does not prompt, does not print
767
- banners, and does not write to stdout except for
768
- JSON-RPC responses.
769
- - Runs until the host closes the stdio stream or sends
770
- a shutdown signal.
771
-
772
- **Environment variables:**
773
- - `KBDB_DB_DIR` -- fallback database directory path
774
- when `--db` is not specified.
775
-
776
- **Exit code:** `0` on clean shutdown, `1` on error.
777
-
778
- See [MCP](mcp.md) for the full specification of
779
- tools, resources, and protocol details.
780
-
781
- **Delegation chain:**
782
- ```
783
- src/cli.ts parseArgs()
784
- -> findDb(rawDbPath)
785
- -> createWorkerClient({ contextPath: dbDir })
786
- -> versionGate(client, dbDir)
787
- -> deps.startMcpServer(dbDir)
788
- (stdio JSON-RPC 2.0 loop)
789
- ```
790
-
791
- ### CLI vs MCP tool coverage
792
-
793
- The MCP server exposes `retrieve` (section/document
794
- lookup by ID) and `status` (database metadata) tools
795
- that have no CLI equivalents. These are programmatic
796
- operations suited to MCP clients (AI agents). CLI
797
- users use `kbdb search` to find content,
798
- `kbdb recall` to expand context progressively, and
799
- `kbdb content` to compose documents by ID.
800
-
801
- ### `check` -- integrity check
802
-
803
- ```
804
- kbdb check [options]
805
- ```
806
-
807
- Verify the integrity of the database. Checks section
808
- file checksums, document manifest references, type
809
- consistency, and divergent content (sections sharing
810
- the same source key with different content).
811
-
812
- **Output:**
813
- - **stdout**: JSON integrity report:
814
- ```json
815
- {
816
- "ok": false,
817
- "errors": [
818
- {
819
- "type": "orphan_section",
820
- "entity": "x9y8z7w6v5u4t3s2r1q0p9o8n7",
821
- "detail": "Section not referenced by any document"
822
- }
823
- ]
824
- }
825
- ```
826
- When all checks pass, `ok` is `true` and `errors`
827
- is empty.
828
- - **stderr**: errors only.
829
-
830
- **Exit code:** `0` when `ok` is `true`, `1` when
831
- errors are found or the command itself fails.
832
-
833
- **Delegation chain:**
834
- ```
835
- src/cli.ts parseArgs()
836
- -> findDb() / promptUser() / runDbInit()
837
- -> createWorkerClient({ contextPath })
838
- -> versionGate(client, dbDir)
839
- -> dispatchCommand(client, options)
840
- -> runCheck(client, options)
841
- -> client.integrityCheck()
842
- -> IPC -> worker daemon
843
- -> kb-worker.wasm
844
- -> fs-database.wasm
845
- -> stdout
846
- ```
847
-
848
- See [Database -- Integrity and
849
- Maintenance](database.md) for the full list of
850
- checks and error types.
851
-
852
- ### `gc` -- garbage collection
853
-
854
- ```
855
- kbdb gc [options]
856
- ```
857
-
858
- Remove unreferenced sections from the database.
859
- A section is eligible for removal when no document
860
- manifest references it (empty `docids` array).
861
-
862
- **Output:**
863
- - **stdout**: JSON report:
864
- ```json
865
- {
866
- "removed_sections": 3,
867
- "removed_bytes": 15360,
868
- "stale_sources": 1
869
- }
870
- ```
871
- When no sections are eligible, `removed_sections`
872
- is `0` and `removed_bytes` is `0`.
873
- `stale_sources` reports sections whose
874
- `source_path` file no longer contains their heading
875
- text (advisory, not automatically removed).
876
- - **stderr**: errors only.
877
-
878
- **Exit code:** `0` on success, `1` on error.
879
-
880
- **Delegation chain:**
881
- ```
882
- src/cli.ts parseArgs()
883
- -> findDb() / promptUser() / runDbInit()
884
- -> createWorkerClient({ contextPath })
885
- -> versionGate(client, dbDir)
886
- -> dispatchCommand(client, options)
887
- -> runGc(client, options)
888
- -> client.gc()
889
- -> IPC -> worker daemon
890
- -> kb-worker.wasm
891
- -> fs-database.wasm
892
- -> stdout
893
- ```
894
-
895
- ### `rebuild` -- rebuild indexes
896
-
897
- ```
898
- kbdb rebuild [options]
899
- ```
900
-
901
- Reconstruct all index files from section files and
902
- document manifests on disk.
903
-
904
- **Output:**
905
- - **stdout**: JSON report:
906
- ```json
907
- {
908
- "sections_reindexed": 39,
909
- "terms_indexed": 1500
910
- }
911
- ```
912
- - **stderr**: errors only.
913
-
914
- **Exit code:** `0` on success, `1` on error.
915
-
916
- **Delegation chain:**
917
- ```
918
- src/cli.ts parseArgs()
919
- -> findDb() / promptUser() / runDbInit()
920
- -> createWorkerClient({ contextPath })
921
- -> versionGate(client, dbDir)
922
- -> dispatchCommand(client, options)
923
- -> runRebuild(client, options)
924
- -> client.rebuildIndexes()
925
- -> IPC -> worker daemon
926
- -> kb-worker.wasm
927
- -> query-parser.wasm (tokenize)
928
- -> fs-database.wasm
929
- (store indexes)
930
- -> stdout
931
- ```
932
-
933
- ### `export` -- snapshot database
934
-
935
- ```
936
- kbdb export [options] [<path>]
937
- ```
938
-
939
- Export the database as a self-contained directory
940
- snapshot for backup, transfer, or version control.
941
- The export includes sections, documents, and the
942
- catalog. Indexes are excluded -- they are derived
943
- data and can be rebuilt with `kbdb rebuild` after
944
- importing.
945
-
946
- **Arguments:**
947
- - `<path>` -- Output directory path. Defaults to
948
- `./kbdb-export/` in the current working directory.
949
- If the directory exists, it is overwritten.
950
-
951
- **Options:**
952
- - `--db <path>` -- Source database directory.
953
-
954
- **Output:**
955
- - **stdout**: JSON report:
956
- ```json
957
- {
958
- "path": "/absolute/path/kbdb-export",
959
- "sections_exported": 42,
960
- "documents_exported": 5
961
- }
962
- ```
963
- - **stderr**: errors only.
964
-
965
- **Exit code:** `0` on success, `1` on error.
966
-
967
- **Delegation chain:**
968
- ```
969
- src/cli.ts parseArgs()
970
- -> findDb() / promptUser() / runDbInit()
971
- -> createWorkerClient({ contextPath })
972
- -> versionGate(client, dbDir)
973
- -> dispatchCommand(client, options)
974
- -> runExport(client, options)
975
- -> client.export({ path })
976
- -> IPC -> worker daemon
977
- -> kb-worker.wasm
978
- -> fs-database.wasm
979
- -> stdout
980
- ```
981
-
982
- ### `kbdb worker` -- daemon lifecycle
983
-
984
- The `worker` command group manages the background
985
- worker daemon process.
986
-
987
- #### `worker stop` -- stop the daemon
988
-
989
- ```
990
- kbdb worker stop [options]
991
- ```
992
-
993
- Stop the running worker daemon for the current
994
- database. If no daemon is running, prints a message
995
- and exits successfully.
996
-
997
- **Exit code:** `0` on success, `1` on error.
998
-
999
- **Delegation chain:**
1000
- ```
1001
- src/cli.ts parseArgs()
1002
- -> dispatchCommand(client, options)
1003
- -> runWorkerStop(client, options)
1004
- -> sends shutdown signal via IPC
1005
- ```
1006
-
1007
- #### `worker restart` -- restart the daemon
1008
-
1009
- ```
1010
- kbdb worker restart [options]
1011
- ```
1012
-
1013
- Stop and restart the worker daemon. Equivalent to
1014
- `worker stop` followed by the next command
1015
- auto-spawning a new daemon.
1016
-
1017
- **Exit code:** `0` on success, `1` on error.
1018
-
1019
- ### `kbdb db` -- database management
1020
-
1021
- The `db` command group manages the `.kbdb` database
1022
- directory lifecycle. It replaces the deprecated
1023
- `--init` and `--migrate` flags with a consistent
1024
- `kbdb db <subcommand>` pattern.
1025
-
1026
- #### `db init` -- initialise database
1027
-
1028
- ```
1029
- kbdb db init [options]
1030
- ```
1031
-
1032
- Create a blank `.kbdb` database directory at the
1033
- target path. This is an explicit initialisation
1034
- command -- it does not silently create directories.
1035
-
1036
- `db init` sets `options.command = 'db-init'` and is
1037
- handled before the data-command path (no daemon
1038
- required).
1039
-
1040
- **Options:**
1041
-
1042
- | Option | Description |
1043
- |---------------|------------------------------------------|
1044
- | `--db <path>` | Path to create `.kbdb` in. Defaults to cwd. |
1045
-
1046
- **Behaviour:**
1047
- - Resolves target path from `--db` or `process.cwd()`.
1048
- - Creates the `.kbdb` directory scaffold directly on
1049
- disk (no daemon required): `catalog.toml`,
1050
- `corpus.bin`, `inverted.idx`, `positional.idx`,
1051
- `sections/`, `documents/`, `worker.toml`,
1052
- `.gitignore`.
1053
- - The database is stamped with `DB_FORMAT_VERSION = 1`.
1054
- - If `.kbdb` already exists: prints error to stderr,
1055
- exits non-zero.
1056
- - Implemented by `runDbInit()` in
1057
- `src/shared/cli/functions/run-db-init.function.ts`.
1058
-
1059
- **Output:**
1060
- - **stdout**: JSON object on success:
1061
- ```json
1062
- { "path": "/absolute/path/.kbdb", "created": true }
1063
- ```
1064
- - **stderr**: error message on failure.
1065
-
1066
- **Exit code:** `0` on success, `1` on error.
1067
-
1068
- **Delegation chain:**
1069
- ```
1070
- src/cli.ts parseArgs()
1071
- -> dispatchCommand(options)
1072
- -> runDbInit(options)
1073
- -> createScaffold(dbDir)
1074
- (writes files directly to disk)
1075
- ```
1076
-
1077
- **Examples:**
1078
- ```sh
1079
- # Initialise in the current directory
1080
- kbdb db init
1081
-
1082
- # Initialise in a specific directory
1083
- kbdb db init --db /path/to/project
1084
- ```
1085
-
1086
- #### `db migrate` -- migrate database
1087
-
1088
- ```
1089
- kbdb db migrate [options]
1090
- ```
1091
-
1092
- Run sequential migration scripts to upgrade a `.kbdb`
1093
- database directory from an older format version to the
1094
- current version.
1095
-
1096
- `db migrate` sets `options.command = 'db-migrate'`.
1097
-
1098
- **Options:**
1099
-
1100
- | Option | Description |
1101
- |---------------|------------------------------------------|
1102
- | `--db <path>` | Path containing `.kbdb`. Defaults to cwd. |
1103
-
1104
- **Behaviour:**
1105
- - Resolves target path from `--db` or `process.cwd()`.
1106
- - Requires an existing `.kbdb` directory. Returns an
1107
- error if none is found.
1108
- - Calls `client.checkVersion(dbDir)` to read the
1109
- catalog version:
1110
- - `needs_migration` (DB version < WASM version):
1111
- calls `client.migrateDatabase(dbDir)`, prints the
1112
- JSON `MigrateResult`, exits 0.
1113
- - `ok` (DB version == WASM version): prints
1114
- "already up to date", exits 0.
1115
- - `too_new` (DB version > WASM version): prints
1116
- error to stderr, exits 1.
1117
-
1118
- **Output:**
1119
- - **stdout**: `MigrateResult` JSON on success, or
1120
- "already up to date" when already current.
1121
- - **stderr**: error message on failure.
1122
-
1123
- **Exit code:** `0` on success, `1` on error.
1124
-
1125
- **Delegation chain:**
1126
- ```
1127
- src/cli.ts parseArgs()
1128
- -> findDb() / promptUser() / runDbInit()
1129
- -> createWorkerClient({ contextPath })
1130
- -> dispatchCommand(client, options)
1131
- -> runDbMigrate(client, options)
1132
- -> client.checkVersion(dbDir)
1133
- -> client.migrateDatabase(dbDir)
1134
- -> IPC -> worker daemon
1135
- -> fs-migration.wasm
1136
- (db_migrate -> migration chain)
1137
- ```
1138
-
1139
- **Examples:**
1140
- ```sh
1141
- # Migrate the database in the current directory
1142
- kbdb db migrate
1143
-
1144
- # Migrate a database at a specific path
1145
- kbdb db migrate --db /path/to/project
1146
- ```
1147
-
1148
- ### `--init` -- initialise database (deprecated)
1149
-
1150
- > **Deprecated.** Use `kbdb db init` instead.
1151
- > `kbdb --init` still works but emits a deprecation
1152
- > warning to stderr:
1153
- > `warning: --init is deprecated, use "kbdb db init"`
1154
-
1155
- ```
1156
- kbdb --init [--db <path>]
1157
- ```
1158
-
1159
- Create a blank `.kbdb` database directory at the
1160
- target path. This is an explicit initialisation
1161
- command -- it does not silently create directories.
1162
-
1163
- `--init` sets `options.command = 'init'` and is
1164
- handled before the data-command path.
1165
-
1166
- **Behaviour:**
1167
- - Resolves target path from `--db` or `process.cwd()`.
1168
- - Creates the `.kbdb` directory scaffold directly on
1169
- disk (no daemon required): `catalog.toml`,
1170
- `corpus.bin`, `inverted.idx`, `positional.idx`,
1171
- `sections/`, `documents/`, `worker.toml`,
1172
- `.gitignore`.
1173
- - The database is stamped with `DB_FORMAT_VERSION = 1`.
1174
- - If `.kbdb` already exists: prints error to stderr,
1175
- exits non-zero.
1176
- - Implemented by `runDbInit()` in
1177
- `src/shared/cli/functions/run-db-init.function.ts`.
1178
-
1179
- **Output:**
1180
- - **stdout**: the absolute path to the created `.kbdb`
1181
- directory on success.
1182
- - **stderr**: error message on failure.
1183
-
1184
- **Exit code:** `0` on success, `1` on error.
1185
-
1186
- **Delegation chain:**
1187
- ```
1188
- src/cli.ts parseArgs()
1189
- -> handleInit(options, deps)
1190
- -> deps.runDbInit(options)
1191
- -> createScaffold(dbDir)
1192
- (writes files directly to disk)
1193
- ```
1194
-
1195
- ### `--migrate` -- migrate database (deprecated)
1196
-
1197
- > **Deprecated.** Use `kbdb db migrate` instead.
1198
- > `kbdb --migrate` still works but emits a
1199
- > deprecation warning to stderr:
1200
- > `warning: --migrate is deprecated, use "kbdb db migrate"`
1201
-
1202
- ```
1203
- kbdb --migrate [--db <path>]
1204
- ```
1205
-
1206
- Run sequential migration scripts to upgrade a `.kbdb`
1207
- database directory from an older format version to the
1208
- current version.
1209
-
1210
- `--migrate` sets `options.command = 'migrate'` and is
1211
- handled before the data-command path.
1212
-
1213
- **Behaviour:**
1214
- - Resolves target path from `--db` or
1215
- `process.cwd()`.
1216
- - Requires an existing `.kbdb` directory. Returns an
1217
- error if none is found.
1218
- - Calls `client.checkVersion(dbDir)` to read the
1219
- catalog version:
1220
- - `needs_migration` (DB version < WASM version):
1221
- calls `client.migrateDatabase(dbDir)`, prints the
1222
- JSON result, exits 0.
1223
- - `ok` (DB version == WASM version): prints
1224
- "already up to date", exits 0.
1225
- - `too_new` (DB version > WASM version): prints
1226
- error to stderr, exits 1.
1227
-
1228
- **Output:**
1229
- - **stdout**: migration result JSON on success, or
1230
- "already up to date" string when already current.
1231
- - **stderr**: error message on failure.
1232
-
1233
- **Exit code:** `0` on success, `1` on error.
1234
-
1235
- **Delegation chain:**
1236
- ```
1237
- src/cli.ts parseArgs()
1238
- -> handleMigrate(options, deps)
1239
- -> deps.findDb(options.dbPath)
1240
- -> deps.createWorkerClient({ contextPath })
1241
- -> client.checkVersion(dbDir)
1242
- -> client.migrateDatabase(dbDir)
1243
- -> IPC -> worker daemon
1244
- -> fs-migration.wasm
1245
- (db_migrate -> migration chain)
1246
- ```
1247
-
1248
- ### `kbdb skill` -- skill management
1249
-
1250
- The `skill` command group manages reusable AI agent
1251
- skill definitions stored as sections with
1252
- `sectionType: 'skill'`. See [Skills](skills.md) for
1253
- the full skill specification.
1254
-
1255
- #### `skill learn` -- create a skill
1256
-
1257
- ```
1258
- kbdb skill learn [options] --name <n> --body <file|->
1259
- ```
1260
-
1261
- Read a skill body from a file or stdin, extract
1262
- `{{argName}}` placeholders, and store the skill as
1263
- an indexed section.
1264
-
1265
- `skill learn` sets `options.command = 'skill-learn'`.
1266
-
1267
- **Options:**
1268
-
1269
- | Option | Required | Description |
1270
- |---------------------|----------|-----------------------------------|
1271
- | `--name <n>` | yes | Skill name (kebab-case) |
1272
- | `--description <d>` | no | Human-readable skill description |
1273
- | `--body <file\|->` | yes | Template body file path or stdin |
1274
- | `--db <path>` | no | Path to `.kbdb` directory |
1275
-
1276
- **Behaviour:**
1277
- - Reads the body text from the file path given to
1278
- `--body`, or from stdin when `--body` is `-`.
1279
- - Scans the body for `{{argName}}` placeholders and
1280
- auto-detects the argument list.
1281
- - Constructs the skill JSON and calls
1282
- `client.addSection()` with `sectionType: 'skill'`.
1283
- - The skill `name` is used as the section `title`
1284
- (2.0x index weight), `description` as the section
1285
- description.
1286
-
1287
- **Output:**
1288
- - **stdout**: JSON object on success:
1289
- ```json
1290
- {
1291
- "kbid": "abcdef1234567890abcdef1234",
1292
- "name": "summarize-document",
1293
- "arguments": ["docid", "max_points"]
1294
- }
1295
- ```
1296
- - **stderr**: errors only.
1297
-
1298
- **Exit code:** `0` on success, `1` on error.
1299
-
1300
- **Delegation chain:**
1301
- ```
1302
- src/cli.ts parseArgs()
1303
- -> findDb() / promptUser() / runDbInit()
1304
- -> createWorkerClient({ contextPath })
1305
- -> versionGate(client, dbDir)
1306
- -> dispatchCommand(client, options)
1307
- -> runSkillLearn(client, options)
1308
- -> client.addSection({
1309
- sectionType: 'skill',
1310
- content: skillJson,
1311
- title: name,
1312
- description })
1313
- -> IPC -> worker daemon
1314
- -> kb-worker.wasm
1315
- -> fs-database.wasm (store)
1316
- ```
1317
-
1318
- **Examples:**
1319
- ```sh
1320
- # Learn a skill from a file
1321
- kbdb skill learn --name summarize-document \
1322
- --description "Summarize a document" \
1323
- --body ./prompts/summarize.txt
1324
-
1325
- # Learn a skill from stdin
1326
- cat summarize.txt | kbdb skill learn \
1327
- --name summarize-document --body -
1328
-
1329
- # Learn a skill in a specific database
1330
- kbdb skill learn --name my-skill \
1331
- --body ./skill.txt --db /path/to/project
1332
- ```
1333
-
1334
- #### `skill list` -- list all skills
1335
-
1336
- ```
1337
- kbdb skill list [options]
1338
- ```
1339
-
1340
- List all skill definitions stored in the database.
1341
-
1342
- `skill list` sets `options.command = 'skill-list'`.
1343
-
1344
- **Output:**
1345
- - **stdout**: JSON array of skill summaries:
1346
- ```json
1347
- [
1348
- {
1349
- "kbid": "abcdef1234567890abcdef1234",
1350
- "name": "summarize-document",
1351
- "description": "Summarize a document...",
1352
- "argumentCount": 2
1353
- }
1354
- ]
1355
- ```
1356
- Empty array when no skills exist.
1357
- - **stderr**: errors only.
1358
-
1359
- **Exit code:** `0` on success, `1` on error.
1360
-
1361
- **Delegation chain:**
1362
- ```
1363
- src/cli.ts parseArgs()
1364
- -> findDb() / promptUser() / runDbInit()
1365
- -> createWorkerClient({ contextPath })
1366
- -> versionGate(client, dbDir)
1367
- -> dispatchCommand(client, options)
1368
- -> runSkillList(client, options)
1369
- -> client.listByType('skill')
1370
- -> IPC -> worker daemon
1371
- -> kb-worker.wasm
1372
- -> fs-database.wasm (scan)
1373
- ```
1374
-
1375
- #### `skill get` -- retrieve a skill
1376
-
1377
- ```
1378
- kbdb skill get [options] <name-or-kbid>
1379
- ```
1380
-
1381
- Retrieve a single skill definition by name or kbid.
1382
-
1383
- `skill get` sets `options.command = 'skill-get'`.
1384
-
1385
- **Arguments:**
1386
- - `<name-or-kbid>` -- (required) the skill name
1387
- (e.g. `summarize-document`) or a 26-character kbid.
1388
- When looked up by name, returns the most recently
1389
- created skill with that name.
1390
-
1391
- **Output:**
1392
- - **stdout**: JSON `SkillDefinition` object:
1393
- ```json
1394
- {
1395
- "kbid": "abcdef1234567890abcdef1234",
1396
- "name": "summarize-document",
1397
- "description": "Summarize a document...",
1398
- "arguments": [
1399
- {
1400
- "name": "docid",
1401
- "type": "string",
1402
- "description": "Document identifier",
1403
- "required": true
1404
- }
1405
- ],
1406
- "body": "Summarize the document {{docid}}..."
1407
- }
1408
- ```
1409
- - **stderr**: errors only.
1410
-
1411
- **Exit code:** `0` on success, `1` when not found or
1412
- on error.
1413
-
1414
- **Delegation chain:**
1415
- ```
1416
- src/cli.ts parseArgs()
1417
- -> findDb() / promptUser() / runDbInit()
1418
- -> createWorkerClient({ contextPath })
1419
- -> versionGate(client, dbDir)
1420
- -> dispatchCommand(client, options)
1421
- -> runSkillGet(client, options)
1422
- -> client.listByType('skill')
1423
- (filter by name or kbid)
1424
- -> client.content([kbid])
1425
- -> IPC -> worker daemon
1426
- -> kb-worker.wasm
1427
- -> fs-database.wasm (fetch)
1428
- ```
1429
-
1430
- #### `skill delete` -- remove a skill
1431
-
1432
- ```
1433
- kbdb skill delete [options] <kbid>
1434
- ```
1435
-
1436
- Remove a skill section by its kbid. The skill body
1437
- and index entries are permanently deleted.
1438
-
1439
- `skill delete` sets `options.command = 'skill-delete'`.
1440
-
1441
- **Arguments:**
1442
- - `<kbid>` -- (required) the 26-character kbid of the
1443
- skill to remove.
1444
-
1445
- **Output:**
1446
- - **stdout**: JSON result:
1447
- ```json
1448
- { "kbid": "abcdef1234567890abcdef1234", "removed": true }
1449
- ```
1450
- `"removed"` is `false` when the kbid does not exist.
1451
- - **stderr**: errors only.
1452
-
1453
- **Exit code:** `0` on success, `1` on error.
1454
-
1455
- **Delegation chain:**
1456
- ```
1457
- src/cli.ts parseArgs()
1458
- -> findDb() / promptUser() / runDbInit()
1459
- -> createWorkerClient({ contextPath })
1460
- -> versionGate(client, dbDir)
1461
- -> dispatchCommand(client, options)
1462
- -> runSkillDelete(client, options)
1463
- -> client.removeSection(kbid)
1464
- -> IPC -> worker daemon
1465
- -> kb-worker.wasm
1466
- -> fs-database.wasm (delete)
1467
- ```
1468
-
1469
- ### `kbdb agent` -- agent management
1470
-
1471
- The `agent` command group manages AI agent persona
1472
- definitions stored as document manifests with
1473
- `type: 'agent'`. See [Agents](agents.md) for the
1474
- full agent specification.
1475
-
1476
- #### `agent create` -- create an agent
1477
-
1478
- ```
1479
- kbdb agent create [options] --name <n>
1480
- --persona <file|-> --skills <kbid,...>
1481
- ```
1482
-
1483
- Read a persona from a file or stdin, validate the
1484
- referenced skill kbids, and create an agent document
1485
- manifest.
1486
-
1487
- `agent create` sets `options.command = 'agent-create'`.
1488
-
1489
- **Options:**
1490
-
1491
- | Option | Required | Description |
1492
- |---------------------|----------|-----------------------------------|
1493
- | `--name <n>` | yes | Agent name (kebab-case) |
1494
- | `--description <d>` | no | Human-readable agent description |
1495
- | `--persona <file\|->` | yes | Persona file path or stdin |
1496
- | `--skills <kbid,...>` | yes | Comma-separated ordered skill kbids |
1497
- | `--db <path>` | no | Path to `.kbdb` directory |
1498
-
1499
- **Behaviour:**
1500
- - Reads the persona text from the file path given to
1501
- `--persona`, or from stdin when `--persona` is `-`.
1502
- - Splits `--skills` on commas to produce an ordered
1503
- list of skill kbids. Each kbid is validated to
1504
- exist in the database before the agent is created.
1505
- - Creates a document manifest with `type = "agent"`,
1506
- the persona text, and ordered `[[sections]]`
1507
- entries referencing each skill kbid.
1508
-
1509
- **Output:**
1510
- - **stdout**: JSON object on success:
1511
- ```json
1512
- {
1513
- "docid": "agent-code-reviewer",
1514
- "name": "code-reviewer",
1515
- "skills": [
1516
- "abcdef1234567890abcdef1234",
1517
- "fedcba9876543210fedcba9876"
1518
- ]
1519
- }
1520
- ```
1521
- - **stderr**: errors only.
1522
-
1523
- **Exit code:** `0` on success, `1` on error.
1524
-
1525
- **Delegation chain:**
1526
- ```
1527
- src/cli.ts parseArgs()
1528
- -> findDb() / promptUser() / runDbInit()
1529
- -> createWorkerClient({ contextPath })
1530
- -> versionGate(client, dbDir)
1531
- -> dispatchCommand(client, options)
1532
- -> runAgentCreate(client, options)
1533
- -> client.listByType('skill')
1534
- (validate skill kbids)
1535
- -> client.createDocument({
1536
- type: 'agent',
1537
- title: name,
1538
- description,
1539
- persona,
1540
- skills: kbids })
1541
- -> IPC -> worker daemon
1542
- -> kb-worker.wasm
1543
- -> fs-database.wasm (write)
1544
- ```
1545
-
1546
- **Examples:**
1547
- ```sh
1548
- # Create an agent from a persona file
1549
- kbdb agent create --name code-reviewer \
1550
- --description "Reviews code for best practices" \
1551
- --persona ./personas/reviewer.txt \
1552
- --skills abc123,def456
1553
-
1554
- # Create an agent with persona from stdin
1555
- cat persona.txt | kbdb agent create \
1556
- --name my-agent --persona - \
1557
- --skills abc123
1558
-
1559
- # Create an agent in a specific database
1560
- kbdb agent create --name my-agent \
1561
- --persona ./persona.txt --skills abc123 \
1562
- --db /path/to/project
1563
- ```
1564
-
1565
- #### `agent list` -- list all agents
1566
-
1567
- ```
1568
- kbdb agent list [options]
1569
- ```
1570
-
1571
- List all agent definitions stored in the database.
1572
-
1573
- `agent list` sets `options.command = 'agent-list'`.
1574
-
1575
- **Output:**
1576
- - **stdout**: JSON array of agent summaries:
1577
- ```json
1578
- [
1579
- {
1580
- "docid": "agent-code-reviewer",
1581
- "name": "code-reviewer",
1582
- "description": "Reviews code for best practices",
1583
- "skillCount": 2
1584
- }
1585
- ]
1586
- ```
1587
- Empty array when no agents exist.
1588
- - **stderr**: errors only.
1589
-
1590
- **Exit code:** `0` on success, `1` on error.
1591
-
1592
- **Delegation chain:**
1593
- ```
1594
- src/cli.ts parseArgs()
1595
- -> findDb() / promptUser() / runDbInit()
1596
- -> createWorkerClient({ contextPath })
1597
- -> versionGate(client, dbDir)
1598
- -> dispatchCommand(client, options)
1599
- -> runAgentList(client, options)
1600
- -> client.listDocumentsByType('agent')
1601
- -> IPC -> worker daemon
1602
- -> kb-worker.wasm
1603
- -> fs-database.wasm (scan)
1604
- ```
1605
-
1606
- #### `agent get` -- retrieve an agent
1607
-
1608
- ```
1609
- kbdb agent get [options] <docid>
1610
- ```
1611
-
1612
- Retrieve a single agent definition by its document
1613
- ID, with resolved skill definitions.
1614
-
1615
- `agent get` sets `options.command = 'agent-get'`.
1616
-
1617
- **Arguments:**
1618
- - `<docid>` -- (required) the agent document ID
1619
- (e.g. `agent-code-reviewer`).
1620
-
1621
- **Output:**
1622
- - **stdout**: JSON `AgentDefinition` object with
1623
- resolved skills:
1624
- ```json
1625
- {
1626
- "docid": "agent-code-reviewer",
1627
- "name": "code-reviewer",
1628
- "description": "Reviews code for best practices",
1629
- "persona": "You are an expert code reviewer...",
1630
- "skills": [
1631
- {
1632
- "kbid": "abcdef1234567890abcdef1234",
1633
- "name": "review-style",
1634
- "position": 0
1635
- },
1636
- {
1637
- "kbid": "fedcba9876543210fedcba9876",
1638
- "name": null,
1639
- "position": 1
1640
- }
1641
- ]
1642
- }
1643
- ```
1644
- A `null` skill name indicates a dangling reference
1645
- (the referenced skill was deleted). This is a
1646
- warning, not an error.
1647
- - **stderr**: errors only.
1648
-
1649
- **Exit code:** `0` on success, `1` when not found or
1650
- on error.
1651
-
1652
- **Delegation chain:**
1653
- ```
1654
- src/cli.ts parseArgs()
1655
- -> findDb() / promptUser() / runDbInit()
1656
- -> createWorkerClient({ contextPath })
1657
- -> versionGate(client, dbDir)
1658
- -> dispatchCommand(client, options)
1659
- -> runAgentGet(client, options)
1660
- -> client.listDocumentsByType('agent')
1661
- (find by docid)
1662
- -> client.listByType('skill')
1663
- (resolve skill kbids)
1664
- -> IPC -> worker daemon
1665
- -> kb-worker.wasm
1666
- -> fs-database.wasm (fetch)
1667
- ```
1668
-
1669
- #### `agent delete` -- remove an agent
1670
-
1671
- ```
1672
- kbdb agent delete [options] <docid>
1673
- ```
1674
-
1675
- Remove an agent document manifest by its document ID.
1676
- Only the agent manifest is removed -- the referenced
1677
- skill sections are not deleted.
1678
-
1679
- `agent delete` sets `options.command = 'agent-delete'`.
1680
-
1681
- **Arguments:**
1682
- - `<docid>` -- (required) the agent document ID to
1683
- remove.
1684
-
1685
- **Output:**
1686
- - **stdout**: JSON result:
1687
- ```json
1688
- { "docid": "agent-code-reviewer", "removed": true }
1689
- ```
1690
- `"removed"` is `false` when the docid does not exist.
1691
- - **stderr**: errors only.
1692
-
1693
- **Exit code:** `0` on success, `1` on error.
1694
-
1695
- **Delegation chain:**
1696
- ```
1697
- src/cli.ts parseArgs()
1698
- -> findDb() / promptUser() / runDbInit()
1699
- -> createWorkerClient({ contextPath })
1700
- -> versionGate(client, dbDir)
1701
- -> dispatchCommand(client, options)
1702
- -> runAgentDelete(client, options)
1703
- -> client.removeDocument(docid)
1704
- -> IPC -> worker daemon
1705
- -> kb-worker.wasm
1706
- -> fs-database.wasm (delete)
1707
- ```
1708
-
1709
- ## Database Initialisation
1710
-
1711
- Before executing any data command (`learn`, `unlearn`,
1712
- `search`, etc.) the CLI checks for the `.kbdb`
1713
- storage directory via `findDb()`.
1714
-
1715
- ### Current behaviour
1716
-
1717
- 1. **Explicit init** -- `kbdb db init` creates the
1718
- database directory with the full scaffold. This is
1719
- the only way to create a new database without being
1720
- prompted.
1721
-
1722
- 2. **Interactive prompt** -- when a data command finds
1723
- no `.kbdb` directory:
1724
- - If stdin is a TTY (`isStdinTty()` returns `true`):
1725
- prompt "No .kbdb database found. Create one in
1726
- \<path>? [y/N]"
1727
- - On "y": call `runDbInit()`, continue with the
1728
- command.
1729
- - Otherwise: print "aborted: no database created"
1730
- to stderr, exit 1.
1731
- - If stdin is not a TTY (piped / CI): print error to
1732
- stderr, exit 1. No prompt.
1733
-
1734
- 2b. **Non-interactive override** -- when
1735
- `--non-interactive` is passed or
1736
- `KBDB_NON_INTERACTIVE` is set to `1` or `true`,
1737
- the CLI overrides `isStdinTty()` to return
1738
- `false`. This forces the non-interactive path
1739
- (error + exit 1) regardless of terminal type.
1740
-
1741
- 3. **Version check gate** -- when `.kbdb` exists, the
1742
- CLI calls `client.checkVersion(dbDir)` before
1743
- dispatching any data command:
1744
- - `needs_migration`: print error ("database needs
1745
- migration -- run `kbdb db migrate`"), exit 1.
1746
- - `too_new`: print error ("database version X is
1747
- newer than kbdb version Y -- upgrade kbdb"),
1748
- exit 1.
1749
- - `ok`: proceed.
1750
-
1751
- 4. **MCP mode** -- does NOT prompt. Requires an
1752
- existing `.kbdb` directory and passes the same
1753
- version gate.
1754
-
1755
- ## CLI Mode Execution Model
1756
-
1757
- The CLI follows a strict pass-through architecture:
1758
-
1759
- 1. Parse command-line arguments (`parseArgs()`).
1760
- 2. Handle `help` or empty command: return `HELP_TEXT`,
1761
- exit 0.
1762
- 3. Handle `version`: return `VERSION` string, exit 0.
1763
- 4. Handle `db-init`: call `runDbInit()` directly (no
1764
- daemon needed).
1765
- 5. Handle `mcp`: find DB, create client, version gate,
1766
- start MCP server.
1767
- 6. Handle `db-migrate`: find DB, create client, call
1768
- `checkVersion` and `migrateDatabase`.
1769
- 7. For data commands: find DB (prompt if missing),
1770
- create client, version gate, call
1771
- `dispatchCommand()`.
1772
- 8. `dispatchCommand()` routes to the appropriate
1773
- `run*` function and returns a `CommandResult`.
1774
- 9. The entry point (`src/cli.ts`) writes
1775
- `result.output` to stdout and `result.error` to
1776
- stderr, then exits with `result.exitCode`.
1777
-
1778
- The CLI prints nothing else. No banners, no progress
1779
- bars, no decorative output unless explicitly requested
1780
- via flag. Stdout contains only the result. Stderr
1781
- contains only errors. This makes the CLI composable
1782
- with pipes, scripts, and programmatic callers.
1783
-
1784
- ## Argument Parsing
1785
-
1786
- The `parseArgs(argv)` function in
1787
- `src/shared/cli/functions/parse-args.function.ts`
1788
- processes the raw argument vector
1789
- (`process.argv.slice(2)` on Node.js,
1790
- `Deno.args` on Deno) into a `CliOptions` object.
1791
-
1792
- ### Parsing rules
1793
-
1794
- 1. `--help` / `-h` and `--version` / `-v` are
1795
- **early-exit flags** -- they set the command and
1796
- return immediately, ignoring all other arguments.
1797
- 2. `--init` sets `command = 'init'`, emits a
1798
- deprecation warning to stderr, and continues
1799
- parsing (does not return early).
1800
- 3. `--migrate` sets `command = 'migrate'`, emits a
1801
- deprecation warning to stderr, and continues
1802
- parsing.
1803
- 4. When the first positional token is `db`, `skill`,
1804
- `agent`, or `worker`, the parser consumes the next positional
1805
- token as the subcommand and combines them into a
1806
- hyphenated command string: `db init` →
1807
- `'db-init'`, `skill learn` → `'skill-learn'`,
1808
- `agent create` → `'agent-create'`,
1809
- `worker stop` → `'worker-stop'`, etc.
1810
- 5. All other flags (`--db`, `--format`, `--mode`,
1811
- `--limit`, `--offset`, `--title`, `--description`,
1812
- `--docid`, `--name`, `--persona`, `--body`,
1813
- `--skills`, `--depth` / `-d`, `--tags`,
1814
- `--timeout-ms`, `--retry`) consume the next token
1815
- as their value. `--depth` is parsed as a number
1816
- and clamped to the range 0--3. `--tags` splits its
1817
- value on commas into a `string[]`. `--timeout-ms`
1818
- and `--retry` are parsed as numbers.
1819
- 6. `--content` / `-c` and `--replace` are boolean
1820
- flags; they set their respective option to `true`
1821
- without consuming the next token.
1822
- 7. The first non-flag, non-group token becomes the
1823
- **command**.
1824
- 8. Subsequent non-flag tokens become **positional
1825
- arguments** (`args`).
1826
- 9. Unknown flags are treated as positional arguments.
1827
-
1828
- ### `CliOptions` type
1829
-
1830
- Defined in
1831
- `src/shared/cli/typings/cli-options.interface.ts`:
1832
-
1833
- ```typescript
1834
- /** Supported output formats for CLI results. */
1835
- type OutputFormat = 'json' | 'text' | 'mcp';
1836
-
1837
- /**
1838
- * Controls which entity type is returned by a search.
1839
- */
1840
- type SearchMode = 'sections' | 'documents' | 'stats';
1841
-
1842
- /** Parsed representation of all CLI arguments. */
1843
- interface CliOptions {
1844
- /** Sub-command to execute. Simple commands use the
1845
- * command name directly (e.g. 'search', 'learn').
1846
- * Compound commands use a hyphenated form
1847
- * (e.g. 'db-init', 'skill-learn', 'agent-create').
1848
- * Legacy flag commands use 'init' and 'migrate'.
1849
- * Empty string when no command is given. */
1850
- command: string;
1851
- /** Path to the knowledge-base root directory. */
1852
- dbPath?: string;
1853
- /** Output format for results. Defaults to 'json'. */
1854
- format: OutputFormat;
1855
- /** Search mode. Defaults to 'sections'. */
1856
- mode: SearchMode;
1857
- /** Maximum number of results. Defaults to 20. */
1858
- limit: number;
1859
- /** Zero-based result offset for pagination.
1860
- * Defaults to 0. */
1861
- offset: number;
1862
- /** Section title for learn command. */
1863
- title?: string;
1864
- /** Section description for learn command. */
1865
- description?: string;
1866
- /** Document ID to attach sections to (learn). */
1867
- docid?: string;
1868
- /** When true, hydrates search result previews
1869
- * with actual section content. */
1870
- content?: boolean;
1871
- /** Skill or agent name (skill learn, agent create). */
1872
- name?: string;
1873
- /** Persona file path or '-' for stdin
1874
- * (agent create). */
1875
- persona?: string;
1876
- /** Skill body file path or '-' for stdin
1877
- * (skill learn). */
1878
- body?: string;
1879
- /** Comma-separated skill kbids
1880
- * (agent create). Parsed to string[]. */
1881
- skills?: string[];
1882
- /** Recall expansion depth (0-3). Defaults to 0. */
1883
- depth?: number;
1884
- /** Comma-separated tags for scoping (learn). */
1885
- tags?: string[];
1886
- /** Enable supersession by source key (learn). */
1887
- replace?: boolean;
1888
- /** Request timeout in ms. */
1889
- timeoutMs?: number;
1890
- /** Max retry count on timeout. */
1891
- retry?: number;
1892
- /** Positional arguments following the sub-command. */
1893
- args: string[];
1894
- }
1895
- ```
1896
-
1897
- `command` is a plain `string`, not a union type. The
1898
- value is whatever the first non-flag token is (or the
1899
- compound form for `db`/`skill`/`agent` groups), or the
1900
- special values `'help'`, `'version'`, `'init'`, and
1901
- `'migrate'` set by flags.
1902
-
1903
- `OutputFormat` and `SearchMode` are string literal
1904
- union type aliases, not enums.
1905
-
1906
- ### Defaults
1907
-
1908
- | Field | Default | Constant |
1909
- |----------|--------------|-------------------|
1910
- | `format` | `'json'` | `DEFAULT_FORMAT` |
1911
- | `mode` | `'sections'` | `DEFAULT_MODE` |
1912
- | `limit` | `20` | `DEFAULT_LIMIT` |
1913
- | `offset` | `0` | `DEFAULT_OFFSET` |
1914
-
1915
- Constants are defined in
1916
- `src/shared/cli/constants/defaults.constant.ts`.
1917
- The same file exports `SUPPORTED_EXTENSIONS` listing
1918
- the file extensions accepted by the learn command.
1919
-
1920
- ## Help Text
1921
-
1922
- The CLI implements a three-level contextual help
1923
- system. The level of detail depends on how many
1924
- command tokens precede `--help`.
1925
-
1926
- ### Level 1: `kbdb --help` (global)
1927
-
1928
- Shows all commands grouped by category, global
1929
- options, and a footer pointing to per-command help.
1930
-
1931
- ```
1932
- kbdb - File-based knowledge base database for AI agents
1933
-
1934
- Usage: kbdb [options]
1935
- kbdb <command> [options] ...[parameters]
1936
- kbdb <command> <subcommand> [options] ...[params]
1937
-
1938
- Options:
1939
- -h, --help Show this help message
1940
- -v, --version Show version information
1941
-
1942
- Knowledge Base:
1943
- learn Import content from files/stdin
1944
- unlearn Remove sections by kbid
1945
- search Query the knowledge base
1946
- recall Retrieve section context by kbid
1947
- content Compose rendered content from ids
1948
-
1949
- Database:
1950
- db init Initialise a new .kbdb directory
1951
- db migrate Migrate database to current format
1952
-
1953
- Maintenance:
1954
- check Verify knowledge base integrity
1955
- gc Garbage collect unreferenced
1956
- sections
1957
- rebuild Reconstruct all index files
1958
- status Show database status
1959
- export Snapshot database for backup
1960
-
1961
- Skills:
1962
- skill learn Create a new skill definition
1963
- skill list List all skills
1964
- skill get Retrieve a skill by name or kbid
1965
- skill delete Remove a skill
1966
-
1967
- Agents:
1968
- agent create Create an agent with skill refs
1969
- agent list List all agents
1970
- agent get Retrieve an agent by docid
1971
- agent delete Remove an agent
1972
-
1973
- Worker:
1974
- worker stop Stop the background daemon
1975
- worker restart Restart the background daemon
1976
-
1977
- Server:
1978
- mcp Start MCP server mode (stdio)
1979
-
1980
- Global Options:
1981
- --db <path> Path to .kbdb directory
1982
- --format <fmt> Output format (json|text|mcp)
1983
-
1984
- Run "kbdb <command> --help" for detailed information.
1985
- ```
1986
-
1987
- ### Level 2: `kbdb <command> --help` (command)
1988
-
1989
- **For commands with subcommands** (`db`, `skill`,
1990
- `agent`): shows subcommand listing with one-line
1991
- descriptions, global options, and a footer:
1992
- `Run "kbdb <cmd> <subcmd> --help" for detailed
1993
- information.`
1994
-
1995
- **For commands without subcommands** (`learn`,
1996
- `search`, `check`, etc.): shows full detail including:
1997
- - Description paragraph
1998
- - Arguments section with semantics
1999
- - Options section with defaults and value descriptions
2000
- - Output section showing both text and json format
2001
- examples
2002
- - Two to three usage examples
2003
-
2004
- ### Level 3: `kbdb <cmd> <subcmd> --help` (subcommand)
2005
-
2006
- Same detail level as Level 2 command help but scoped
2007
- to a single subcommand. Includes: usage line,
2008
- description paragraph, options with defaults,
2009
- arguments, output format examples, and usage examples.
2010
-
2011
- ### Help text principles
2012
-
2013
- - Every help level shows `[options]` immediately after
2014
- the command or subcommand in usage lines.
2015
- - Options show short and long forms, value placeholder,
2016
- and default when applicable.
2017
- - The output section shows both `text` and `json`
2018
- formats where relevant.
2019
- - Examples progress from simple to complex.
2020
- - Global options (`--db`, `--format`, `--help`) appear
2021
- in every help level for discoverability.
2022
-
2023
- ## Output Types
2024
-
2025
- ### `SearchDisplay` type
2026
-
2027
- Defined in
2028
- `src/shared/cli/typings/search-display.model.ts`.
2029
- This is the type that `formatOutput` and all search
2030
- output handlers operate on. It is produced by
2031
- `runSearch()` and optionally enriched by
2032
- `hydrateSearchPreviews()`.
2033
-
2034
- ```typescript
2035
- interface SearchDisplay {
2036
- /** Knowledge-base identifier of the matched section. */
2037
- kbid: string;
2038
- /** Section title text, or null when the section
2039
- * has no title. */
2040
- heading: string | null;
2041
- /** Section MIME type (e.g. "text/markdown"). */
2042
- type: string;
2043
- /** Document identifiers this section belongs to.
2044
- * May be empty for standalone sections. */
2045
- docids: string[];
2046
- /** Relevance score from the ranking engine. */
2047
- score: number;
2048
- /** Normalized score (0.0-1.0) relative to the top
2049
- * result in this result set. */
2050
- confidence: number;
2051
- /** KWIC excerpt (~150 chars) centered on the
2052
- * highest-scoring matched term. Empty string
2053
- * for image sections. */
2054
- snippet: string;
2055
- /** Query terms that matched, as a flat string[]. */
2056
- matched_terms: string[];
2057
- /** Fields that contained matches: subset of
2058
- * ["heading", "body", "code"]. */
2059
- matched_fields: string[];
2060
- /** ISO 8601 creation timestamp. */
2061
- created_at: string;
2062
- /** Full section text. Empty string when --content
2063
- * is not used. */
2064
- preview: string;
2065
- }
2066
- ```
2067
-
2068
- `heading`, `type`, `docids`, `snippet`, and
2069
- `matched_terms` are always populated from the search
2070
- result. `preview` is always an empty string unless
2071
- `--content` / `-c` is supplied, in which case
2072
- `hydrateSearchPreviews()` fills it with the actual
2073
- section text fetched from `client.content()`.
2074
- `heading` is `null` when the section has no title.
2075
-
2076
- ### `LearnResult` type
2077
-
2078
- Defined in
2079
- `src/shared/cli/typings/learn-result.model.ts`.
2080
- Produced by `runLearn()` for each file ingested.
2081
-
2082
- ```typescript
2083
- interface LearnResult {
2084
- /** Knowledge-base identifier assigned to the section. */
2085
- kbid: string;
2086
- /** Absolute path to the source file (or "-" for
2087
- * stdin). */
2088
- path: string;
2089
- /** UTF-8 character count of the ingested content. */
2090
- size: number;
2091
- /** true when the file was skipped. */
2092
- skipped: boolean;
2093
- /** Kbid of the section this one superseded via
2094
- * --replace, or null. */
2095
- superseded: string | null;
2096
- /** Warning strings (e.g. "heading_missing"). */
2097
- warnings: string[];
2098
- /** Sections with similarity >= 0.85. */
2099
- near_duplicates: Array<{
2100
- kbid: string;
2101
- similarity: number;
2102
- }>;
2103
- }
2104
- ```
2105
-
2106
- ### `CommandResult` type
2107
-
2108
- Defined in
2109
- `src/shared/cli/typings/command-result.model.ts`.
2110
- Returned by `runCli()` and `dispatchCommand()` so the
2111
- entry point can write output and exit without those
2112
- functions touching process globals.
2113
-
2114
- ```typescript
2115
- interface CommandResult {
2116
- /** Text to write to stdout (if any). */
2117
- output?: string;
2118
- /** Error message to write to stderr (if any). */
2119
- error?: string;
2120
- /** Process exit code. 0 means success. */
2121
- exitCode: number;
2122
- }
2123
- ```
2124
-
2125
- ## Key Functions
2126
-
2127
- ### `runCli`
2128
-
2129
- Source:
2130
- `src/shared/cli/functions/run-cli.function.ts`
2131
-
2132
- Full CLI orchestrator. Takes the raw argument vector
2133
- and an injectable `CliDeps` object. Returns a
2134
- `CommandResult`. Never touches process globals.
2135
-
2136
- ```typescript
2137
- async function runCli(
2138
- argv: string[],
2139
- deps: CliDeps,
2140
- ): Promise<CommandResult>
2141
- ```
2142
-
2143
- `CliDeps` contains:
2144
-
2145
- | Field | Description |
2146
- |---------------------|--------------------------------------|
2147
- | `isStdinTty` | Returns `true` when stdin is a TTY |
2148
- | `promptUser` | Prompts the user and returns input |
2149
- | `createWorkerClient`| Creates a connected worker client |
2150
- | `findDb` | Looks up the `.kbdb` directory |
2151
- | `runDbInit` | Creates the `.kbdb` scaffold on disk |
2152
- | `startMcpServer` | (Optional) Starts the MCP server |
2153
-
2154
- Routing within `runCli`:
2155
- - `command === 'help'` or empty: return `HELP_TEXT`
2156
- - `command === 'version'`: return `VERSION`
2157
- - `command === 'db-init'`: `handleDbInit` (no client)
2158
- - `command === 'init'`: `handleDbInit` (no client,
2159
- deprecated -- emits warning)
2160
- - `command === 'mcp'`: `handleMcp` (requires client)
2161
- - `command === 'db-migrate'`: `handleDbMigrate`
2162
- (requires client)
2163
- - `command === 'migrate'`: `handleDbMigrate` (requires
2164
- client, deprecated -- emits warning)
2165
- - anything else: `handleDataCommand` (requires client,
2166
- runs version gate, then `dispatchCommand`)
2167
-
2168
- ### `dispatchCommand`
2169
-
2170
- Source:
2171
- `src/shared/cli/functions/dispatch-command.function.ts`
2172
-
2173
- Routes a parsed command to the appropriate `run*`
2174
- handler. Returns `CommandResult` without throwing.
2175
- Wraps each handler call in a try/catch so errors are
2176
- captured as `error` fields with a non-zero exit code.
2177
-
2178
- ```typescript
2179
- async function dispatchCommand(
2180
- client: DispatchClient,
2181
- options: CliOptions,
2182
- io?: LearnIO,
2183
- ): Promise<CommandResult>
2184
- ```
2185
-
2186
- Routing table:
2187
-
2188
- | command | handler | requires client |
2189
- |------------------|--------------------|-----------------|
2190
- | `learn` | `runLearn` | yes |
2191
- | `unlearn` | `runUnlearn` | yes |
2192
- | `search` | `runSearch` | yes |
2193
- | `recall` | `runRecall` | yes |
2194
- | `content` | `runContent` | yes |
2195
- | `check` | `runCheck` | yes |
2196
- | `gc` | `runGc` | yes |
2197
- | `rebuild` | `runRebuild` | yes |
2198
- | `export` | `runExport` | yes |
2199
- | `db-init` | `runDbInit` | no |
2200
- | `db-migrate` | `runDbMigrate` | yes |
2201
- | `skill-learn` | `runSkillLearn` | yes |
2202
- | `skill-list` | `runSkillList` | yes |
2203
- | `skill-get` | `runSkillGet` | yes |
2204
- | `skill-delete` | `runSkillDelete` | yes |
2205
- | `agent-create` | `runAgentCreate` | yes |
2206
- | `agent-list` | `runAgentList` | yes |
2207
- | `agent-get` | `runAgentGet` | yes |
2208
- | `worker-stop` | `runWorkerStop` | yes |
2209
- | `worker-restart` | `runWorkerRestart` | yes |
2210
- | `agent-delete` | `runAgentDelete` | yes |
2211
-
2212
- Unknown commands return exit code 1 with an "unknown
2213
- command" error.
2214
-
2215
- For `search`, `dispatchCommand` also:
2216
- 1. Calls `runSearch()` to get `SearchDisplay[]`.
2217
- 2. When `options.content === true`, calls
2218
- `hydrateSearchPreviews(client, results)` to fill
2219
- each `preview` field.
2220
- 3. Calls `formatOutput(results, options.format)` to
2221
- produce the final output string.
2222
-
2223
- ### `formatOutput`
2224
-
2225
- Source:
2226
- `src/shared/cli/functions/format-output.function.ts`
2227
-
2228
- Serialises a `SearchDisplay[]` to a string in the
2229
- requested format.
2230
-
2231
- ```typescript
2232
- function formatOutput(
2233
- results: SearchDisplay[],
2234
- format: OutputFormat,
2235
- ): string
2236
- ```
2237
-
2238
- - `'json'` -- `JSON.stringify(results, null, 2)`
2239
- - `'text'` -- numbered list with kbid, score, preview,
2240
- and matched terms
2241
- - `'mcp'` -- `{ type: 'text', text: '...' }` envelope
2242
- with one line per result
2243
-
2244
- ### `runDbInit`
2245
-
2246
- Source:
2247
- `src/shared/cli/functions/run-db-init.function.ts`
2248
-
2249
- Creates the `.kbdb` directory scaffold directly on
2250
- disk without a daemon. Replaces the former `runInit`.
2251
-
2252
- ```typescript
2253
- async function runDbInit(
2254
- options: CliOptions,
2255
- ): Promise<CommandResult>
2256
- ```
2257
-
2258
- Writes `catalog.toml`, `corpus.bin`, `inverted.idx`,
2259
- `positional.idx`, `sections/`, `documents/`,
2260
- `worker.toml`, and `.gitignore` under the resolved
2261
- database directory. Returns a JSON result with `path`
2262
- and `created: true` on success.
2263
-
2264
- ### `runDbMigrate`
2265
-
2266
- Source:
2267
- `src/shared/cli/functions/run-db-migrate.function.ts`
2268
-
2269
- Runs the database migration path via the worker
2270
- client. Replaces the former `runMigrate`.
2271
-
2272
- ```typescript
2273
- async function runDbMigrate(
2274
- client: DispatchClient,
2275
- options: CliOptions,
2276
- ): Promise<CommandResult>
2277
- ```
2278
-
2279
- Calls `client.checkVersion(dbDir)`, then
2280
- `client.migrateDatabase(dbDir)` when migration is
2281
- needed. Returns the `MigrateResult` JSON.
2282
-
2283
- ### `runSkillLearn`
2284
-
2285
- Source:
2286
- `src/shared/cli/functions/run-skill-learn.function.ts`
2287
-
2288
- Reads the skill body, extracts `{{argName}}`
2289
- placeholders, and stores the skill as a section.
2290
-
2291
- ```typescript
2292
- async function runSkillLearn(
2293
- client: DispatchClient,
2294
- options: CliOptions,
2295
- ): Promise<CommandResult>
2296
- ```
2297
-
2298
- Reads body from `options.body` (file path or `-` for
2299
- stdin). Calls `client.addSection()` with
2300
- `sectionType: 'skill'`. Returns JSON with `kbid`,
2301
- `name`, and `arguments`.
2302
-
2303
- ### `runSkillList`
2304
-
2305
- Source:
2306
- `src/shared/cli/functions/run-skill-list.function.ts`
2307
-
2308
- Lists all skill sections in the database.
2309
-
2310
- ```typescript
2311
- async function runSkillList(
2312
- client: DispatchClient,
2313
- options: CliOptions,
2314
- ): Promise<CommandResult>
2315
- ```
2316
-
2317
- Calls `client.listByType('skill')` and returns a JSON
2318
- array of skill summaries.
2319
-
2320
- ### `runSkillGet`
2321
-
2322
- Source:
2323
- `src/shared/cli/functions/run-skill-get.function.ts`
2324
-
2325
- Retrieves a single skill by name or kbid.
2326
-
2327
- ```typescript
2328
- async function runSkillGet(
2329
- client: DispatchClient,
2330
- options: CliOptions,
2331
- ): Promise<CommandResult>
2332
- ```
2333
-
2334
- Uses `options.args[0]` as the name-or-kbid. Calls
2335
- `client.listByType('skill')` to find the section,
2336
- then `client.content([kbid])` to fetch the body.
2337
- Returns a full `SkillDefinition` JSON.
2338
-
2339
- ### `runSkillDelete`
2340
-
2341
- Source:
2342
- `src/shared/cli/functions/run-skill-delete.function.ts`
2343
-
2344
- Removes a skill section by kbid.
2345
-
2346
- ```typescript
2347
- async function runSkillDelete(
2348
- client: DispatchClient,
2349
- options: CliOptions,
2350
- ): Promise<CommandResult>
2351
- ```
2352
-
2353
- Uses `options.args[0]` as the kbid. Calls
2354
- `client.removeSection(kbid)`. Returns JSON with
2355
- `kbid` and `removed`.
2356
-
2357
- ### `runAgentCreate`
2358
-
2359
- Source:
2360
- `src/shared/cli/functions/run-agent-create.function.ts`
2361
-
2362
- Reads the persona, validates skill kbids, and creates
2363
- an agent document manifest.
2364
-
2365
- ```typescript
2366
- async function runAgentCreate(
2367
- client: DispatchClient,
2368
- options: CliOptions,
2369
- ): Promise<CommandResult>
2370
- ```
2371
-
2372
- Reads persona from `options.persona` (file path or
2373
- `-` for stdin). Splits `options.skills` on commas.
2374
- Validates each skill kbid exists via
2375
- `client.listByType('skill')`. Calls
2376
- `client.createDocument()` with `type: 'agent'`.
2377
- Returns JSON with `docid`, `name`, and `skills`.
2378
-
2379
- ### `runAgentList`
2380
-
2381
- Source:
2382
- `src/shared/cli/functions/run-agent-list.function.ts`
2383
-
2384
- Lists all agent document manifests in the database.
2385
-
2386
- ```typescript
2387
- async function runAgentList(
2388
- client: DispatchClient,
2389
- options: CliOptions,
2390
- ): Promise<CommandResult>
2391
- ```
2392
-
2393
- Calls `client.listDocumentsByType('agent')` and
2394
- returns a JSON array of agent summaries.
2395
-
2396
- ### `runAgentGet`
2397
-
2398
- Source:
2399
- `src/shared/cli/functions/run-agent-get.function.ts`
2400
-
2401
- Retrieves a single agent by docid with resolved
2402
- skill definitions.
2403
-
2404
- ```typescript
2405
- async function runAgentGet(
2406
- client: DispatchClient,
2407
- options: CliOptions,
2408
- ): Promise<CommandResult>
2409
- ```
2410
-
2411
- Uses `options.args[0]` as the docid. Fetches the
2412
- agent manifest via `client.listDocumentsByType()`,
2413
- then resolves each skill kbid via
2414
- `client.listByType('skill')`. Returns a full
2415
- `AgentDefinition` JSON. Dangling skill kbids appear
2416
- with `name: null`.
2417
-
2418
- ### `runAgentDelete`
2419
-
2420
- Source:
2421
- `src/shared/cli/functions/run-agent-delete.function.ts`
2422
-
2423
- Removes an agent document manifest by docid. Does
2424
- not delete the referenced skill sections.
2425
-
2426
- ```typescript
2427
- async function runAgentDelete(
2428
- client: DispatchClient,
2429
- options: CliOptions,
2430
- ): Promise<CommandResult>
2431
- ```
2432
-
2433
- Uses `options.args[0]` as the docid. Calls
2434
- `client.removeDocument(docid)`. Returns JSON with
2435
- `docid` and `removed`.
2436
-
2437
- ## Architecture -- How CLI Connects to WASM
2438
-
2439
- The CLI never loads WASM modules or accesses the
2440
- `.kbdb` directory directly. The architecture is a
2441
- four-layer delegation chain:
2442
-
2443
- ```
2444
- User
2445
- |
2446
- v
2447
- src/cli.ts (TypeScript) Layer 1: CLI
2448
- | parseArgs(), runCli(),
2449
- | dispatchCommand(), formatOutput()
2450
- |
2451
- v
2452
- worker-client/ (TypeScript) Layer 2: IPC Client
2453
- | createWorkerClient()
2454
- | JSON-RPC 2.0 over IPC
2455
- |
2456
- v
2457
- src/worker.ts (TypeScript) Layer 3: Daemon
2458
- | loads WASM modules,
2459
- | manages cache,
2460
- | serves IPC requests
2461
- |
2462
- v
2463
- WASM modules (Rust) Layer 4: Engine
2464
- kb-worker.wasm (orchestration)
2465
- -> query-parser.wasm (tokenize, parse, rank)
2466
- -> fs-database.wasm (storage, indexes)
2467
- -> fs-migration.wasm (version migration)
2468
- ```
2469
-
2470
- ### Layer 1: CLI (`src/cli.ts`)
2471
-
2472
- The entry point. Responsibilities:
2473
- - Parse command-line arguments
2474
- - Dispatch to the correct command handler via `runCli`
2475
- - Format output for stdout via `dispatchCommand` /
2476
- `formatOutput`
2477
- - Handle errors to stderr
2478
- - Exit with appropriate code
2479
-
2480
- Source: `src/cli.ts`
2481
- Module: `src/shared/cli/`
2482
-
2483
- ### Layer 2: Worker Client
2484
-
2485
- The IPC bridge. Responsibilities:
2486
- - Resolve database directory path
2487
- - Compute context ID (SHA-256 of path)
2488
- - Discover running daemon or spawn a new one
2489
- - Connect to daemon over IPC socket
2490
- - Expose typed async methods that send JSON-RPC 2.0
2491
- requests
2492
-
2493
- Source: `src/shared/worker-client/`
2494
- See: [Worker Client](worker-client.md)
2495
-
2496
- ### Layer 3: Worker Daemon
2497
-
2498
- The background process. Responsibilities:
2499
- - Compile and load WASM modules once at startup
2500
- - Maintain in-memory LRU cache
2501
- - Process IPC requests through WASM modules
2502
- - Manage daemon lifecycle (idle timeout, shutdown)
2503
-
2504
- Source: `src/worker.ts`
2505
- Module: `src/shared/worker-daemon/`
2506
- See: [Worker Daemon](worker-daemon.md)
2507
-
2508
- ### Layer 4: WASM Engine
2509
-
2510
- The Rust engine compiled to WebAssembly.
2511
- Responsibilities vary by module:
2512
-
2513
- | Module | Responsibility |
2514
- |---------------------|-----------------------------------|
2515
- | `kb-worker.wasm` | Orchestrates the other modules, manages cache and async result tokens |
2516
- | `query-parser.wasm` | Tokenization pipeline, query parsing, keyword extraction, ranking (BM25F, TF-IDF, RAKE) |
2517
- | `fs-database.wasm` | `.kbdb` directory I/O: section CRUD, document manifests, B+ tree indexes, integrity checks |
2518
- | `fs-migration.wasm` | Database format versioning, sequential migration scripts |
2519
-
2520
- See: [Database](database.md),
2521
- [Query Parser](query-parser.md)
2522
-
2523
- ### Which WASM module handles what
2524
-
2525
- | CLI command | WASM modules involved |
2526
- |-------------------|-------------------------------------------|
2527
- | `learn` | `query-parser` (tokenize) + `fs-database` (store + index) via `kb-worker` |
2528
- | `unlearn` | `fs-database` (delete + re-index) via `kb-worker` |
2529
- | `search` | `query-parser` (parse + rank) + `fs-database` (index lookup) via `kb-worker` |
2530
- | `content` | `fs-database` (fetch sections/docs) via `kb-worker` |
2531
- | `check` | `fs-database` (verify checksums, scan manifests) via `kb-worker` |
2532
- | `gc` | `fs-database` (scan + remove unreferenced) via `kb-worker` |
2533
- | `rebuild` | `query-parser` (retokenize) + `fs-database` (rebuild indexes) via `kb-worker` |
2534
- | `db init` | None -- `runDbInit()` writes files directly |
2535
- | `db migrate` | `fs-migration` (`db_migrate`) via daemon |
2536
- | `skill learn` | `fs-database` (store section) via `kb-worker` |
2537
- | `skill list` | `fs-database` (scan by type) via `kb-worker` |
2538
- | `skill get` | `fs-database` (fetch section) via `kb-worker` |
2539
- | `skill delete` | `fs-database` (delete section) via `kb-worker` |
2540
- | `agent create` | `fs-database` (write manifest) via `kb-worker` |
2541
- | `agent list` | `fs-database` (scan documents by type) via `kb-worker` |
2542
- | `agent get` | `fs-database` (fetch manifest + sections) via `kb-worker` |
2543
- | `agent delete` | `fs-database` (remove manifest) via `kb-worker` |
2544
-
2545
- ### Data flow: search
2546
-
2547
- ```
2548
- kbdb search "machine learning" --limit 5
2549
-
2550
- 1. parseArgs() -> { command: 'search',
2551
- args: ['machine', 'learning'],
2552
- mode: 'sections', limit: 5, offset: 0,
2553
- format: 'json', content: undefined }
2554
-
2555
- 2. handleDataCommand():
2556
- findDb() -> '/home/user/project/.kbdb'
2557
-
2558
- 3. createWorkerClient({ contextPath })
2559
- -> discovers daemon, connects via IPC
2560
-
2561
- 4. versionGate(client, dbDir)
2562
- -> client.checkVersion(dbDir)
2563
- -> status 'ok', proceed
2564
-
2565
- 5. dispatchCommand(client, options)
2566
- -> runSearch(client, options)
2567
- -> client.search({
2568
- query: 'machine learning',
2569
- mode: 'sections', limit: 5,
2570
- offset: 0 })
2571
- -> JSON-RPC: { method: 'search', params: {...} }
2572
-
2573
- 6. Worker daemon receives request:
2574
- -> kb-worker.wasm orchestrates:
2575
- a. query-parser.wasm: parse query into
2576
- retrieval plan
2577
- b. fs-database.wasm: execute plan against
2578
- indexes, return raw matches
2579
- c. query-parser.wasm: rank results (BM25F,
2580
- proximity, zone, freshness scoring)
2581
- -> returns ranked results via IPC
2582
-
2583
- 7. runSearch() maps to SearchDisplay[]:
2584
- [{ kbid, heading, type, docids, score,
2585
- snippet, matched_terms, preview: '' }]
2586
-
2587
- 8. options.content is falsy -> skip hydration
2588
-
2589
- 9. formatOutput(results, 'json')
2590
- -> JSON.stringify(results, null, 2)
2591
-
2592
- 10. CommandResult: { output, exitCode: 0 }
2593
-
2594
- 11. src/cli.ts writes output to stdout
2595
- client.disconnect()
2596
- ```
2597
-
2598
- ## Environment Variables
2599
-
2600
- | Variable | Used by | Description |
2601
- |-----------------------|-----------|-------------------------|
2602
- | `KBDB_DB_DIR` | CLI + MCP | Fallback database directory when `--db` is not specified |
2603
- | `KBDB_DAEMON_TIMEOUT` | CLI + MCP | Request timeout fallback (ms) |
2604
- | `KBDB_RETRY` | CLI + MCP | Retry count fallback |
2605
-
2606
- ### Resolution Priority
2607
-
2608
- When multiple sources set the same option, the
2609
- most specific source wins:
2610
-
2611
- - **timeout**: `--timeout-ms` >
2612
- `KBDB_DAEMON_TIMEOUT` > `30000`
2613
- - **retry**: `--retry` > `KBDB_RETRY` > `5`
2614
- - **db path**: `--db` > `KBDB_DB_DIR` > cwd
2615
-
2616
- ## Exit Codes
2617
-
2618
- | Code | Meaning |
2619
- |------|----------------------------------------|
2620
- | `0` | Success |
2621
- | `1` | Error (invalid args, missing DB, WASM error, version mismatch, unknown command) |
2622
-
2623
- All new commands (`db init`, `db migrate`, `skill`
2624
- subcommands, `agent` subcommands) follow the same two
2625
- exit code convention. No additional codes are needed.
2626
-
2627
- ## Design Constraints
2628
-
2629
- - The CLI is a **thin pass-through**. It does not
2630
- perform keyword extraction, indexing, ranking, or
2631
- database I/O itself.
2632
- - **stdout** contains only the command result. No
2633
- banners, progress bars, or decorative output.
2634
- - **stderr** contains only errors (and deprecation
2635
- warnings for `--init` / `--migrate`).
2636
- - The CLI does not read or write `.kbdb` files
2637
- directly (except `db init`, which creates the
2638
- scaffold without a daemon). All other database
2639
- operations go through the worker client -> daemon ->
2640
- WASM chain.
2641
- - The CLI works on both **Deno and Node.js**. Runtime
2642
- differences (argument access, process spawning) are
2643
- abstracted in `src/shared/runtime/` and
2644
- `src/shared/platform/`.
2645
- - Output format is controlled by `--format`, not by
2646
- detecting whether stdout is a TTY.
2647
- - The `--init` and `--migrate` flags are kept for
2648
- backward compatibility but are deprecated. They emit
2649
- a warning to stderr and delegate to the same
2650
- `runDbInit` / `runDbMigrate` handlers as the new
2651
- `kbdb db init` / `kbdb db migrate` commands.
2652
- - `kbdb db init` is the canonical way to create a
2653
- new database. `kbdb db migrate` is the canonical
2654
- way to migrate.