@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
@@ -1,1547 +0,0 @@
1
- # Worker Daemon
2
-
3
- *A detached TypeScript daemon that loads the WASM
4
- module, caches indexes and content objects in memory,
5
- and serves database operations over local IPC.*
6
-
7
- ## Goal
8
-
9
- The worker daemon (`src/worker.ts`) is a detached
10
- background process that provides knowledge base content
11
- retrieval and caching management. It is accessible
12
- **only** by worker client connections over local IPC
13
- (see [Worker Client](worker-client.md)).
14
-
15
- The daemon:
16
-
17
- 1. Loads and compiles the WASM modules once at startup
18
- (`kb-worker` for database operations, `embedding`
19
- for default TF-IDF vector computation).
20
- 2. Holds indexes and content objects in an in-memory
21
- cache managed by the WASM module.
22
- 3. Listens for IPC requests from worker client
23
- connections.
24
- 4. Processes all database operations through the WASM
25
- module.
26
- 5. Returns results over IPC.
27
-
28
- The daemon is spawned on demand by the worker client
29
- module and shuts itself down after a configurable idle
30
- timeout. It is not a persistent server -- it is a
31
- short-lived background process that exists only to
32
- amortize WASM compilation cost and share cached data
33
- across worker client connections.
34
-
35
- The daemon has no knowledge of its callers. It does not
36
- know whether a request originates from a CLI invocation,
37
- an MCP server, or any other consumer. It speaks only
38
- the JSON-RPC 2.0 protocol defined in this document.
39
-
40
- ### Why a Separate Process
41
-
42
- The daemon runs as a separate OS process rather than an
43
- in-process worker thread to provide:
44
-
45
- - **Process isolation** -- The daemon survives the exit
46
- of the process that spawned it. It stays alive as
47
- long as the idle timeout allows, serving any worker
48
- client that connects.
49
- - **Cross-connection sharing** -- Multiple concurrent
50
- worker client connections share the same daemon and
51
- its warm cache for the same database directory.
52
- - **Independent lifecycle** -- The daemon starts and
53
- stops independently of any single consumer.
54
- - **Single WASM compilation** -- The daemon compiles
55
- the WASM module once at startup. All connected worker
56
- clients reuse the compiled module, avoiding repeated
57
- compilation overhead.
58
-
59
- ## Context
60
-
61
- Every worker daemon operates within a **context** --
62
- the absolute path to the knowledge base database
63
- directory (e.g. `${target_dir}/.kbdb`). The context is
64
- the fundamental scope for all daemon operations. It
65
- determines:
66
-
67
- - **Which database is served** -- The daemon loads the
68
- WASM module and operates exclusively on the database
69
- at its context path. It never accesses other
70
- databases.
71
- - **Which daemon to connect to** -- Each context gets
72
- its own independent daemon process. Worker client
73
- connections targeting the same database share one
74
- daemon; different databases run separate daemons.
75
- - **Which configuration applies** -- Daemon
76
- configuration (cache limits, timeouts) is read from
77
- `worker.toml` inside the context directory.
78
-
79
- ### Context ID
80
-
81
- Each context has a **context ID** (`ctx`) -- a
82
- **SHA-256 hash of the database directory's absolute
83
- path**, truncated to 16 lowercase hexadecimal
84
- characters. The truncated hash provides 64 bits of
85
- entropy -- sufficient to disambiguate all database
86
- directories on a single machine.
87
-
88
- Example: `/home/user/project/.kbdb` hashes to
89
- `ctx = "a1b2c3d4e5f67890"`.
90
-
91
- The context ID serves as:
92
-
93
- - **PID file name** -- `kbdb-{ctx}.pid` in the OS
94
- temporary directory.
95
- - **IPC socket/pipe name** --
96
- `kbdb-{ctx}.sock` (Unix) or
97
- `\\.\pipe\kbdb-{ctx}` (Windows).
98
- - **Crash log file name** -- `kbdb-{ctx}.crash` in
99
- the OS temporary directory, written on startup
100
- failure.
101
- - **Request validation** -- Every IPC request includes
102
- the `ctx` param. The daemon verifies it matches its
103
- own context and rejects misrouted requests with error
104
- code `-32001` (context mismatch).
105
-
106
- A single machine may host multiple knowledge bases.
107
- Each database directory is an independent context with
108
- its own daemon, its own cache, and its own WASM module
109
- instance. There is no shared state across contexts.
110
-
111
- ## Write Serialization
112
-
113
- The daemon serializes write operations using an
114
- exclusive file lock on `kbdb-{ctx}.lock` in the OS
115
- temporary directory. The lock file uses the same
116
- context ID as the PID file and IPC socket.
117
-
118
- - **Read operations** proceed without acquiring the
119
- lock. Concurrent reads are fully parallel.
120
- - **Write operations** acquire the exclusive lock
121
- before calling the WASM write export. If another
122
- write is already in progress, the new write queues
123
- behind the lock and waits.
124
- - **Lock duration** -- the lock is held only for the
125
- duration of the single write operation and released
126
- immediately after it completes. It is not held
127
- across multiple operations or across client
128
- connections.
129
-
130
- This serialization model is equivalent to SQLite's
131
- default locking: readers never block, and writers
132
- take turns one at a time.
133
-
134
- Write methods subject to this lock are:
135
- `addSection`, `updateSection`, `removeSection`,
136
- `groupSections`, `removeGrouping`, `initDirectory`,
137
- `gc`, and `rebuildIndexes`.
138
-
139
- ## Daemon Startup
140
-
141
- When the worker client spawns a new daemon (see
142
- [Worker Client -- Spawning](worker-client.md)), the
143
- daemon process performs the following startup sequence:
144
-
145
- 1. Reads `worker.toml` from the context directory for
146
- configuration (falls back to defaults if absent).
147
- 2. Computes the SHA-256 of the context path to derive
148
- the context ID.
149
- 3. Validates startup preconditions (see Startup
150
- Preconditions below). If any check fails, the daemon
151
- prints an error to stderr, writes a crash log to
152
- `{tmpdir}/kbdb-{ctx}.crash`, and exits with code 1.
153
- It does **not** write a PID file or create an IPC
154
- socket.
155
- 4. Compiles and instantiates the `kb-worker` WASM
156
- module (see WASM Module below).
157
- 5. Calls `worker_init` on the WASM module to open the
158
- database context.
159
- 6. Calls `db_check_integrity` on the WASM module to
160
- run a startup health check. If `ok` is false, the
161
- daemon logs a structured warning to stderr listing
162
- the error count and error types. The daemon
163
- continues operating -- health issues are not fatal
164
- to startup. The health status (`integrity_ok`,
165
- `integrity_errors`) is included in subsequent
166
- `status` responses.
167
- 7. Removes the stale IPC socket if present.
168
- 8. Creates the IPC socket (`kbdb-{ctx}.sock` on Unix,
169
- named pipe on Windows) and begins listening
170
- (async, with backlog 256).
171
- 9. Writes its PID to `kbdb-{ctx}.pid` in the OS
172
- temporary directory.
173
-
174
- The daemon writes its PID file only after the IPC
175
- socket is bound and listening. This guarantees the
176
- worker client's PID-file poll succeeds only when
177
- the socket is ready to accept connections. If the
178
- daemon exits before step 9, the worker client's
179
- PID-file poll times out, and the worker client
180
- reads the crash log (or the daemon's stderr) to
181
- report the failure reason.
182
-
183
- ### Startup Preconditions
184
-
185
- The daemon validates the following conditions before
186
- proceeding with WASM module loading and IPC setup. If
187
- any condition fails, the daemon prints a structured
188
- error message to stderr, writes a crash log, and exits
189
- with exit code `1`.
190
-
191
- **1. Database directory exists**
192
-
193
- The context path must be an existing directory. If the
194
- directory does not exist, the daemon prints to stderr:
195
-
196
- ```
197
- kbdb-worker: database directory not found: /path/to/.kbdb
198
- ```
199
-
200
- The daemon does not create the directory. Database
201
- initialisation is the responsibility of the CLI
202
- (`kbdb --init`) or the `initDirectory` IPC method.
203
-
204
- **2. Database directory is readable and writable**
205
-
206
- The daemon must have both read and write access to the
207
- context directory. The daemon checks both R_OK and
208
- W_OK access flags.
209
-
210
- If the directory is not accessible:
211
-
212
- ```
213
- kbdb-worker: cannot access database directory: /path/to/.kbdb
214
- -- permission denied
215
- ```
216
-
217
- The daemon requires write access because database
218
- operations (add, update, remove sections) modify files
219
- in the context directory. A read-only daemon mode is
220
- not supported.
221
-
222
- **3. Database version is compatible**
223
-
224
- After confirming the directory exists and is
225
- accessible, the daemon reads `catalog.toml` and checks
226
- the `version` field against `DB_FORMAT_VERSION` (fixed
227
- at `1` in `daemon-defaults.constant.ts`).
228
-
229
- - **version == DB_FORMAT_VERSION** -- compatible,
230
- proceed with startup.
231
- - **version > DB_FORMAT_VERSION** -- the database was
232
- created or migrated by a newer version of kbdb that
233
- this daemon cannot handle. The daemon prints to
234
- stderr:
235
-
236
- ```
237
- kbdb-worker: database version 3 is newer than kbdb
238
- version 1 -- upgrade kbdb to open this database
239
- ```
240
-
241
- - **version < DB_FORMAT_VERSION** (or absent) -- the
242
- database needs migration. The daemon prints to
243
- stderr:
244
-
245
- ```
246
- kbdb-worker: database version 0 requires migration
247
- to version 1 -- run `kbdb --migrate` before
248
- starting the daemon
249
- ```
250
-
251
- The daemon does not auto-migrate. Migration is an
252
- explicit user action.
253
-
254
- ### Startup Failure Behaviour
255
-
256
- When a precondition fails (or WASM loading fails):
257
-
258
- 1. The daemon prints the error message to **stderr**.
259
- 2. The daemon writes a crash log to
260
- `{tmpdir}/kbdb-{ctx}.crash` (JSON with `error`
261
- and `timestamp` fields).
262
- 3. The daemon exits with exit code **1**.
263
- 4. No PID file is written.
264
- 5. No IPC socket is created.
265
-
266
- The crash log and stderr output are the mechanisms for
267
- communicating startup failures. The crash log persists
268
- after the daemon exits so the worker client can read it
269
- even after the subprocess has gone.
270
-
271
- ## Connection Tracking
272
-
273
- The daemon tracks active client connections via an
274
- internal counter. The idle timer is only active when
275
- the connection count is zero. The timer resets whenever
276
- a client connects, disconnects, or sends a request.
277
- The daemon stays alive as long as at least one client
278
- is connected, regardless of the idle timer.
279
-
280
- `SO_KEEPALIVE` (30-second interval) provides a
281
- secondary mechanism for detecting dead connections
282
- beyond the counter-based idle timer. If a client
283
- process crashes without closing the socket, the OS
284
- will detect the dead peer within ~30 seconds and
285
- close the connection, allowing the daemon to
286
- decrement its counter and eventually idle-shutdown.
287
-
288
- ## Graceful Shutdown
289
-
290
- On shutdown (idle timeout or OS signal SIGTERM/SIGINT),
291
- the daemon:
292
-
293
- 1. Clears the idle timer.
294
- 2. Closes the IPC server, stopping new connections.
295
- 3. Clears the WASM module references.
296
- 4. Removes its PID file (`kbdb-{ctx}.pid`).
297
- 5. Removes the IPC socket file (`kbdb-{ctx}.sock` on
298
- Unix).
299
- 6. Removes the crash log (`kbdb-{ctx}.crash`) if it
300
- exists.
301
- 7. Calls `process.exit(0)`.
302
-
303
- ## WASM Modules
304
-
305
- The daemon loads four WASM modules at startup. Three
306
- share a single `WebAssembly.Memory` and are wired
307
- together via imports; the fourth is a standalone
308
- pure-computation module.
309
-
310
- ```
311
- query-parser.wasm (standalone)
312
- fs-database.wasm (standalone)
313
- default-embedding.wasm (standalone, no host imports)
314
-
315
- kb-worker.wasm
316
- (imports query-parser + fs-database)
317
-
318
- host I/O imports (TypeScript)
319
- ```
320
-
321
- ### WASM Module: kb-worker.wasm
322
-
323
- `kb-worker.wasm` is the orchestration module. Its
324
- responsibilities:
325
-
326
- - **Query orchestration** -- Parses queries, performs
327
- index lookups, scores and ranks results.
328
- - **Write orchestration** -- Tokenizes content per
329
- field and stores pre-computed term frequencies,
330
- positions, and token counts in the database.
331
- - **Cache management** -- Manages the LRU cache of
332
- sections, indexes, and manifests internally.
333
- - **Result tokens** -- Manages async query tokens for
334
- IPC callers.
335
-
336
- ### Module Loading
337
-
338
- When the daemon starts (after all startup preconditions
339
- pass), it:
340
-
341
- 1. Creates a deferred `MemoryRef` (initially `null`)
342
- and `AllocatorRef` (initially `null`).
343
- 2. Builds the host I/O import record using
344
- `createHostImports`, passing the context path and
345
- both deferred refs.
346
- 3. Reads `kbdb_worker_bg.wasm` from the WASM build
347
- output directory (`kb-worker/kbdb_worker_bg.wasm`).
348
- 4. Compiles the WASM bytes with `WebAssembly.compile`.
349
- 5. Instantiates the module with `WebAssembly.instantiate`,
350
- providing `{ env: { ...hostImports } }`.
351
- 6. Wires the `MemoryRef` to the module's exported
352
- `memory` and the `AllocatorRef` to the module's
353
- exported `kbdb_alloc`.
354
- 7. Calls `worker_init(pathBytes)` to open the database
355
- context (passes `.` as the path, resolved relative
356
- to the context path).
357
-
358
- The `WasmModules` record tracks only two fields:
359
-
360
- ```typescript
361
- interface WasmModules {
362
- readonly memory: WebAssembly.Memory;
363
- readonly kbWorker: WebAssembly.Instance;
364
- }
365
- ```
366
-
367
- The module exports its own linear memory (not imported
368
- externally). Host I/O imports read and write it through
369
- the deferred `MemoryRef`.
370
-
371
- ### Host I/O Imports
372
-
373
- The `kb-worker.wasm` module calls back into TypeScript
374
- for all filesystem operations. The host import record
375
- (`createHostImports`) provides:
376
-
377
- | Import name | Description |
378
- |-------------------|--------------------------------------------|
379
- | `host_read_file` | Read file bytes; out-pointer protocol |
380
- | `host_write_file` | Write bytes to file |
381
- | `host_rename` | Rename (atomic swap) a file |
382
- | `host_remove_file`| Delete a file |
383
- | `host_list_dir` | List directory entries; out-pointer protocol |
384
- | `host_mkdir` | Create directory recursively |
385
- | `host_file_exists`| Check if a file exists (returns 1 or 0) |
386
-
387
- All paths passed from WASM are relative; the host
388
- resolves them against the `contextPath`. Out-pointer
389
- functions (`host_read_file`, `host_list_dir`) allocate
390
- a buffer in WASM memory via `allocator.alloc` and write
391
- the pointer and length back to WASM-provided addresses.
392
-
393
- ### WASM Memory Management
394
-
395
- The TypeScript layer uses four WASM exports to manage
396
- shared memory:
397
-
398
- | Export | Signature | Purpose |
399
- |-------------------|----------------------------------|-----------------------|
400
- | `kbdb_alloc` | `(size: i32) -> i32` | Allocate WASM memory |
401
- | `kbdb_free` | `(ptr: i32, size: i32) -> void` | Free WASM memory |
402
- | `get_return_ptr` | `() -> i32` | Read return slot ptr |
403
- | `get_return_len` | `() -> i32` | Read return slot len |
404
-
405
- For call conventions that pass input data:
406
-
407
- 1. Encode the input as bytes.
408
- 2. Allocate a buffer with `kbdb_alloc(len)`.
409
- 3. Write the bytes into WASM memory at the returned
410
- pointer.
411
- 4. Call the WASM export with `(ptr, len)`.
412
- 5. Free the input buffer with `kbdb_free(ptr, len)`.
413
- 6. Read the return slot with `get_return_ptr()` and
414
- `get_return_len()`, copy the bytes, then free
415
- the return buffer.
416
-
417
- Zero-argument WASM exports (no input data) are called
418
- directly; only the return slot is read afterward.
419
-
420
- Return code `-1` (as a signed i32) signals an error;
421
- the return slot contains a UTF-8 error message.
422
-
423
- ## Configuration
424
-
425
- Daemon configuration is stored in
426
- `${context_path}/worker.toml`. The daemon reads it at
427
- startup via `readConfig`. If the file is absent or
428
- unreadable, all defaults apply. The `DaemonConfig`
429
- interface uses camelCase properties:
430
-
431
- ```typescript
432
- interface DaemonConfig {
433
- readonly contextPath: string;
434
- readonly itemLimit: number;
435
- readonly indexLimit: number;
436
- readonly timeoutMs: number;
437
- readonly itemTtlMs: number;
438
- }
439
- ```
440
-
441
- Settings (TOML keys map to camelCase properties):
442
-
443
- | TOML key | Property | Description | Default |
444
- |----------------|---------------|--------------------------------------|----------------|
445
- | `item_limit` | `itemLimit` | Max content objects held in cache | 1000 |
446
- | `index_limit` | `indexLimit` | Max index segments held in cache | 100 |
447
- | `timeout_ms` | `timeoutMs` | Daemon idle timeout in milliseconds | 300000 (5 min) |
448
- | `item_ttl_ms` | `itemTtlMs` | Per-item cache TTL in milliseconds | 60000 (1 min) |
449
-
450
- The `contextPath` field is always set from the runtime
451
- argument; it is not read from `worker.toml`.
452
-
453
- Example `worker.toml`:
454
-
455
- ```toml
456
- item_limit = 2000
457
- index_limit = 200
458
- timeout_ms = 600000
459
- item_ttl_ms = 120000
460
- ```
461
-
462
- Configuration is set once when the daemon spawns and
463
- does not change until the daemon shuts down and a new
464
- one is spawned.
465
-
466
- ### Client vs Daemon Timeouts
467
-
468
- The `KBDB_DAEMON_TIMEOUT` environment variable (or
469
- `--timeout-ms` CLI flag) controls the **client-side
470
- request timeout** -- how long a CLI or MCP client
471
- waits for a response from the daemon before giving
472
- up and optionally retrying.
473
-
474
- The `timeout_ms` setting in `worker.toml` controls
475
- the **daemon-side idle timeout** -- how long the
476
- daemon stays alive after all client connections have
477
- closed.
478
-
479
- These are independent. A long-running query may
480
- exceed the client request timeout while the daemon
481
- continues processing. Conversely, a short idle
482
- timeout shuts the daemon down quickly between
483
- invocations but has no effect on in-flight
484
- requests.
485
-
486
- ## IPC Transport
487
-
488
- The daemon listens on a local IPC channel:
489
-
490
- - **Linux / macOS** -- Unix domain socket at
491
- `{tmpdir}/kbdb-{ctx}.sock`
492
- (e.g., `/tmp/kbdb-a1b2c3d4e5f67890.sock`).
493
- - **Windows** -- Named pipe at
494
- `\\.\pipe\kbdb-{ctx}`.
495
-
496
- The IPC path is computed by the platform-specific
497
- `getIpcPath(ctx)` function.
498
-
499
- Both Deno and Node.js support Unix domain sockets and
500
- Windows named pipes natively:
501
-
502
- - **Node.js** -- `net.createServer()` with
503
- `server.listen(path)` and
504
- `net.createConnection(path)`.
505
-
506
- No third-party IPC library is required. The daemon
507
- creates the IPC socket at startup and removes it on
508
- shutdown.
509
-
510
- ### Socket Options
511
-
512
- - **Backlog**: `256`. Handles connection bursts from
513
- concurrent CLI invocations and benchmarks without
514
- dropping connections.
515
- - **SO_KEEPALIVE**: Enabled on every accepted
516
- connection with a 30-second interval. Detects dead
517
- clients without relying solely on the idle timer.
518
- Both the server and client enable keepalive (see
519
- [Worker Client](worker-client.md)).
520
-
521
- ## IPC Protocol
522
-
523
- Communication uses **JSON-RPC 2.0** over the IPC
524
- channel. Each request is a JSON-RPC call with a method
525
- name and params; each response is a JSON-RPC result or
526
- error.
527
-
528
- Messages are delimited by newlines. Each JSON-RPC
529
- message is a single line of JSON followed by `\n`. This
530
- provides simple framing over the stream-oriented IPC
531
- transport.
532
-
533
- Every request includes a `ctx` param -- the context ID.
534
- The daemon verifies the `ctx` matches its own context
535
- and returns a JSON-RPC error (`-32001`, "context
536
- mismatch") if it does not.
537
-
538
- ## Method Routing
539
-
540
- The daemon dispatches each IPC method to one of three
541
- categories:
542
-
543
- 1. **Daemon-state methods** -- handled directly in
544
- TypeScript without touching WASM.
545
- 2. **Config methods** (`config_{key}`) -- read from
546
- `DaemonConfig` in TypeScript.
547
- 3. **WASM methods** -- routed through `WASM_METHOD_MAP`
548
- to a named `kb-worker.wasm` export.
549
-
550
- ### WASM Method Map
551
-
552
- The daemon accepts both camelCase and snake_case aliases
553
- for each WASM operation:
554
-
555
- | IPC method(s) | WASM export |
556
- |-----------------------------------------|--------------------------|
557
- | `search`, `query` | `worker_search` |
558
- | `addSection`, `add_section` | `worker_add_section` |
559
- | `updateSection`, `update_section` | `worker_update_section` |
560
- | `removeSection`, `remove_section` | `worker_remove_section` |
561
- | `readSections`, `read_sections` | `worker_read_sections` |
562
- | `groupSections`, `group_sections` | `worker_group_sections` |
563
- | `removeGrouping`, `remove_grouping` | `worker_remove_grouping` |
564
- | `retrieveDocument`, `retrieve_doc` | `worker_retrieve_doc` |
565
- | `content`, `compose` | `worker_compose` |
566
- | `integrityCheck`, `integrity_check` | `worker_check_integrity` |
567
- | `gc` | `worker_garbage_collect` |
568
- | `rebuildIndexes`, `rebuild_indexes` | `worker_rebuild_indexes` |
569
- | `initDirectory`, `init_directory` | `worker_init_directory` |
570
- | `migrateDatabase` | (not yet supported) |
571
- | `query` | `worker_query` |
572
- | `get_result_status` | `worker_result_status` |
573
- | `get_result` | `worker_get_result` |
574
- | `invalidate` | `worker_invalidate` |
575
- | `invalidateAll`, `invalidate_all` | `worker_invalidate_all` |
576
- | `dbStatus`, `db_status` | `worker_status` |
577
- | `listByType`, `list_by_type` | `worker_list_by_type` |
578
- | `listDocumentsByType` | `worker_list_docs_by_type` |
579
- | `recall` | `worker_recall` |
580
- | `export` | `db_export` |
581
-
582
- `migrateDatabase` is listed in the map but throws
583
- `IpcError(-32601, 'migrateDatabase is not yet
584
- supported')` when called.
585
-
586
- ## IPC API -- Daemon-State Methods
587
-
588
- These methods are handled in TypeScript without WASM
589
- calls.
590
-
591
- ### `status`
592
-
593
- Returns the daemon's current state.
594
-
595
- ```json
596
- // Request
597
- {
598
- "jsonrpc": "2.0",
599
- "method": "status",
600
- "params": { "ctx": "<context-id>" },
601
- "id": 1
602
- }
603
-
604
- // Response
605
- {
606
- "jsonrpc": "2.0", "id": 1,
607
- "result": {
608
- "state": "busy",
609
- "integrity_ok": true,
610
- "integrity_errors": []
611
- }
612
- }
613
- ```
614
-
615
- Result fields:
616
-
617
- | Field | Type | Description |
618
- |--------------------|----------|-------------------------------------------|
619
- | `state` | string | `"busy"` if connections > 0, else `"idle"` |
620
- | `integrity_ok` | boolean | `true` if startup health check passed |
621
- | `integrity_errors` | string[] | Error types from `db_check_integrity`; |
622
- | | | empty when `integrity_ok` is `true` |
623
-
624
- ### `idle_at`
625
-
626
- Returns the Unix timestamp (in seconds) when the last
627
- transaction completed.
628
-
629
- ```json
630
- // Request
631
- {
632
- "jsonrpc": "2.0",
633
- "method": "idle_at",
634
- "params": { "ctx": "<context-id>" },
635
- "id": 2
636
- }
637
-
638
- // Response
639
- {
640
- "jsonrpc": "2.0", "id": 2,
641
- "result": 1750012800
642
- }
643
- ```
644
-
645
- Result: integer (Unix epoch seconds). `0` if no
646
- transaction has completed since startup.
647
-
648
- ### `config_{key}`
649
-
650
- Returns a configuration value. Method name is `config_`
651
- followed by the TOML key name.
652
-
653
- | Method | DaemonConfig property | Returns |
654
- |----------------------|-----------------------|------------------------------|
655
- | `config_timeout_ms` | `timeoutMs` | Daemon idle timeout in ms |
656
- | `config_item_ttl_ms` | `itemTtlMs` | Per-item cache TTL in ms |
657
- | `config_item_limit` | `itemLimit` | Max cached content objects |
658
- | `config_index_limit` | `indexLimit` | Max cached index segments |
659
-
660
- ```json
661
- // Request
662
- {
663
- "jsonrpc": "2.0",
664
- "method": "config_timeout_ms",
665
- "params": { "ctx": "<context-id>" },
666
- "id": 3
667
- }
668
-
669
- // Response
670
- {
671
- "jsonrpc": "2.0", "id": 3,
672
- "result": 300000
673
- }
674
- ```
675
-
676
- ### `checkVersion`
677
-
678
- Reads `catalog.toml` from the given path (or the
679
- daemon's own context path) and returns a version status
680
- object. Does not require the daemon to be fully started.
681
-
682
- **Request params:**
683
-
684
- | Param | Type | Required | Description |
685
- |--------------|--------|----------|-----------------------------------|
686
- | `ctx` | string | yes | Context ID |
687
- | `targetPath` | string | no | Path to read catalog from; defaults to `contextPath` |
688
-
689
- **Response (`VersionStatus`):**
690
-
691
- | Field | Type | Values |
692
- |-------------------|--------|----------------------------------------------|
693
- | `status` | string | `"compatible"` \| `"needs_migration"` \| `"too_new"` |
694
- | `currentVersion` | number | Version found in catalog (0 if absent) |
695
- | `requiredVersion` | number | `DB_FORMAT_VERSION` (currently `1`) |
696
-
697
- ```json
698
- // Request
699
- {
700
- "jsonrpc": "2.0",
701
- "method": "checkVersion",
702
- "params": { "ctx": "<context-id>" },
703
- "id": 4
704
- }
705
-
706
- // Response
707
- {
708
- "jsonrpc": "2.0", "id": 4,
709
- "result": {
710
- "status": "compatible",
711
- "currentVersion": 1,
712
- "requiredVersion": 1
713
- }
714
- }
715
- ```
716
-
717
- ## IPC API -- WASM Read Methods
718
-
719
- ### `search` / `query`
720
-
721
- Submits a full-text search query. The daemon encodes
722
- the params, calls `worker_search`, and decodes the
723
- result synchronously. Returns a `ScoredResult[]` array.
724
-
725
- **Request params:**
726
-
727
- | Param | Type | Required | Description |
728
- |----------|--------|----------|-------------------------------|
729
- | `ctx` | string | yes | Context ID |
730
- | `query` | string | yes | Query text |
731
- | `mode` | string | no | `"and"` (default) or `"or"` |
732
- | `limit` | number | no | Max results (default 20) |
733
- | `offset` | number | no | Zero-based result offset (default 0) |
734
-
735
- ```json
736
- // Request
737
- {
738
- "jsonrpc": "2.0",
739
- "method": "search",
740
- "params": {
741
- "ctx": "<context-id>",
742
- "query": "TypeScript architecture",
743
- "mode": "and",
744
- "limit": 10
745
- },
746
- "id": 5
747
- }
748
-
749
- // Response
750
- {
751
- "jsonrpc": "2.0", "id": 5,
752
- "result": {
753
- "items": [
754
- {
755
- "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3",
756
- "heading": "Architecture Overview",
757
- "type": "text/markdown",
758
- "docids": ["doc-5678"],
759
- "snippet": "The system is organized...",
760
- "matched_terms": ["architecture", "system"],
761
- "score": 8.7432
762
- }
763
- ],
764
- "total": 42,
765
- "offset": 0,
766
- "limit": 20,
767
- "has_more": true
768
- }
769
- }
770
- ```
771
-
772
- Note: the IPC layer keeps `score` (CLI uses it). The
773
- MCP layer strips it.
774
-
775
- Result: `PagedSearchResult` decoded from the WASM
776
- binary return slot.
777
-
778
- ### `get_result_status`
779
-
780
- Checks the status of a previously submitted async
781
- operation by its numeric token.
782
-
783
- **Request params:**
784
-
785
- | Param | Type | Description |
786
- |---------|--------|------------------------|
787
- | `ctx` | string | Context ID |
788
- | `token` | number | Token from prior call |
789
-
790
- ```json
791
- // Request
792
- {
793
- "jsonrpc": "2.0",
794
- "method": "get_result_status",
795
- "params": { "ctx": "<context-id>", "token": 42 },
796
- "id": 6
797
- }
798
-
799
- // Response
800
- {
801
- "jsonrpc": "2.0", "id": 6,
802
- "result": { "status": 2 }
803
- }
804
- ```
805
-
806
- Result: `{ status: number }` -- the raw status code
807
- from `worker_result_status`.
808
-
809
- ### `get_result`
810
-
811
- Retrieves the result for a previously submitted async
812
- operation by its numeric token. Decodes the return slot
813
- as `ScoredResult[]`.
814
-
815
- **Request params:**
816
-
817
- | Param | Type | Description |
818
- |---------|--------|------------------------|
819
- | `ctx` | string | Context ID |
820
- | `token` | number | Token from prior call |
821
-
822
- ```json
823
- // Request
824
- {
825
- "jsonrpc": "2.0",
826
- "method": "get_result",
827
- "params": { "ctx": "<context-id>", "token": 42 },
828
- "id": 7
829
- }
830
-
831
- // Response
832
- {
833
- "jsonrpc": "2.0", "id": 7,
834
- "result": [
835
- { "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3", "score": 0.95 }
836
- ]
837
- }
838
- ```
839
-
840
- ### `readSections` / `read_sections`
841
-
842
- Reads multiple sections by kb-id. Returns an array of
843
- `SectionRecord` objects decoded from the WASM binary.
844
-
845
- **Request params:**
846
-
847
- | Param | Type | Description |
848
- |----------|----------|--------------------------------|
849
- | `ctx` | string | Context ID |
850
- | `kbids` | string[] | List of section IDs to read |
851
-
852
- ```json
853
- // Request
854
- {
855
- "jsonrpc": "2.0",
856
- "method": "readSections",
857
- "params": {
858
- "ctx": "<context-id>",
859
- "kbids": [
860
- "a1b2c3d4e5f6g7h8j9k0l1m2n3",
861
- "p4q5r6s7t8u9v0w1x2y3z4a5b6"
862
- ]
863
- },
864
- "id": 8
865
- }
866
-
867
- // Response
868
- {
869
- "jsonrpc": "2.0", "id": 8,
870
- "result": [
871
- {
872
- "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3",
873
- "docids": ["doc-5678"],
874
- "type": "text/markdown",
875
- "title": "Architecture Overview",
876
- "description": "High-level overview",
877
- "content": "Section body text..."
878
- }
879
- ]
880
- }
881
- ```
882
-
883
- ### `recall`
884
-
885
- Progressive context expansion for one or more
886
- sections. Returns section content plus, depending
887
- on the `depth` parameter, parent documents,
888
- sibling sections, forward references, and
889
- back-references from the reference graph index.
890
-
891
- **Request params:**
892
-
893
- | Param | Type | Required | Description |
894
- |---------|----------|----------|--------------------------|
895
- | `ctx` | string | yes | Context ID |
896
- | `kbid` | string | no* | Single section ID |
897
- | `kbids` | string[] | no* | Batch section IDs |
898
- | `depth` | number | no | Expansion depth (0--3, default 0) |
899
-
900
- *At least one of `kbid` or `kbids` required.
901
-
902
- The daemon calls `worker_recall` in the WASM
903
- engine, which reads sections, optionally looks up
904
- parent documents, sibling sections, forward
905
- references, and back-references from
906
- `references.idx` depending on the requested depth.
907
-
908
- Result: `RecallResult` (single) or
909
- `RecallResult[]` (batch) decoded from the WASM
910
- binary return slot.
911
-
912
- ### `retrieveDocument` / `retrieve_doc`
913
-
914
- Retrieves a document manifest by document ID. Returns
915
- a decoded `DocumentManifest`.
916
-
917
- **Request params:**
918
-
919
- | Param | Type | Description |
920
- |---------|--------|--------------------|
921
- | `ctx` | string | Context ID |
922
- | `docid` | string | Document ID |
923
-
924
- ```json
925
- // Request
926
- {
927
- "jsonrpc": "2.0",
928
- "method": "retrieveDocument",
929
- "params": {
930
- "ctx": "<context-id>",
931
- "docid": "doc-5678"
932
- },
933
- "id": 9
934
- }
935
-
936
- // Response (decoded DocumentManifest)
937
- {
938
- "jsonrpc": "2.0", "id": 9,
939
- "result": { ... }
940
- }
941
- ```
942
-
943
- ### `dbStatus` / `db_status`
944
-
945
- Returns database status information. The WASM module
946
- (`worker_status`) writes a key-value text block to the
947
- return slot; the daemon decodes it and returns it as an
948
- object.
949
-
950
- **Request params:** `ctx` only.
951
-
952
- ```json
953
- // Request
954
- {
955
- "jsonrpc": "2.0",
956
- "method": "dbStatus",
957
- "params": { "ctx": "<context-id>" },
958
- "id": 10
959
- }
960
-
961
- // Response (decoded key-value text)
962
- {
963
- "jsonrpc": "2.0", "id": 10,
964
- "result": { "sections": "42", "documents": "5" }
965
- }
966
- ```
967
-
968
- ### `listByType` / `list_by_type`
969
-
970
- Returns all sections whose `sectionType` field
971
- matches the given type string. The daemon encodes the
972
- params, calls `worker_list_by_type`, and decodes the
973
- result as an array of section records.
974
-
975
- **Request params:**
976
-
977
- | Param | Type | Required | Description |
978
- |---------------|--------|----------|-----------------------------------|
979
- | `ctx` | string | yes | Context ID |
980
- | `sectionType` | string | yes | Section type to filter by |
981
-
982
- ```json
983
- // Request
984
- {
985
- "jsonrpc": "2.0",
986
- "method": "listByType",
987
- "params": {
988
- "ctx": "<context-id>",
989
- "sectionType": "skill"
990
- },
991
- "id": 23
992
- }
993
-
994
- // Response
995
- {
996
- "jsonrpc": "2.0", "id": 23,
997
- "result": [
998
- {
999
- "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3",
1000
- "docids": [],
1001
- "type": "skill",
1002
- "title": "summarize-document",
1003
- "description": "Summarize a document into
1004
- key points",
1005
- "content": "{\"name\":\"summarize-document\",...}"
1006
- }
1007
- ]
1008
- }
1009
- ```
1010
-
1011
- Result: array of `SectionRecord` objects filtered by
1012
- the requested `sectionType`. Returns an empty array
1013
- when no sections match.
1014
-
1015
- ### `listDocumentsByType`
1016
-
1017
- Returns all document manifests whose `type` field
1018
- matches the given document type string. The daemon
1019
- encodes the params, calls `worker_list_docs_by_type`,
1020
- and decodes the result as an array of document
1021
- manifests.
1022
-
1023
- **Request params:**
1024
-
1025
- | Param | Type | Required | Description |
1026
- |-----------|--------|----------|------------------------------------|
1027
- | `ctx` | string | yes | Context ID |
1028
- | `docType` | string | yes | Document type to filter by |
1029
-
1030
- ```json
1031
- // Request
1032
- {
1033
- "jsonrpc": "2.0",
1034
- "method": "listDocumentsByType",
1035
- "params": {
1036
- "ctx": "<context-id>",
1037
- "docType": "agent"
1038
- },
1039
- "id": 24
1040
- }
1041
-
1042
- // Response
1043
- {
1044
- "jsonrpc": "2.0", "id": 24,
1045
- "result": [
1046
- {
1047
- "docid": "agent-code-reviewer",
1048
- "title": "Code Reviewer Agent",
1049
- "type": "agent",
1050
- "sections": [
1051
- { "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3", "position": 0 },
1052
- { "kbid": "p4q5r6s7t8u9v0w1x2y3z4a5b6", "position": 1 }
1053
- ]
1054
- }
1055
- ]
1056
- }
1057
- ```
1058
-
1059
- Result: array of document manifest objects filtered
1060
- by the requested `docType`. Returns an empty array
1061
- when no documents match. Documents without a `type`
1062
- field are regular documents and are not returned by
1063
- this method.
1064
-
1065
- ## IPC API -- WASM Write Methods
1066
-
1067
- ### `addSection` / `add_section`
1068
-
1069
- Adds a new section to the database. The params are
1070
- binary-encoded and passed to `worker_add_section`. The
1071
- return slot contains the new section's kb-id as UTF-8.
1072
-
1073
- **Request params:**
1074
-
1075
- | Param | Type | Required | Description |
1076
- |---------------|--------|----------|-----------------------------------------------|
1077
- | `ctx` | string | yes | Context ID |
1078
- | `sectionType` | string | yes | Section type (`"text"`, `"image"`, `"code"`, etc.) |
1079
- | `mimeType` | string | no | MIME type |
1080
- | `content` | string | yes | Section content |
1081
- | `title` | string | no | Section title |
1082
- | `description` | string | no | Section description |
1083
- | `docid` | string | no | Document ID to attach this section to |
1084
-
1085
- ```json
1086
- // Request
1087
- {
1088
- "jsonrpc": "2.0",
1089
- "method": "addSection",
1090
- "params": {
1091
- "ctx": "<context-id>",
1092
- "sectionType": "text",
1093
- "mimeType": "text/markdown",
1094
- "content": "# Architecture\n\nOverview...",
1095
- "title": "Architecture Overview",
1096
- "docid": "doc-5678"
1097
- },
1098
- "id": 11
1099
- }
1100
-
1101
- // Response
1102
- {
1103
- "jsonrpc": "2.0", "id": 11,
1104
- "result": { "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3" }
1105
- }
1106
- ```
1107
-
1108
- ### `updateSection` / `update_section`
1109
-
1110
- Updates an existing section. The params are
1111
- binary-encoded and passed to `worker_update_section`.
1112
- Returns the new kb-id (content hash may change).
1113
-
1114
- **Request params:**
1115
-
1116
- | Param | Type | Required | Description |
1117
- |---------------|--------|----------|----------------------------------------|
1118
- | `ctx` | string | yes | Context ID |
1119
- | `kbid` | string | yes | Existing section ID to replace |
1120
- | `sectionType` | string | yes | New section type |
1121
- | `mimeType` | string | no | New MIME type |
1122
- | `content` | string | yes | New content |
1123
- | `title` | string | no | New title |
1124
- | `description` | string | no | New description |
1125
- | `docid` | string | no | Document ID |
1126
-
1127
- ```json
1128
- // Request
1129
- {
1130
- "jsonrpc": "2.0",
1131
- "method": "updateSection",
1132
- "params": {
1133
- "ctx": "<context-id>",
1134
- "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3",
1135
- "sectionType": "text",
1136
- "content": "Updated content...",
1137
- "title": "Updated Title"
1138
- },
1139
- "id": 12
1140
- }
1141
-
1142
- // Response
1143
- {
1144
- "jsonrpc": "2.0", "id": 12,
1145
- "result": { "kbid": "x9y8z7w6v5u4t3s2r1q0p9o8n7" }
1146
- }
1147
- ```
1148
-
1149
- ### `removeSection` / `remove_section`
1150
-
1151
- Removes a section by kb-id. The kb-id is UTF-8 encoded
1152
- and passed to `worker_remove_section`. The return flag
1153
- is decoded by `decodeRemoveFlag`.
1154
-
1155
- **Request params:**
1156
-
1157
- | Param | Type | Description |
1158
- |---------|--------|-------------------------|
1159
- | `ctx` | string | Context ID |
1160
- | `kbid` | string | Section ID to remove |
1161
-
1162
- ```json
1163
- // Request
1164
- {
1165
- "jsonrpc": "2.0",
1166
- "method": "removeSection",
1167
- "params": {
1168
- "ctx": "<context-id>",
1169
- "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3"
1170
- },
1171
- "id": 13
1172
- }
1173
-
1174
- // Response
1175
- {
1176
- "jsonrpc": "2.0", "id": 13,
1177
- "result": { "removed": true }
1178
- }
1179
- ```
1180
-
1181
- ### `groupSections` / `group_sections`
1182
-
1183
- Groups a set of sections into a named document. Params
1184
- are binary-encoded and passed to `worker_group_sections`.
1185
- Returns the new document ID.
1186
-
1187
- **Request params:**
1188
-
1189
- | Param | Type | Description |
1190
- |---------|----------|-----------------------------------|
1191
- | `ctx` | string | Context ID |
1192
- | `title` | string | Document title |
1193
- | `kbids` | string[] | Section IDs to group |
1194
-
1195
- ```json
1196
- // Request
1197
- {
1198
- "jsonrpc": "2.0",
1199
- "method": "groupSections",
1200
- "params": {
1201
- "ctx": "<context-id>",
1202
- "title": "Architecture Guide",
1203
- "kbids": [
1204
- "a1b2c3d4e5f6g7h8j9k0l1m2n3",
1205
- "p4q5r6s7t8u9v0w1x2y3z4a5b6"
1206
- ]
1207
- },
1208
- "id": 14
1209
- }
1210
-
1211
- // Response
1212
- {
1213
- "jsonrpc": "2.0", "id": 14,
1214
- "result": { "docid": "doc-5678" }
1215
- }
1216
- ```
1217
-
1218
- ### `removeGrouping` / `remove_grouping`
1219
-
1220
- Removes a document grouping (the manifest), leaving
1221
- the underlying sections intact. The document ID is
1222
- UTF-8 encoded and passed to `worker_remove_grouping`.
1223
-
1224
- **Request params:**
1225
-
1226
- | Param | Type | Description |
1227
- |---------|--------|----------------------|
1228
- | `ctx` | string | Context ID |
1229
- | `docid` | string | Document ID to ungroup |
1230
-
1231
- ```json
1232
- // Request
1233
- {
1234
- "jsonrpc": "2.0",
1235
- "method": "removeGrouping",
1236
- "params": {
1237
- "ctx": "<context-id>",
1238
- "docid": "doc-5678"
1239
- },
1240
- "id": 15
1241
- }
1242
-
1243
- // Response
1244
- {
1245
- "jsonrpc": "2.0", "id": 15,
1246
- "result": { "ok": true }
1247
- }
1248
- ```
1249
-
1250
- ### `content` / `compose`
1251
-
1252
- Composes a rendered Markdown document from one or more
1253
- kbid or docid identifiers. The identifiers are
1254
- binary-encoded and passed to `worker_compose`. The
1255
- return slot is decoded by `decodeComposeOutput`.
1256
-
1257
- **Request params:**
1258
-
1259
- | Param | Type | Description |
1260
- |---------|----------|----------------------------------------|
1261
- | `ctx` | string | Context ID |
1262
- | `ids` | string[] | kbids or docids to compose |
1263
-
1264
- ```json
1265
- // Request
1266
- {
1267
- "jsonrpc": "2.0",
1268
- "method": "compose",
1269
- "params": {
1270
- "ctx": "<context-id>",
1271
- "ids": [
1272
- "a1b2c3d4e5f6g7h8j9k0l1m2n3",
1273
- "doc-5678"
1274
- ]
1275
- },
1276
- "id": 16
1277
- }
1278
-
1279
- // Response
1280
- {
1281
- "jsonrpc": "2.0", "id": 16,
1282
- "result": {
1283
- "data": "# Architecture Guide\n\n...",
1284
- "total": 4096
1285
- }
1286
- }
1287
- ```
1288
-
1289
- Result fields:
1290
-
1291
- | Field | Type | Description |
1292
- |---------|--------|-----------------------------------------------|
1293
- | `data` | string | Rendered Markdown string (`output.markdown`) |
1294
- | `total` | number | Total character count (`output.totalChars`) |
1295
-
1296
- ### `invalidate`
1297
-
1298
- Evicts a single cached entry by kb-id. The kb-id is
1299
- UTF-8 encoded and passed to `worker_invalidate`.
1300
-
1301
- **Request params:**
1302
-
1303
- | Param | Type | Description |
1304
- |---------|--------|------------------------|
1305
- | `ctx` | string | Context ID |
1306
- | `kbid` | string | Section ID to evict |
1307
-
1308
- ```json
1309
- // Request
1310
- {
1311
- "jsonrpc": "2.0",
1312
- "method": "invalidate",
1313
- "params": {
1314
- "ctx": "<context-id>",
1315
- "kbid": "a1b2c3d4e5f6g7h8j9k0l1m2n3"
1316
- },
1317
- "id": 17
1318
- }
1319
-
1320
- // Response
1321
- {
1322
- "jsonrpc": "2.0", "id": 17,
1323
- "result": { "ok": true }
1324
- }
1325
- ```
1326
-
1327
- ### `invalidateAll` / `invalidate_all`
1328
-
1329
- Evicts the entire WASM cache by calling
1330
- `worker_invalidate_all` with no arguments.
1331
-
1332
- **Request params:** `ctx` only.
1333
-
1334
- ```json
1335
- // Request
1336
- {
1337
- "jsonrpc": "2.0",
1338
- "method": "invalidateAll",
1339
- "params": { "ctx": "<context-id>" },
1340
- "id": 18
1341
- }
1342
-
1343
- // Response
1344
- {
1345
- "jsonrpc": "2.0", "id": 18,
1346
- "result": { "ok": true }
1347
- }
1348
- ```
1349
-
1350
- ### `initDirectory` / `init_directory`
1351
-
1352
- Initialises a new database directory. The path is
1353
- UTF-8 encoded and passed to `worker_init_directory`.
1354
- When `path` is omitted, the daemon uses its own
1355
- `targetDir`.
1356
-
1357
- **Request params:**
1358
-
1359
- | Param | Type | Required | Description |
1360
- |---------|--------|----------|----------------------------------------------|
1361
- | `ctx` | string | yes | Context ID |
1362
- | `path` | string | no | Path to initialise; defaults to `targetDir` |
1363
-
1364
- ```json
1365
- // Request
1366
- {
1367
- "jsonrpc": "2.0",
1368
- "method": "initDirectory",
1369
- "params": { "ctx": "<context-id>" },
1370
- "id": 19
1371
- }
1372
-
1373
- // Response
1374
- {
1375
- "jsonrpc": "2.0", "id": 19,
1376
- "result": { "ok": true }
1377
- }
1378
- ```
1379
-
1380
- ## IPC API -- Maintenance Methods
1381
-
1382
- Maintenance methods perform database-wide operations.
1383
- They call WASM and return results directly.
1384
-
1385
- ### `integrityCheck` / `integrity_check`
1386
-
1387
- Verifies the integrity of the database. Calls
1388
- `worker_check_integrity` with no arguments. The return
1389
- slot contains a key-value text block decoded by
1390
- `decodeKeyValueText`.
1391
-
1392
- **Request params:** `ctx` only.
1393
-
1394
- ```json
1395
- // Request
1396
- {
1397
- "jsonrpc": "2.0",
1398
- "method": "integrityCheck",
1399
- "params": { "ctx": "<context-id>" },
1400
- "id": 20
1401
- }
1402
-
1403
- // Response (decoded key-value text as object)
1404
- {
1405
- "jsonrpc": "2.0", "id": 20,
1406
- "result": { "ok": "true", "sections_checked": "42" }
1407
- }
1408
- ```
1409
-
1410
- ### `gc`
1411
-
1412
- Removes section files not referenced by any document
1413
- manifest. Calls `worker_garbage_collect` with no
1414
- arguments. The return slot contains a key-value text
1415
- block decoded by `decodeKeyValueText`.
1416
-
1417
- **Request params:** `ctx` only.
1418
-
1419
- ```json
1420
- // Request
1421
- {
1422
- "jsonrpc": "2.0",
1423
- "method": "gc",
1424
- "params": { "ctx": "<context-id>" },
1425
- "id": 21
1426
- }
1427
-
1428
- // Response (decoded key-value text as object)
1429
- {
1430
- "jsonrpc": "2.0", "id": 21,
1431
- "result": { "removed_sections": "3", "removed_bytes": "15360" }
1432
- }
1433
- ```
1434
-
1435
- ### `rebuildIndexes` / `rebuild_indexes`
1436
-
1437
- Reconstructs all index files from section files and
1438
- document manifests on disk. Calls
1439
- `worker_rebuild_indexes` with no arguments. Returns
1440
- `{ ok: true }` on success.
1441
-
1442
- **Request params:** `ctx` only.
1443
-
1444
- ```json
1445
- // Request
1446
- {
1447
- "jsonrpc": "2.0",
1448
- "method": "rebuildIndexes",
1449
- "params": { "ctx": "<context-id>" },
1450
- "id": 22
1451
- }
1452
-
1453
- // Response
1454
- {
1455
- "jsonrpc": "2.0", "id": 22,
1456
- "result": { "ok": true }
1457
- }
1458
- ```
1459
-
1460
- ## Error Responses
1461
-
1462
- JSON-RPC 2.0 error format for invalid requests:
1463
-
1464
- ```json
1465
- {
1466
- "jsonrpc": "2.0", "id": 11,
1467
- "error": {
1468
- "code": -32601,
1469
- "message": "Method not found: unknownMethod"
1470
- }
1471
- }
1472
- ```
1473
-
1474
- Standard JSON-RPC 2.0 error codes apply. Application
1475
- errors use codes in the `-32000` to `-32099` range:
1476
-
1477
- | Code | Meaning |
1478
- |----------|--------------------------------------|
1479
- | `-32001` | Context mismatch |
1480
- | `-32700` | Parse error (malformed JSON line) |
1481
- | `-32601` | Method not found |
1482
- | `-32000` | WASM call error (message from WASM) |
1483
-
1484
- Startup errors (`-32004` through `-32007` in previous
1485
- versions of this document) are not returned over IPC
1486
- because the daemon exits before creating the IPC
1487
- socket. They are communicated via stderr and the crash
1488
- log.
1489
-
1490
- ## Source Files
1491
-
1492
- The worker daemon module lives in
1493
- `src/shared/worker-daemon/` with the following
1494
- structure:
1495
-
1496
- ```
1497
- src/shared/worker-daemon/
1498
- classes/
1499
- worker-daemon.class.ts # WorkerDaemon class
1500
- functions/
1501
- create-host-imports.function.ts # WASM host I/O imports
1502
- create-ipc-server.function.ts # IPC socket server
1503
- load-wasm-modules.function.ts # WASM compilation/instantiation
1504
- read-config.function.ts # worker.toml parser
1505
- run-worker.function.ts # entry-point logic
1506
- start-daemon.function.ts # startup orchestration
1507
- constants/
1508
- daemon-defaults.constant.ts # defaults + DB_FORMAT_VERSION
1509
- typings/
1510
- daemon-config.interface.ts # DaemonConfig
1511
- ipc-handler.interface.ts # IpcRequest, IpcResponse, IpcHandler
1512
- wasm-modules.interface.ts # WasmModules
1513
- wasm/
1514
- kb-worker/
1515
- kbdb_worker_bg.wasm # compiled WASM (gitignored)
1516
- ```
1517
-
1518
- The `run-worker.function.ts` implements the entry-point
1519
- logic (argument validation and calling `startDaemon`).
1520
- The `start-daemon.function.ts` orchestrates the full
1521
- startup sequence: reads config, computes the context ID,
1522
- constructs `WorkerDaemon`, checks preconditions, starts
1523
- the daemon, and installs signal handlers.
1524
-
1525
- ## Distribution
1526
-
1527
- The worker daemon (`src/worker.ts` and its compiled
1528
- `kbdb-worker.js`) ships as part of the npm/JSR package.
1529
- No per-platform native binaries are required.
1530
-
1531
- The package includes four WASM modules:
1532
-
1533
- - `kb-worker/kbdb_worker_bg.wasm` -- orchestration
1534
- module that imports query-parser and fs-database
1535
- - `query-parser/query_parser_bg.wasm` -- tokenization
1536
- and query parsing
1537
- - `fs-database/fs_database_bg.wasm` -- filesystem
1538
- storage engine
1539
- - `default-embedding/kbdb_default_embedding_bg.wasm`
1540
- -- built-in TF-IDF embedding (standalone, no host
1541
- imports)
1542
-
1543
- All are compiled from Rust via `wasm-pack` and work
1544
- on all platforms. The daemon loads and compiles them
1545
- at startup using the runtime's `WebAssembly` API. The
1546
- daemon runs on the same runtime (Node.js or Deno) as
1547
- the worker client that spawns it.