@dikolab/kbdb 0.3.1 → 0.4.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 (468) hide show
  1. package/README.md +108 -126
  2. package/dist/chunk-BJPSPNGX.mjs +223 -0
  3. package/dist/chunk-BJPSPNGX.mjs.map +7 -0
  4. package/dist/cli.cjs +956 -319
  5. package/dist/cli.cjs.map +4 -4
  6. package/dist/cli.d.ts +9 -0
  7. package/dist/cli.mjs +840 -321
  8. package/dist/cli.mjs.map +4 -4
  9. package/dist/kbdb-worker.cjs +714 -94
  10. package/dist/kbdb-worker.cjs.map +4 -4
  11. package/dist/mod.cjs +122 -16
  12. package/dist/mod.cjs.map +3 -3
  13. package/dist/mod.d.ts +23 -2
  14. package/dist/mod.mjs +121 -16
  15. package/dist/mod.mjs.map +3 -3
  16. package/dist/src/shared/cli/functions/dispatch-command.function.d.ts +2 -1
  17. package/dist/src/shared/cli/functions/find-db.function.d.ts +7 -8
  18. package/dist/src/shared/cli/functions/handle-mcp.function.d.ts +1 -1
  19. package/dist/src/shared/cli/functions/parse-args.function.d.ts +4 -3
  20. package/dist/src/shared/cli/functions/resolve-kbid-prefix.function.d.ts +27 -0
  21. package/dist/src/shared/cli/functions/resolve-raw-db-path.function.d.ts +10 -0
  22. package/dist/src/shared/cli/functions/run-cli.function.d.ts +3 -1
  23. package/dist/src/shared/cli/functions/run-content.function.d.ts +8 -3
  24. package/dist/src/shared/cli/functions/run-import.function.d.ts +27 -0
  25. package/dist/src/shared/cli/functions/run-recall.function.d.ts +10 -4
  26. package/dist/src/shared/cli/functions/run-search.function.d.ts +7 -0
  27. package/dist/src/shared/cli/functions/run-unlearn.function.d.ts +9 -4
  28. package/dist/src/shared/cli/functions/run-worker-restart.function.d.ts +11 -0
  29. package/dist/src/shared/cli/functions/run-worker-stop.function.d.ts +11 -0
  30. package/dist/src/shared/cli/index.d.ts +2 -0
  31. package/dist/src/shared/cli/typings/cli-deps.interface.d.ts +4 -1
  32. package/dist/src/shared/cli/typings/cli-options.interface.d.ts +17 -0
  33. package/dist/src/shared/cli/typings/dispatch-client.type.d.ts +2 -1
  34. package/dist/src/shared/cli/typings/search-display.model.d.ts +6 -0
  35. package/dist/src/shared/embedding/classes/api-embedding-provider.class.d.ts +33 -0
  36. package/dist/src/shared/embedding/classes/onnx-embedding-provider.class.d.ts +33 -0
  37. package/dist/src/shared/embedding/functions/append-vector-entry.function.d.ts +14 -0
  38. package/dist/src/shared/embedding/functions/create-embedding-provider.function.d.ts +12 -0
  39. package/dist/src/shared/embedding/functions/detect-stale-vectors.function.d.ts +16 -0
  40. package/dist/src/shared/embedding/functions/parse-api-embedding-response.function.d.ts +11 -0
  41. package/dist/src/shared/embedding/functions/rebuild-vectors.function.d.ts +15 -0
  42. package/dist/src/shared/embedding/functions/scan-semantic-contradictions.function.d.ts +13 -0
  43. package/dist/src/shared/embedding/index.d.ts +7 -0
  44. package/dist/src/shared/embedding/typings/semantic-contradiction.model.d.ts +21 -0
  45. package/dist/src/shared/embedding/typings/stale-vectors-report.model.d.ts +16 -0
  46. package/dist/src/shared/mcp/classes/mcp-server.class.d.ts +22 -2
  47. package/dist/src/shared/mcp/functions/create-mcp-server.function.d.ts +6 -1
  48. package/dist/src/shared/mcp/functions/has-sampling-capability.function.d.ts +8 -0
  49. package/dist/src/shared/mcp/functions/run-auto-capture.function.d.ts +26 -0
  50. package/dist/src/shared/mcp/typings/mcp-client.interface.d.ts +2 -0
  51. package/dist/src/shared/mcp/typings/mcp-integrity-check-result.model.d.ts +24 -0
  52. package/dist/src/shared/mcp/typings/mcp-worker-client.interface.d.ts +3 -1
  53. package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
  54. package/dist/src/shared/wasm-codec/typings/paged-search-result.model.d.ts +2 -0
  55. package/dist/src/shared/worker-client/classes/worker-client.class.d.ts +31 -1
  56. package/dist/src/shared/worker-client/constants/request-timeout.constant.d.ts +2 -0
  57. package/dist/src/shared/worker-client/constants/retry-defaults.constant.d.ts +2 -0
  58. package/dist/src/shared/worker-client/functions/get-or-create-client.function.d.ts +20 -0
  59. package/dist/src/shared/worker-client/functions/retry-on-timeout.function.d.ts +17 -0
  60. package/dist/src/shared/worker-client/index.d.ts +4 -1
  61. package/dist/src/shared/worker-client/typings/import-result.model.d.ts +16 -0
  62. package/dist/src/shared/worker-client/typings/integrity-check-result.model.d.ts +24 -0
  63. package/dist/src/shared/worker-client/typings/search-params.model.d.ts +4 -0
  64. package/dist/src/shared/worker-client/typings/search-result.model.d.ts +6 -0
  65. package/dist/src/shared/worker-client/typings/worker-client-options.interface.d.ts +7 -0
  66. package/dist/src/shared/worker-daemon/classes/worker-daemon.class.d.ts +5 -0
  67. package/dist/src/shared/worker-daemon/functions/create-ipc-server.function.d.ts +11 -11
  68. package/dist/src/shared/worker-daemon/functions/embed-after-learn.function.d.ts +13 -0
  69. package/dist/src/shared/worker-daemon/functions/handle-hybrid-search.function.d.ts +44 -0
  70. package/dist/src/shared/worker-daemon/functions/handle-import.function.d.ts +14 -0
  71. package/dist/src/shared/worker-daemon/functions/handle-read-ops.function.d.ts +7 -1
  72. package/dist/src/shared/worker-daemon/functions/handle-write-ops.function.d.ts +9 -4
  73. package/dist/src/shared/worker-daemon/typings/handler-context.interface.d.ts +3 -0
  74. package/dist/wasm/fs-database/kbdb_fs_database.d.ts +16 -85
  75. package/dist/wasm/fs-database/kbdb_fs_database.js +16 -85
  76. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  77. package/dist/wasm/kb-worker/kbdb_worker.d.ts +20 -115
  78. package/dist/wasm/kb-worker/kbdb_worker.js +20 -115
  79. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  80. package/dist/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
  81. package/dist/worker.d.ts +8 -0
  82. package/dist/worker.mjs +606 -102
  83. package/dist/worker.mjs.map +4 -4
  84. package/docs/details/README.md +4 -0
  85. package/docs/details/agent-tooling.md +122 -0
  86. package/docs/details/cli.md +78 -12
  87. package/docs/details/knowledge-base.md +173 -0
  88. package/docs/details/library-api.md +42 -2
  89. package/docs/details/mcp-server.md +39 -8
  90. package/docs/details/search-and-ranking.md +56 -0
  91. package/docs/goals/cli.md +110 -34
  92. package/docs/goals/mcp.md +22 -19
  93. package/docs/goals/query-parser.md +8 -0
  94. package/docs/goals/worker-client.md +62 -1
  95. package/docs/goals/worker-daemon.md +52 -10
  96. package/docs/modules/typescript/cli.md +1 -1
  97. package/docs/modules/typescript/shared/cli/functions.md +116 -13
  98. package/docs/modules/typescript/shared/cli/module.md +33 -20
  99. package/docs/modules/typescript/shared/cli/typings.md +4 -0
  100. package/docs/modules/typescript/shared/embedding/functions.md +104 -25
  101. package/docs/modules/typescript/shared/mcp/module.md +1 -1
  102. package/docs/modules/typescript/shared/mcp/typings.md +8 -1
  103. package/docs/modules/typescript/shared/worker-client/module.md +9 -1
  104. package/docs/modules/typescript/shared/worker-client/typings.md +3 -0
  105. package/docs/modules/typescript/shared/worker-daemon/module.md +6 -3
  106. package/docs/overview.md +43 -22
  107. package/docs/release-notes/0.3.1.md +10 -0
  108. package/docs/release-notes/0.3.2.md +64 -0
  109. package/docs/release-notes/0.4.0.md +80 -0
  110. package/docs/release-notes/README.md +2 -0
  111. package/mod.ts +33 -15
  112. package/package.json +11 -10
  113. package/dist/chunk-JG2UCKLI.mjs +0 -95
  114. package/dist/chunk-JG2UCKLI.mjs.map +0 -7
  115. package/src/cli.ts +0 -71
  116. package/src/shared/auto-capture/classes/auto-capture-controller.class.ts +0 -62
  117. package/src/shared/auto-capture/constants/auto-capture-defaults.constant.ts +0 -15
  118. package/src/shared/auto-capture/functions/build-capture-prompt.function.ts +0 -27
  119. package/src/shared/auto-capture/functions/evaluate-trigger.function.ts +0 -50
  120. package/src/shared/auto-capture/index.ts +0 -7
  121. package/src/shared/auto-capture/typings/auto-capture-config.interface.ts +0 -13
  122. package/src/shared/auto-capture/typings/auto-capture-state.interface.ts +0 -13
  123. package/src/shared/auto-capture/typings/auto-capture-trigger.interface.ts +0 -7
  124. package/src/shared/cli/constants/defaults.constant.ts +0 -19
  125. package/src/shared/cli/constants/global-help.constant.ts +0 -73
  126. package/src/shared/cli/constants/help-text.constant.ts +0 -4
  127. package/src/shared/cli/constants/leaf-help.constant.ts +0 -219
  128. package/src/shared/cli/constants/memory-protocol-body.constant.ts +0 -39
  129. package/src/shared/cli/constants/query-guidance-body.constant.ts +0 -37
  130. package/src/shared/cli/constants/subcommand-help.constant.ts +0 -195
  131. package/src/shared/cli/functions/collect-files.function.ts +0 -55
  132. package/src/shared/cli/functions/compute-section-kbid.function.ts +0 -49
  133. package/src/shared/cli/functions/dispatch-command.function.ts +0 -390
  134. package/src/shared/cli/functions/ensure-db.function.ts +0 -21
  135. package/src/shared/cli/functions/error-to-message.function.ts +0 -9
  136. package/src/shared/cli/functions/find-db.function.ts +0 -20
  137. package/src/shared/cli/functions/format-mcp-output.function.ts +0 -41
  138. package/src/shared/cli/functions/format-output.function.ts +0 -95
  139. package/src/shared/cli/functions/format-text-output.function.ts +0 -42
  140. package/src/shared/cli/functions/generate-group-help.function.ts +0 -41
  141. package/src/shared/cli/functions/generate-help.function.ts +0 -654
  142. package/src/shared/cli/functions/handle-data-command.function.ts +0 -67
  143. package/src/shared/cli/functions/handle-mcp.function.ts +0 -56
  144. package/src/shared/cli/functions/handle-migrate.function.ts +0 -64
  145. package/src/shared/cli/functions/hydrate-search-previews.function.ts +0 -29
  146. package/src/shared/cli/functions/install-default-skills.function.ts +0 -296
  147. package/src/shared/cli/functions/is-stdin-tty.function.ts +0 -12
  148. package/src/shared/cli/functions/parse-args.function.ts +0 -156
  149. package/src/shared/cli/functions/prompt-user.function.ts +0 -36
  150. package/src/shared/cli/functions/resolve-skill-names.function.ts +0 -43
  151. package/src/shared/cli/functions/run-agent-create.function.ts +0 -114
  152. package/src/shared/cli/functions/run-agent-delete.function.ts +0 -47
  153. package/src/shared/cli/functions/run-agent-get.function.ts +0 -166
  154. package/src/shared/cli/functions/run-agent-list.function.ts +0 -58
  155. package/src/shared/cli/functions/run-check.function.ts +0 -159
  156. package/src/shared/cli/functions/run-cli.function.ts +0 -299
  157. package/src/shared/cli/functions/run-content.function.ts +0 -47
  158. package/src/shared/cli/functions/run-db-init.function.ts +0 -44
  159. package/src/shared/cli/functions/run-db-migrate.function.ts +0 -40
  160. package/src/shared/cli/functions/run-export.function.ts +0 -40
  161. package/src/shared/cli/functions/run-gc.function.ts +0 -51
  162. package/src/shared/cli/functions/run-init.function.ts +0 -93
  163. package/src/shared/cli/functions/run-learn.function.ts +0 -223
  164. package/src/shared/cli/functions/run-migrate.function.ts +0 -85
  165. package/src/shared/cli/functions/run-rebuild.function.ts +0 -47
  166. package/src/shared/cli/functions/run-recall.function.ts +0 -66
  167. package/src/shared/cli/functions/run-search.function.ts +0 -133
  168. package/src/shared/cli/functions/run-skill-delete.function.ts +0 -47
  169. package/src/shared/cli/functions/run-skill-get.function.ts +0 -90
  170. package/src/shared/cli/functions/run-skill-learn.function.ts +0 -70
  171. package/src/shared/cli/functions/run-skill-list.function.ts +0 -74
  172. package/src/shared/cli/functions/run-status.function.ts +0 -29
  173. package/src/shared/cli/functions/run-unlearn.function.ts +0 -58
  174. package/src/shared/cli/functions/version-gate.function.ts +0 -44
  175. package/src/shared/cli/functions/wrap-command.function.ts +0 -34
  176. package/src/shared/cli/index.ts +0 -55
  177. package/src/shared/cli/typings/agent-create-client.interface.ts +0 -47
  178. package/src/shared/cli/typings/agent-get-client.interface.ts +0 -39
  179. package/src/shared/cli/typings/check-client.interface.ts +0 -66
  180. package/src/shared/cli/typings/cli-deps.interface.ts +0 -54
  181. package/src/shared/cli/typings/cli-options.interface.ts +0 -72
  182. package/src/shared/cli/typings/command-result.model.ts +0 -15
  183. package/src/shared/cli/typings/disconnectable-client.interface.ts +0 -29
  184. package/src/shared/cli/typings/dispatch-client.type.ts +0 -46
  185. package/src/shared/cli/typings/learn-client.interface.ts +0 -53
  186. package/src/shared/cli/typings/learn-io.interface.ts +0 -5
  187. package/src/shared/cli/typings/learn-result.model.ts +0 -27
  188. package/src/shared/cli/typings/search-client.interface.ts +0 -73
  189. package/src/shared/cli/typings/search-display.model.ts +0 -54
  190. package/src/shared/dir-resolver/functions/join-path.function.ts +0 -13
  191. package/src/shared/dir-resolver/functions/resolve-base-dir.function.ts +0 -25
  192. package/src/shared/dir-resolver/functions/resolve-wasm-dir.function.ts +0 -5
  193. package/src/shared/dir-resolver/functions/resolve-worker-script.function.ts +0 -13
  194. package/src/shared/dir-resolver/index.ts +0 -11
  195. package/src/shared/dir-resolver/typings/base-dir.interface.ts +0 -4
  196. package/src/shared/embedding/classes/null-embedding-provider.class.ts +0 -29
  197. package/src/shared/embedding/constants/near-duplicate-thresholds.constant.ts +0 -17
  198. package/src/shared/embedding/functions/build-vector-index.function.ts +0 -79
  199. package/src/shared/embedding/functions/cosine-similarity.function.ts +0 -31
  200. package/src/shared/embedding/functions/detect-near-duplicates.function.ts +0 -69
  201. package/src/shared/embedding/functions/jaccard-coefficient.function.ts +0 -26
  202. package/src/shared/embedding/functions/read-vector-index-meta.function.ts +0 -44
  203. package/src/shared/embedding/functions/rrf-fuse.function.ts +0 -33
  204. package/src/shared/embedding/functions/search-vectors.function.ts +0 -59
  205. package/src/shared/embedding/index.ts +0 -20
  206. package/src/shared/embedding/typings/embedding-config.interface.ts +0 -23
  207. package/src/shared/embedding/typings/embedding-provider.interface.ts +0 -25
  208. package/src/shared/embedding/typings/near-duplicate-candidate.model.ts +0 -25
  209. package/src/shared/embedding/typings/near-duplicate-result.model.ts +0 -26
  210. package/src/shared/embedding/typings/vector-index-entry.model.ts +0 -13
  211. package/src/shared/embedding/typings/vector-index-meta.model.ts +0 -14
  212. package/src/shared/embedding/typings/vector-search-result.model.ts +0 -8
  213. package/src/shared/hash/functions/compute-sha256.ts +0 -17
  214. package/src/shared/hash/index.ts +0 -1
  215. package/src/shared/mcp/classes/mcp-server.class.ts +0 -480
  216. package/src/shared/mcp/constants/mcp-error-codes.constant.ts +0 -30
  217. package/src/shared/mcp/constants/tool-agent-create.constant.ts +0 -39
  218. package/src/shared/mcp/constants/tool-agent-delete.constant.ts +0 -26
  219. package/src/shared/mcp/constants/tool-agent-get.constant.ts +0 -24
  220. package/src/shared/mcp/constants/tool-agent-list.constant.ts +0 -18
  221. package/src/shared/mcp/constants/tool-auto-capture-review.constant.ts +0 -32
  222. package/src/shared/mcp/constants/tool-check.constant.ts +0 -21
  223. package/src/shared/mcp/constants/tool-content.constant.ts +0 -29
  224. package/src/shared/mcp/constants/tool-export.constant.ts +0 -27
  225. package/src/shared/mcp/constants/tool-gc.constant.ts +0 -21
  226. package/src/shared/mcp/constants/tool-learn.constant.ts +0 -58
  227. package/src/shared/mcp/constants/tool-rebuild.constant.ts +0 -21
  228. package/src/shared/mcp/constants/tool-recall.constant.ts +0 -36
  229. package/src/shared/mcp/constants/tool-retrieve.constant.ts +0 -31
  230. package/src/shared/mcp/constants/tool-search.constant.ts +0 -51
  231. package/src/shared/mcp/constants/tool-skill-delete.constant.ts +0 -24
  232. package/src/shared/mcp/constants/tool-skill-get.constant.ts +0 -27
  233. package/src/shared/mcp/constants/tool-skill-learn.constant.ts +0 -37
  234. package/src/shared/mcp/constants/tool-skill-list.constant.ts +0 -18
  235. package/src/shared/mcp/constants/tool-status.constant.ts +0 -20
  236. package/src/shared/mcp/constants/tool-unlearn.constant.ts +0 -25
  237. package/src/shared/mcp/functions/as-boolean-or-undefined.function.ts +0 -11
  238. package/src/shared/mcp/functions/as-string-array-or-undefined.function.ts +0 -17
  239. package/src/shared/mcp/functions/as-string-array.function.ts +0 -15
  240. package/src/shared/mcp/functions/as-string.function.ts +0 -10
  241. package/src/shared/mcp/functions/build-skills-text.function.ts +0 -43
  242. package/src/shared/mcp/functions/create-mcp-server.function.ts +0 -14
  243. package/src/shared/mcp/functions/create-prompt-definitions.function.ts +0 -102
  244. package/src/shared/mcp/functions/create-resource-templates.function.ts +0 -23
  245. package/src/shared/mcp/functions/create-tool-definitions.function.ts +0 -530
  246. package/src/shared/mcp/functions/extract-skill-arguments.function.ts +0 -27
  247. package/src/shared/mcp/functions/handle-agent-create.function.ts +0 -116
  248. package/src/shared/mcp/functions/handle-agent-delete.function.ts +0 -50
  249. package/src/shared/mcp/functions/handle-agent-get.function.ts +0 -160
  250. package/src/shared/mcp/functions/handle-agent-list.function.ts +0 -50
  251. package/src/shared/mcp/functions/handle-agent-prompt.function.ts +0 -68
  252. package/src/shared/mcp/functions/handle-completion.function.ts +0 -114
  253. package/src/shared/mcp/functions/handle-mcp-request.function.ts +0 -202
  254. package/src/shared/mcp/functions/handle-prompt-get.function.ts +0 -220
  255. package/src/shared/mcp/functions/handle-recall.function.ts +0 -66
  256. package/src/shared/mcp/functions/handle-resource-read.function.ts +0 -56
  257. package/src/shared/mcp/functions/handle-roots-list.function.ts +0 -29
  258. package/src/shared/mcp/functions/handle-skill-prompt.function.ts +0 -44
  259. package/src/shared/mcp/functions/handle-tool-auto-capture-review.function.ts +0 -24
  260. package/src/shared/mcp/functions/handle-tool-call.function.ts +0 -560
  261. package/src/shared/mcp/functions/handle-tool-check.function.ts +0 -21
  262. package/src/shared/mcp/functions/handle-tool-content.function.ts +0 -23
  263. package/src/shared/mcp/functions/handle-tool-export.function.ts +0 -25
  264. package/src/shared/mcp/functions/handle-tool-gc.function.ts +0 -21
  265. package/src/shared/mcp/functions/handle-tool-learn.function.ts +0 -69
  266. package/src/shared/mcp/functions/handle-tool-rebuild.function.ts +0 -21
  267. package/src/shared/mcp/functions/handle-tool-retrieve.function.ts +0 -40
  268. package/src/shared/mcp/functions/handle-tool-search.function.ts +0 -47
  269. package/src/shared/mcp/functions/handle-tool-skill-delete.function.ts +0 -34
  270. package/src/shared/mcp/functions/handle-tool-skill-get.function.ts +0 -59
  271. package/src/shared/mcp/functions/handle-tool-skill-learn.function.ts +0 -61
  272. package/src/shared/mcp/functions/handle-tool-skill-list.function.ts +0 -39
  273. package/src/shared/mcp/functions/handle-tool-status.function.ts +0 -21
  274. package/src/shared/mcp/functions/handle-tool-unlearn.function.ts +0 -24
  275. package/src/shared/mcp/functions/parse-agent-meta.function.ts +0 -27
  276. package/src/shared/mcp/functions/parse-skill-arguments.function.ts +0 -36
  277. package/src/shared/mcp/functions/parse-skill-content.function.ts +0 -38
  278. package/src/shared/mcp/functions/read-agent-meta.function.ts +0 -41
  279. package/src/shared/mcp/functions/resolve-skill-refs.function.ts +0 -50
  280. package/src/shared/mcp/functions/run-startup-health-check.function.ts +0 -34
  281. package/src/shared/mcp/functions/serialize-skill-content.function.ts +0 -12
  282. package/src/shared/mcp/functions/should-emit-log.function.ts +0 -38
  283. package/src/shared/mcp/index.ts +0 -28
  284. package/src/shared/mcp/typings/agent-types.interface.ts +0 -39
  285. package/src/shared/mcp/typings/log-types.interface.ts +0 -26
  286. package/src/shared/mcp/typings/mcp-capabilities.interface.ts +0 -16
  287. package/src/shared/mcp/typings/mcp-client.interface.ts +0 -317
  288. package/src/shared/mcp/typings/mcp-completion.interface.ts +0 -45
  289. package/src/shared/mcp/typings/mcp-content-result.model.ts +0 -9
  290. package/src/shared/mcp/typings/mcp-export-result.model.ts +0 -11
  291. package/src/shared/mcp/typings/mcp-gc-result.model.ts +0 -15
  292. package/src/shared/mcp/typings/mcp-integrity-check-result.model.ts +0 -17
  293. package/src/shared/mcp/typings/mcp-integrity-error.model.ts +0 -15
  294. package/src/shared/mcp/typings/mcp-notification.interface.ts +0 -9
  295. package/src/shared/mcp/typings/mcp-rebuild-result.model.ts +0 -9
  296. package/src/shared/mcp/typings/mcp-request.interface.ts +0 -11
  297. package/src/shared/mcp/typings/mcp-resource-result.interface.ts +0 -12
  298. package/src/shared/mcp/typings/mcp-resource-template.interface.ts +0 -11
  299. package/src/shared/mcp/typings/mcp-response.interface.ts +0 -18
  300. package/src/shared/mcp/typings/mcp-server-info.interface.ts +0 -7
  301. package/src/shared/mcp/typings/mcp-server-state.interface.ts +0 -17
  302. package/src/shared/mcp/typings/mcp-tool-annotations.interface.ts +0 -32
  303. package/src/shared/mcp/typings/mcp-tool-definition.interface.ts +0 -16
  304. package/src/shared/mcp/typings/mcp-tool-result.interface.ts +0 -19
  305. package/src/shared/mcp/typings/mcp-types.interface.ts +0 -158
  306. package/src/shared/mcp/typings/mcp-worker-client.interface.ts +0 -243
  307. package/src/shared/mcp/typings/prompt-types.interface.ts +0 -39
  308. package/src/shared/mcp/typings/remove-section-result.model.ts +0 -10
  309. package/src/shared/mcp/typings/sampling-types.interface.ts +0 -48
  310. package/src/shared/mcp/typings/skill-types.interface.ts +0 -29
  311. package/src/shared/mcp/typings/tool-call-result.model.ts +0 -18
  312. package/src/shared/mod.ts +0 -1
  313. package/src/shared/platform/functions/get-ipc-path.function.ts +0 -19
  314. package/src/shared/platform/functions/get-tmpdir.function.ts +0 -8
  315. package/src/shared/platform/functions/is-process-alive.function.ts +0 -17
  316. package/src/shared/platform/index.ts +0 -3
  317. package/src/shared/runtime/functions/detect-runtime.ts +0 -14
  318. package/src/shared/runtime/functions/get-args.ts +0 -16
  319. package/src/shared/runtime/index.ts +0 -3
  320. package/src/shared/runtime/typings/runtime.ts +0 -2
  321. package/src/shared/sync/functions/build-import-report.function.ts +0 -40
  322. package/src/shared/sync/functions/parse-export-entry.function.ts +0 -45
  323. package/src/shared/sync/functions/resolve-conflict.function.ts +0 -31
  324. package/src/shared/sync/functions/serialize-export-entry.function.ts +0 -18
  325. package/src/shared/sync/index.ts +0 -9
  326. package/src/shared/sync/typings/conflict-resolution.type.ts +0 -8
  327. package/src/shared/sync/typings/export-entry.interface.ts +0 -13
  328. package/src/shared/sync/typings/export-options.interface.ts +0 -9
  329. package/src/shared/sync/typings/import-options.interface.ts +0 -7
  330. package/src/shared/sync/typings/import-report.interface.ts +0 -15
  331. package/src/shared/version/constants/version.constant.ts +0 -2
  332. package/src/shared/version/index.ts +0 -1
  333. package/src/shared/wasm-codec/functions/decode-add-section-result.function.ts +0 -112
  334. package/src/shared/wasm-codec/functions/decode-compose-output.function.ts +0 -16
  335. package/src/shared/wasm-codec/functions/decode-document-manifest-list.function.ts +0 -70
  336. package/src/shared/wasm-codec/functions/decode-document-manifest.function.ts +0 -87
  337. package/src/shared/wasm-codec/functions/decode-f32.function.ts +0 -16
  338. package/src/shared/wasm-codec/functions/decode-key-value-text.function.ts +0 -15
  339. package/src/shared/wasm-codec/functions/decode-one-recall-result.function.ts +0 -86
  340. package/src/shared/wasm-codec/functions/decode-option-string.function.ts +0 -24
  341. package/src/shared/wasm-codec/functions/decode-recall-document.function.ts +0 -59
  342. package/src/shared/wasm-codec/functions/decode-recall-reference.function.ts +0 -52
  343. package/src/shared/wasm-codec/functions/decode-recall-result.function.ts +0 -267
  344. package/src/shared/wasm-codec/functions/decode-recall-sibling.function.ts +0 -43
  345. package/src/shared/wasm-codec/functions/decode-remove-flag.function.ts +0 -3
  346. package/src/shared/wasm-codec/functions/decode-scored-results.function.ts +0 -194
  347. package/src/shared/wasm-codec/functions/decode-section-match.function.ts +0 -80
  348. package/src/shared/wasm-codec/functions/decode-section-record-list.function.ts +0 -20
  349. package/src/shared/wasm-codec/functions/decode-section-record-trailing.function.ts +0 -75
  350. package/src/shared/wasm-codec/functions/decode-section-record.function.ts +0 -85
  351. package/src/shared/wasm-codec/functions/decode-section-records.function.ts +0 -249
  352. package/src/shared/wasm-codec/functions/decode-section-type.function.ts +0 -30
  353. package/src/shared/wasm-codec/functions/decode-string.function.ts +0 -22
  354. package/src/shared/wasm-codec/functions/decode-u32.function.ts +0 -16
  355. package/src/shared/wasm-codec/functions/decode-u64.function.ts +0 -16
  356. package/src/shared/wasm-codec/functions/decode-wasm-list.function.ts +0 -31
  357. package/src/shared/wasm-codec/functions/encode-add-section-params.function.ts +0 -102
  358. package/src/shared/wasm-codec/functions/encode-group-params.function.ts +0 -28
  359. package/src/shared/wasm-codec/functions/encode-identifier-list.function.ts +0 -17
  360. package/src/shared/wasm-codec/functions/encode-kbid-list.function.ts +0 -17
  361. package/src/shared/wasm-codec/functions/encode-option-string.function.ts +0 -14
  362. package/src/shared/wasm-codec/functions/encode-recall-params.function.ts +0 -68
  363. package/src/shared/wasm-codec/functions/encode-search-params.function.ts +0 -12
  364. package/src/shared/wasm-codec/functions/encode-section-type.function.ts +0 -18
  365. package/src/shared/wasm-codec/functions/encode-string.function.ts +0 -9
  366. package/src/shared/wasm-codec/functions/encode-type-filter-param.function.ts +0 -13
  367. package/src/shared/wasm-codec/functions/encode-u32.function.ts +0 -5
  368. package/src/shared/wasm-codec/functions/encode-update-section-params.function.ts +0 -16
  369. package/src/shared/wasm-codec/index.ts +0 -49
  370. package/src/shared/wasm-codec/typings/add-section-input.model.ts +0 -45
  371. package/src/shared/wasm-codec/typings/add-section-result.model.ts +0 -28
  372. package/src/shared/wasm-codec/typings/document-manifest.model.ts +0 -20
  373. package/src/shared/wasm-codec/typings/document-section.model.ts +0 -12
  374. package/src/shared/wasm-codec/typings/item-decoder.type.ts +0 -10
  375. package/src/shared/wasm-codec/typings/near-duplicate.model.ts +0 -16
  376. package/src/shared/wasm-codec/typings/paged-search-result.model.ts +0 -22
  377. package/src/shared/wasm-codec/typings/section-match.model.ts +0 -31
  378. package/src/shared/wasm-codec/typings/section-record-trailing.model.ts +0 -38
  379. package/src/shared/wasm-codec/typings/section-record.model.ts +0 -66
  380. package/src/shared/wasm-codec/typings/section-type-result.model.ts +0 -12
  381. package/src/shared/worker-client/classes/worker-client.class.ts +0 -466
  382. package/src/shared/worker-client/functions/compute-context-id.function.ts +0 -18
  383. package/src/shared/worker-client/functions/create-worker-client.function.ts +0 -70
  384. package/src/shared/worker-client/functions/discover-daemon.function.ts +0 -47
  385. package/src/shared/worker-client/functions/handle-ipc-data.function.ts +0 -49
  386. package/src/shared/worker-client/functions/resolve-db-path.function.ts +0 -21
  387. package/src/shared/worker-client/functions/send-ipc-request.function.ts +0 -39
  388. package/src/shared/worker-client/functions/spawn-daemon.function.ts +0 -35
  389. package/src/shared/worker-client/functions/wait-for-daemon.function.ts +0 -34
  390. package/src/shared/worker-client/index.ts +0 -44
  391. package/src/shared/worker-client/typings/add-section-result.model.ts +0 -39
  392. package/src/shared/worker-client/typings/content-result.model.ts +0 -12
  393. package/src/shared/worker-client/typings/daemon-info.model.ts +0 -7
  394. package/src/shared/worker-client/typings/export-result.model.ts +0 -14
  395. package/src/shared/worker-client/typings/gc-result.model.ts +0 -18
  396. package/src/shared/worker-client/typings/integrity-check-result.model.ts +0 -43
  397. package/src/shared/worker-client/typings/json-rpc-response.interface.ts +0 -17
  398. package/src/shared/worker-client/typings/migrate-result.model.ts +0 -11
  399. package/src/shared/worker-client/typings/pending-call.interface.ts +0 -7
  400. package/src/shared/worker-client/typings/rebuild-result.model.ts +0 -12
  401. package/src/shared/worker-client/typings/recall-document.model.ts +0 -16
  402. package/src/shared/worker-client/typings/recall-params.model.ts +0 -15
  403. package/src/shared/worker-client/typings/recall-reference.model.ts +0 -32
  404. package/src/shared/worker-client/typings/recall-result.model.ts +0 -98
  405. package/src/shared/worker-client/typings/recall-sibling.model.ts +0 -11
  406. package/src/shared/worker-client/typings/recall-single-result.model.ts +0 -41
  407. package/src/shared/worker-client/typings/remove-section-result.model.ts +0 -7
  408. package/src/shared/worker-client/typings/search-params.model.ts +0 -14
  409. package/src/shared/worker-client/typings/search-result.model.ts +0 -43
  410. package/src/shared/worker-client/typings/section.model.ts +0 -43
  411. package/src/shared/worker-client/typings/status-result.model.ts +0 -14
  412. package/src/shared/worker-client/typings/version-status.model.ts +0 -28
  413. package/src/shared/worker-client/typings/worker-client-error.interface.ts +0 -8
  414. package/src/shared/worker-client/typings/worker-client-options.interface.ts +0 -30
  415. package/src/shared/worker-daemon/classes/ipc-error.class.ts +0 -22
  416. package/src/shared/worker-daemon/classes/worker-daemon.class.ts +0 -1291
  417. package/src/shared/worker-daemon/constants/daemon-defaults.constant.ts +0 -29
  418. package/src/shared/worker-daemon/constants/wasm-method-map.constant.ts +0 -69
  419. package/src/shared/worker-daemon/functions/build-ipc-error-response.function.ts +0 -16
  420. package/src/shared/worker-daemon/functions/check-catalog-version.function.ts +0 -54
  421. package/src/shared/worker-daemon/functions/check-preconditions.function.ts +0 -28
  422. package/src/shared/worker-daemon/functions/create-host-imports.function.ts +0 -328
  423. package/src/shared/worker-daemon/functions/create-ipc-server.function.ts +0 -87
  424. package/src/shared/worker-daemon/functions/detect-stale-pid.function.ts +0 -33
  425. package/src/shared/worker-daemon/functions/dispatch-request.function.ts +0 -190
  426. package/src/shared/worker-daemon/functions/handle-check-version.function.ts +0 -74
  427. package/src/shared/worker-daemon/functions/handle-config-method.function.ts +0 -27
  428. package/src/shared/worker-daemon/functions/handle-read-ops.function.ts +0 -236
  429. package/src/shared/worker-daemon/functions/handle-write-ops.function.ts +0 -257
  430. package/src/shared/worker-daemon/functions/load-wasm-modules.function.ts +0 -95
  431. package/src/shared/worker-daemon/functions/parse-auto-capture-section.function.ts +0 -51
  432. package/src/shared/worker-daemon/functions/parse-catalog-version.function.ts +0 -20
  433. package/src/shared/worker-daemon/functions/parse-embedding-section.function.ts +0 -38
  434. package/src/shared/worker-daemon/functions/parse-worker-toml.function.ts +0 -104
  435. package/src/shared/worker-daemon/functions/read-config.function.ts +0 -83
  436. package/src/shared/worker-daemon/functions/run-startup-integrity-check.function.ts +0 -55
  437. package/src/shared/worker-daemon/functions/run-worker.function.ts +0 -57
  438. package/src/shared/worker-daemon/functions/scan-near-duplicates.function.ts +0 -92
  439. package/src/shared/worker-daemon/functions/start-daemon.function.ts +0 -74
  440. package/src/shared/worker-daemon/functions/wasm-bridge.function.ts +0 -144
  441. package/src/shared/worker-daemon/functions/wasm-memory-helpers.function.ts +0 -41
  442. package/src/shared/worker-daemon/functions/write-lock.function.ts +0 -49
  443. package/src/shared/worker-daemon/index.ts +0 -16
  444. package/src/shared/worker-daemon/typings/allocator-ref.interface.ts +0 -16
  445. package/src/shared/worker-daemon/typings/daemon-config.interface.ts +0 -20
  446. package/src/shared/worker-daemon/typings/fs-adapter.interface.ts +0 -22
  447. package/src/shared/worker-daemon/typings/handler-context.interface.ts +0 -19
  448. package/src/shared/worker-daemon/typings/ipc-handler.interface.ts +0 -39
  449. package/src/shared/worker-daemon/typings/memory-ref.interface.ts +0 -13
  450. package/src/shared/worker-daemon/typings/wasm-fn.type.ts +0 -2
  451. package/src/shared/worker-daemon/typings/wasm-modules.interface.ts +0 -7
  452. package/src/shared/worker-daemon/typings/write-lock.interface.ts +0 -13
  453. package/src/wasm/fs-database/kbdb_fs_database.d.ts +0 -259
  454. package/src/wasm/fs-database/kbdb_fs_database.js +0 -515
  455. package/src/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  456. package/src/wasm/fs-database/kbdb_fs_database_bg.wasm.d.ts +0 -35
  457. package/src/wasm/fs-database/package.json +0 -13
  458. package/src/wasm/kb-worker/kbdb_worker.d.ts +0 -650
  459. package/src/wasm/kb-worker/kbdb_worker.js +0 -1181
  460. package/src/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  461. package/src/wasm/kb-worker/kbdb_worker_bg.wasm.d.ts +0 -77
  462. package/src/wasm/kb-worker/package.json +0 -13
  463. package/src/wasm/query-parser/kbdb_query_parser.d.ts +0 -195
  464. package/src/wasm/query-parser/kbdb_query_parser.js +0 -403
  465. package/src/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
  466. package/src/wasm/query-parser/kbdb_query_parser_bg.wasm.d.ts +0 -25
  467. package/src/wasm/query-parser/package.json +0 -13
  468. package/src/worker.ts +0 -42
@@ -1,1291 +0,0 @@
1
- import {
2
- existsSync,
3
- readFileSync,
4
- readdirSync,
5
- accessSync,
6
- writeFileSync,
7
- unlinkSync,
8
- constants,
9
- } from 'node:fs';
10
- import { join } from 'node:path';
11
- import { tmpdir } from 'node:os';
12
- import type { Server } from 'node:net';
13
- import type { DaemonConfig } from '../typings/daemon-config.interface.ts';
14
- import type { WasmModules } from '../typings/wasm-modules.interface.ts';
15
- import type {
16
- IpcRequest,
17
- IpcResponse,
18
- IpcHandler,
19
- } from '../typings/ipc-handler.interface.ts';
20
- import { DB_FORMAT_VERSION } from '../constants/daemon-defaults.constant.ts';
21
- import { loadWasmModules } from '../functions/load-wasm-modules.function.ts';
22
- import { createIpcServer } from '../functions/create-ipc-server.function.ts';
23
- import { getIpcPath } from '../../platform/functions/get-ipc-path.function.ts';
24
- import {
25
- encodeSearchParams,
26
- encodeAddSectionParams,
27
- encodeUpdateSectionParams,
28
- encodeKbidList,
29
- encodeGroupParams,
30
- encodeIdentifierList,
31
- encodeTypeFilterParam,
32
- encodeRecallParams,
33
- decodePagedSearchResult,
34
- decodeSectionRecords,
35
- decodeSectionRecordList,
36
- decodeDocumentManifest,
37
- decodeDocumentManifestList,
38
- decodeComposeOutput,
39
- decodeKeyValueText,
40
- decodeRemoveFlag,
41
- decodeRecallResult,
42
- decodeAddSectionResult,
43
- } from '../../wasm-codec/index.ts';
44
-
45
- import type { AddSectionInput } from '../../wasm-codec/index.ts';
46
-
47
- // ---------------------------------------------------------------------------
48
- // Internal types
49
- // ---------------------------------------------------------------------------
50
-
51
- /** Callable WASM export function signature. */
52
- type WasmFn = (...args: unknown[]) => unknown;
53
-
54
- /** Mapping from IPC method name to kb-worker.wasm export name. */
55
- const WASM_METHOD_MAP: Readonly<Partial<Record<string, string>>> = {
56
- search: 'worker_search',
57
- addSection: 'worker_add_section',
58
- add_section: 'worker_add_section',
59
- updateSection: 'worker_update_section',
60
- update_section: 'worker_update_section',
61
- removeSection: 'worker_remove_section',
62
- remove_section: 'worker_remove_section',
63
- readSections: 'worker_read_sections',
64
- read_sections: 'worker_read_sections',
65
- groupSections: 'worker_group_sections',
66
- group_sections: 'worker_group_sections',
67
- removeGrouping: 'worker_remove_grouping',
68
- remove_grouping: 'worker_remove_grouping',
69
- retrieveDocument: 'worker_retrieve_doc',
70
- retrieve_doc: 'worker_retrieve_doc',
71
- content: 'worker_compose',
72
- compose: 'worker_compose',
73
- integrity_check: 'worker_check_integrity',
74
- integrityCheck: 'worker_check_integrity',
75
- gc: 'worker_garbage_collect',
76
- rebuild_indexes: 'worker_rebuild_indexes',
77
- rebuildIndexes: 'worker_rebuild_indexes',
78
- init_directory: 'worker_init_directory',
79
- initDirectory: 'worker_init_directory',
80
- migrateDatabase: 'worker_migrate',
81
- query: 'worker_query',
82
- get_result_status: 'worker_result_status',
83
- get_result: 'worker_get_result',
84
- invalidate: 'worker_invalidate',
85
- invalidate_all: 'worker_invalidate_all',
86
- invalidateAll: 'worker_invalidate_all',
87
- db_status: 'worker_status',
88
- dbStatus: 'worker_status',
89
- listByType: 'worker_list_by_type',
90
- list_by_type: 'worker_list_by_type',
91
- listDocumentsByType: 'worker_list_docs_by_type',
92
- list_docs_by_type: 'worker_list_docs_by_type',
93
- recall: 'worker_recall',
94
- export: 'worker_export',
95
- exportDb: 'worker_export',
96
- };
97
-
98
- /** Config method name prefix. */
99
- const CONFIG_PREFIX = 'config_';
100
-
101
- /** Config key → DaemonConfig property mapping. */
102
- const CONFIG_KEY_MAP: Readonly<
103
- Partial<Record<string, keyof DaemonConfig>>
104
- > = {
105
- timeout_ms: 'timeoutMs',
106
- item_ttl_ms: 'itemTtlMs',
107
- item_limit: 'itemLimit',
108
- index_limit: 'indexLimit',
109
- };
110
-
111
- // ---------------------------------------------------------------------------
112
- // IpcError
113
- // ---------------------------------------------------------------------------
114
-
115
- /** Typed JSON-RPC error used internally by WorkerDaemon dispatch. */
116
- class IpcError extends Error {
117
- /** JSON-RPC error code. */
118
- readonly code: number;
119
-
120
- constructor(code: number, message: string) {
121
- super(message);
122
- this.code = code;
123
- this.name = 'IpcError';
124
- }
125
- }
126
-
127
- // ---------------------------------------------------------------------------
128
- // WorkerDaemon
129
- // ---------------------------------------------------------------------------
130
-
131
- /**
132
- * Core daemon class that manages the full worker daemon lifecycle.
133
- *
134
- * Orchestrates WASM module loading, IPC server creation, request
135
- * routing to `kb-worker.wasm` exports, idle timeout tracking, and
136
- * graceful shutdown. The daemon validates startup preconditions before
137
- * loading WASM modules and rejects IPC requests whose `ctx` param does
138
- * not match the daemon's context ID.
139
- */
140
- export class WorkerDaemon {
141
- /** Context ID (16-character hex SHA-256 prefix). */
142
- readonly ctx: string;
143
-
144
- /** Absolute path to the `.kbdb` directory. */
145
- readonly targetDir: string;
146
-
147
- /** Parsed daemon configuration from `worker.toml`. */
148
- readonly config: DaemonConfig;
149
-
150
- /** Number of currently active IPC client connections. */
151
- get connectionCount(): number {
152
- return this._connectionCount;
153
- }
154
-
155
- private _connectionCount = 0;
156
- private _wasmModules: WasmModules | null = null;
157
- private _idleAt = 0;
158
- private _idleTimer: ReturnType<typeof setTimeout> | null = null;
159
- private _server: Server | null = null;
160
- private readonly _wasmDir: string;
161
-
162
- /** Queue of waiters for the single-writer lock. */
163
- private _writeQueue: { resolve: () => void }[] = [];
164
-
165
- /** Whether the write lock is currently held. */
166
- private _writeLocked = false;
167
-
168
- /** Whether the startup integrity check passed. */
169
- private _integrityOk = true;
170
-
171
- /** Integrity errors found at startup, if any. */
172
- private _integrityErrors: string[] = [];
173
-
174
- /**
175
- * @param ctx - context ID (16-hex characters), the first 16 of
176
- * the SHA-256 hash of `targetDir`
177
- * @param targetDir - absolute path to the `.kbdb` directory
178
- * @param config - parsed daemon configuration
179
- * @param wasmDir - path to the WASM build output directory
180
- */
181
- constructor(
182
- ctx: string,
183
- targetDir: string,
184
- config: DaemonConfig,
185
- wasmDir?: string,
186
- ) {
187
- this.ctx = ctx;
188
- this.targetDir = targetDir;
189
- this.config = config;
190
- this._wasmDir = wasmDir ?? '';
191
- }
192
-
193
- // -----------------------------------------------------------------------
194
- // Public API
195
- // -----------------------------------------------------------------------
196
-
197
- /**
198
- * Validates startup preconditions before WASM module loading.
199
- *
200
- * Checks that the database directory exists, is readable and
201
- * writable, and that `catalog.toml` reports a compatible version.
202
- *
203
- * @throws {Error} if any precondition fails -- `startDaemon`
204
- * catches this, prints to stderr, and exits with code 1
205
- */
206
- checkPreconditions(): void {
207
- if (!existsSync(this.targetDir)) {
208
- throw new Error(
209
- `database directory not found: ${this.targetDir}`,
210
- );
211
- }
212
-
213
- try {
214
- accessSync(
215
- this.targetDir,
216
-
217
- constants.R_OK | constants.W_OK,
218
- );
219
- } catch {
220
- throw new Error(
221
- `cannot access database directory: ${this.targetDir}` +
222
- ' -- permission denied',
223
- );
224
- }
225
-
226
- this.checkCatalogVersion();
227
- }
228
-
229
- /**
230
- * Starts the daemon: loads WASM modules, writes the PID file,
231
- * creates the IPC socket, and begins listening for connections.
232
- *
233
- * Call `checkPreconditions()` before `start()` to validate the
234
- * database directory. The daemon will not start if any precondition
235
- * fails.
236
- *
237
- * @throws when WASM module loading fails or the IPC socket cannot
238
- * be created
239
- */
240
- async start(): Promise<void> {
241
- const wasmModules = await loadWasmModules(
242
- this.config,
243
- this._wasmDir,
244
- );
245
- this._wasmModules = wasmModules;
246
-
247
- this.initWorkerContext();
248
- this.runStartupIntegrityCheck();
249
-
250
- const pidPath = join(tmpdir(), `kbdb-${this.ctx}.pid`);
251
- writeFileSync(pidPath, process.pid.toString());
252
-
253
- const ipcPath = getIpcPath(this.ctx);
254
-
255
- if (existsSync(ipcPath)) {
256
- try {
257
- unlinkSync(ipcPath);
258
- } catch {
259
- // ignore stale socket removal errors
260
- }
261
- }
262
-
263
- const handler: IpcHandler = (req) => this.handleRequest(req);
264
- this._server = createIpcServer(ipcPath, handler);
265
-
266
- this._server.on('connection', () => {
267
- this.incrementConnections();
268
- this.resetIdleTimer();
269
- });
270
-
271
- this._server.on('close', () => {
272
- this.decrementConnections();
273
- if (this._connectionCount === 0) {
274
- this.resetIdleTimer();
275
- }
276
- });
277
-
278
- this.resetIdleTimer();
279
- }
280
-
281
- /**
282
- * Gracefully shuts down the daemon.
283
- *
284
- * Stops accepting new connections, clears the idle timer, purges
285
- * WASM state, removes the PID file and IPC socket file, then exits
286
- * the process.
287
- */
288
- stop(): void {
289
- if (this._idleTimer !== null) {
290
- clearTimeout(this._idleTimer);
291
- this._idleTimer = null;
292
- }
293
-
294
- if (this._server !== null) {
295
- this._server.close();
296
- this._server = null;
297
- }
298
-
299
- this._wasmModules = null;
300
-
301
- const pidPath = join(tmpdir(), `kbdb-${this.ctx}.pid`);
302
- try {
303
- unlinkSync(pidPath);
304
- } catch {
305
- // ignore cleanup errors
306
- }
307
-
308
- const ipcPath = getIpcPath(this.ctx);
309
- try {
310
- unlinkSync(ipcPath);
311
- } catch {
312
- // ignore cleanup errors
313
- }
314
-
315
- const crashPath = join(tmpdir(), `kbdb-${this.ctx}.crash`);
316
- try {
317
- unlinkSync(crashPath);
318
- } catch {
319
- // ignore cleanup errors
320
- }
321
-
322
- process.exit(0);
323
- }
324
-
325
- /**
326
- * Handles a single JSON-RPC 2.0 request.
327
- *
328
- * Validates context, then routes to a daemon-state handler or a
329
- * WASM export. Requests whose `ctx` param does not match the
330
- * daemon's context ID are rejected with error code `-32001`.
331
- *
332
- * @param request - incoming JSON-RPC request
333
- * @returns the JSON-RPC response
334
- */
335
- async handleRequest(request: IpcRequest): Promise<IpcResponse> {
336
- const params = request.params as
337
- | Record<string, unknown>
338
- | undefined;
339
- if (params === undefined || params.ctx !== this.ctx) {
340
- return this.errorResponse(
341
- request.id,
342
- -32001,
343
- 'context mismatch',
344
- );
345
- }
346
-
347
- this.resetIdleTimer();
348
-
349
- try {
350
- const result = await this.dispatch(request.method, params);
351
- this._idleAt = Math.floor(Date.now() / 1000);
352
- return {
353
- jsonrpc: '2.0',
354
- id: request.id,
355
- result,
356
- };
357
- } catch (err) {
358
- this._idleAt = Math.floor(Date.now() / 1000);
359
- if (err instanceof IpcError) {
360
- return this.errorResponse(
361
- request.id,
362
- err.code,
363
- err.message,
364
- );
365
- }
366
- const message =
367
- err instanceof Error ? err.message : String(err);
368
- return this.errorResponse(request.id, -32000, message);
369
- }
370
- }
371
-
372
- /**
373
- * Increments the active connection count.
374
- *
375
- * Call when a new IPC client connects.
376
- */
377
- incrementConnections(): void {
378
- this._connectionCount++;
379
- }
380
-
381
- /**
382
- * Decrements the active connection count, clamped to zero.
383
- *
384
- * Call when an IPC client disconnects.
385
- */
386
- decrementConnections(): void {
387
- if (this._connectionCount > 0) {
388
- this._connectionCount--;
389
- }
390
- }
391
-
392
- /**
393
- * Injects pre-built WASM modules for unit testing.
394
- *
395
- * This method exists solely to support unit tests that cannot
396
- * load real WASM binaries. It must not be called in production
397
- * code -- production code uses `start()` to load modules.
398
- *
399
- * @param modules - pre-built WASM module instances
400
- * @internal
401
- */
402
- injectModulesForTesting(modules: WasmModules): void {
403
- this._wasmModules = modules;
404
- }
405
-
406
- // -----------------------------------------------------------------------
407
- // Private helpers
408
- // -----------------------------------------------------------------------
409
-
410
- /** Resets the idle timer; triggers stop() when it fires. */
411
- private resetIdleTimer(): void {
412
- if (this._idleTimer !== null) {
413
- clearTimeout(this._idleTimer);
414
- }
415
- if (this._connectionCount === 0) {
416
- this._idleTimer = setTimeout(() => {
417
- this.stop();
418
- }, this.config.timeoutMs);
419
- }
420
- }
421
-
422
- /** Reads catalog.toml and validates the version field. */
423
- private checkCatalogVersion(): void {
424
- const catalogPath = join(this.targetDir, 'catalog.toml');
425
- let text: string;
426
- try {
427
- text = readFileSync(catalogPath, 'utf-8');
428
- } catch {
429
- throw new Error(
430
- `cannot read database directory: ${this.targetDir}` +
431
- ' -- permission denied',
432
- );
433
- }
434
-
435
- const version = parseCatalogVersion(text);
436
- if (version === null) {
437
- throw new Error(
438
- 'database version 0 requires migration to version ' +
439
- String(DB_FORMAT_VERSION) +
440
- ' -- run `kbdb --migrate` before starting the daemon',
441
- );
442
- }
443
-
444
- if (version > DB_FORMAT_VERSION) {
445
- throw new Error(
446
- 'database version ' +
447
- String(version) +
448
- ' is newer than kbdb version ' +
449
- String(DB_FORMAT_VERSION) +
450
- ' -- upgrade kbdb to open this database',
451
- );
452
- }
453
-
454
- if (version < DB_FORMAT_VERSION) {
455
- throw new Error(
456
- 'database version ' +
457
- String(version) +
458
- ' requires migration to version ' +
459
- String(DB_FORMAT_VERSION) +
460
- ' -- run `kbdb --migrate` before starting the daemon',
461
- );
462
- }
463
- }
464
-
465
- /** Builds a JSON-RPC error response. */
466
- private errorResponse(
467
- id: number | string,
468
- code: number,
469
- message: string,
470
- ): IpcResponse {
471
- return {
472
- jsonrpc: '2.0',
473
- id,
474
- error: { code, message },
475
- };
476
- }
477
-
478
- /**
479
- * Dispatches a request method to the appropriate handler.
480
- *
481
- * Handles daemon-state methods (`status`, `idle_at`,
482
- * `config_{key}`) inline and routes WASM methods to the
483
- * correct calling convention for each export.
484
- */
485
- private dispatch(
486
- method: string,
487
- params: Record<string, unknown>,
488
- ): unknown {
489
- if (method === 'status') {
490
- return {
491
- status: this._connectionCount > 0 ? 'busy' : 'idle',
492
- integrityOk: this._integrityOk,
493
- integrityErrors: this._integrityErrors,
494
- };
495
- }
496
-
497
- if (method === 'idle_at') {
498
- return this._idleAt;
499
- }
500
-
501
- if (method === 'checkVersion') {
502
- return this.handleCheckVersion(params);
503
- }
504
-
505
- if (method.startsWith(CONFIG_PREFIX)) {
506
- return this.handleConfigMethod(method);
507
- }
508
-
509
- const wasmMethod = WASM_METHOD_MAP[method];
510
- if (wasmMethod !== undefined) {
511
- return this.dispatchWasm(method, wasmMethod, params);
512
- }
513
-
514
- throw new IpcError(-32601, `Method not found: ${method}`);
515
- }
516
-
517
- private async dispatchWasm(
518
- method: string,
519
- wasmExport: string,
520
- params: Record<string, unknown>,
521
- ): Promise<unknown> {
522
- // Read-only operations — no write lock required.
523
- if (method === 'search' || method === 'query') {
524
- return this.handleSearch(params);
525
- }
526
- if (method === 'readSections' || method === 'read_sections') {
527
- return this.handleReadSections(params);
528
- }
529
- if (method === 'retrieveDocument' || method === 'retrieve_doc') {
530
- return this.handleRetrieveDoc(params);
531
- }
532
- if (method === 'content' || method === 'compose') {
533
- return this.handleCompose(params);
534
- }
535
- if (method === 'integrityCheck' || method === 'integrity_check') {
536
- return this.handleIntegrityCheck();
537
- }
538
- if (method === 'dbStatus' || method === 'db_status') {
539
- return this.handleDbStatus();
540
- }
541
- if (method === 'get_result_status') {
542
- return this.handleResultStatus(params);
543
- }
544
- if (method === 'get_result') {
545
- return this.handleGetResult(params);
546
- }
547
- if (method === 'listByType' || method === 'list_by_type') {
548
- return this.handleListByType(params);
549
- }
550
- if (
551
- method === 'listDocumentsByType' ||
552
- method === 'list_docs_by_type'
553
- ) {
554
- return this.handleListDocsByType(params);
555
- }
556
- if (method === 'recall') {
557
- return this.handleRecall(params);
558
- }
559
- if (method === 'export' || method === 'exportDb') {
560
- return this.handleExport(params);
561
- }
562
-
563
- // Write operations — serialised through the single-writer lock.
564
- await this.acquireWriteLock();
565
- try {
566
- if (method === 'invalidate') {
567
- return this.handleInvalidate(params);
568
- }
569
- if (
570
- method === 'invalidateAll' ||
571
- method === 'invalidate_all'
572
- ) {
573
- return this.handleInvalidateAll();
574
- }
575
- if (method === 'addSection' || method === 'add_section') {
576
- return this.handleAddSection(params);
577
- }
578
- if (
579
- method === 'updateSection' ||
580
- method === 'update_section'
581
- ) {
582
- return this.handleUpdateSection(params);
583
- }
584
- if (
585
- method === 'removeSection' ||
586
- method === 'remove_section'
587
- ) {
588
- return this.handleRemoveSection(params);
589
- }
590
- if (
591
- method === 'groupSections' ||
592
- method === 'group_sections'
593
- ) {
594
- return this.handleGroupSections(params);
595
- }
596
- if (
597
- method === 'removeGrouping' ||
598
- method === 'remove_grouping'
599
- ) {
600
- return this.handleRemoveGrouping(params);
601
- }
602
- if (method === 'gc') {
603
- return this.handleGc();
604
- }
605
- if (
606
- method === 'rebuildIndexes' ||
607
- method === 'rebuild_indexes'
608
- ) {
609
- return this.handleRebuild();
610
- }
611
- if (
612
- method === 'initDirectory' ||
613
- method === 'init_directory'
614
- ) {
615
- return this.handleInitDirectory(params);
616
- }
617
- if (method === 'migrateDatabase') {
618
- throw new IpcError(
619
- -32601,
620
- 'migrateDatabase is not yet supported',
621
- );
622
- }
623
- return this.invokeWasmRaw(wasmExport, new Uint8Array(0));
624
- } finally {
625
- this.releaseWriteLock();
626
- }
627
- }
628
-
629
- // -- Search/query (token-based async) --
630
-
631
- private handleSearch(params: Record<string, unknown>): unknown {
632
- const query = (params['query'] as string | undefined) ?? '';
633
- const mode = (params['mode'] as string | undefined) ?? 'and';
634
- const limit = Number(params['limit'] ?? 20);
635
- const offset = Number(params['offset'] ?? 0);
636
- const encoded = encodeSearchParams(query, mode, limit, offset);
637
-
638
- const searchFn = this.getExport('worker_search');
639
- const ptr = this.wasmAlloc(encoded.length);
640
- this.wasmWrite(ptr, encoded);
641
- const token = searchFn(ptr, encoded.length) as number;
642
- this.wasmFree(ptr, encoded.length);
643
-
644
- const statusFn = this.getExport('worker_result_status');
645
- const status = statusFn(token) as number;
646
- if (status === 3) {
647
- const getResultFn = this.getExport('worker_get_result');
648
- getResultFn(token);
649
- const errBytes = this.readReturnSlot();
650
- const errMsg = new TextDecoder().decode(errBytes);
651
- throw new IpcError(-32000, errMsg);
652
- }
653
-
654
- const getResultFn = this.getExport('worker_get_result');
655
- const rc = getResultFn(token) as number;
656
- if (rc === -1) {
657
- const errBytes = this.readReturnSlot();
658
- throw new IpcError(-32000, new TextDecoder().decode(errBytes));
659
- }
660
- const resultBytes = this.readReturnSlot();
661
- return decodePagedSearchResult(resultBytes);
662
- }
663
-
664
- // -- Token status/result (u32 direct params) --
665
-
666
- private handleResultStatus(
667
- params: Record<string, unknown>,
668
- ): unknown {
669
- const token = Number(params['token'] ?? 0);
670
- const fn = this.getExport('worker_result_status');
671
- const status = fn(token) as number;
672
- return { status };
673
- }
674
-
675
- private handleGetResult(params: Record<string, unknown>): unknown {
676
- const token = Number(params['token'] ?? 0);
677
- const fn = this.getExport('worker_get_result');
678
- const rc = fn(token) as number;
679
- if (rc === -1) {
680
- const errBytes = this.readReturnSlot();
681
- throw new IpcError(-32000, new TextDecoder().decode(errBytes));
682
- }
683
- const bytes = this.readReturnSlot();
684
- return decodePagedSearchResult(bytes);
685
- }
686
-
687
- // -- Binary-encoded input methods --
688
-
689
- private handleAddSection(params: Record<string, unknown>): unknown {
690
- const sectionType = (params['sectionType'] ?? 'text') as string;
691
- const semanticType =
692
- sectionType === 'text' ||
693
- sectionType === 'code' ||
694
- sectionType === 'image'
695
- ? sectionType
696
- : 'text';
697
- const typeName =
698
- sectionType !== semanticType ? sectionType : null;
699
- const tags = Array.isArray(params['tags'])
700
- ? (params['tags'] as string[])
701
- : [];
702
- const input: AddSectionInput = {
703
- sectionType: semanticType,
704
- mimeType: params['mimeType'] as string | undefined,
705
- content: (params['content'] as string | undefined) ?? '',
706
- title: (params['title'] as string | null) ?? null,
707
- description: (params['description'] as string | null) ?? null,
708
- docid: (params['docid'] as string | null) ?? null,
709
- typeName,
710
- sourcePath:
711
- typeof params['sourcePath'] === 'string'
712
- ? params['sourcePath']
713
- : undefined,
714
- sourceMtime:
715
- typeof params['sourceMtime'] === 'string'
716
- ? params['sourceMtime']
717
- : undefined,
718
- tags,
719
- replace: params['replace'] === true,
720
- };
721
- const encoded = encodeAddSectionParams(input);
722
- const bytes = this.callWasmSync('worker_add_section', encoded);
723
- const decoded = decodeAddSectionResult(bytes);
724
- const nearDups =
725
- decoded.nearDuplicates.length > 0
726
- ? decoded.nearDuplicates
727
- : this.scanNearDuplicates(input.content, decoded.kbid);
728
- return {
729
- kbid: decoded.kbid,
730
- indexed_terms_count: decoded.indexedTermsCount,
731
- elapsed_ms: decoded.elapsedMs,
732
- superseded: decoded.superseded,
733
- warnings: decoded.warnings,
734
- near_duplicates: nearDups,
735
- };
736
- }
737
-
738
- private handleUpdateSection(
739
- params: Record<string, unknown>,
740
- ): unknown {
741
- const oldKbid = (params['kbid'] as string | undefined) ?? '';
742
- const updSectionType = (params['sectionType'] ??
743
- 'text') as string;
744
- const updSemanticType =
745
- updSectionType === 'text' ||
746
- updSectionType === 'code' ||
747
- updSectionType === 'image'
748
- ? updSectionType
749
- : 'text';
750
- const updTypeName =
751
- updSectionType !== updSemanticType ? updSectionType : null;
752
- const input: AddSectionInput = {
753
- sectionType: updSemanticType,
754
- mimeType: params['mimeType'] as string | undefined,
755
- content: (params['content'] as string | undefined) ?? '',
756
- title: (params['title'] as string | null) ?? null,
757
- description: (params['description'] as string | null) ?? null,
758
- docid: (params['docid'] as string | null) ?? null,
759
- typeName: updTypeName,
760
- };
761
- const encoded = encodeUpdateSectionParams(oldKbid, input);
762
- const bytes = this.callWasmSync('worker_update_section', encoded);
763
- const newKbid = new TextDecoder().decode(bytes);
764
- return { kbid: newKbid };
765
- }
766
-
767
- private handleReadSections(
768
- params: Record<string, unknown>,
769
- ): unknown {
770
- const kbids = (params['kbids'] ?? []) as string[];
771
- const encoded = encodeKbidList(kbids);
772
- const bytes = this.callWasmSync('worker_read_sections', encoded);
773
- return decodeSectionRecords(bytes);
774
- }
775
-
776
- private handleGroupSections(
777
- params: Record<string, unknown>,
778
- ): unknown {
779
- const title = (params['title'] as string | undefined) ?? '';
780
- const kbids = (params['kbids'] ?? []) as string[];
781
- const docType = (params['docType'] as string | undefined) ?? '';
782
- const encoded = encodeGroupParams(title, kbids, docType);
783
- const bytes = this.callWasmSync('worker_group_sections', encoded);
784
- const docid = new TextDecoder().decode(bytes);
785
- return { docid };
786
- }
787
-
788
- private handleCompose(params: Record<string, unknown>): unknown {
789
- const ids = (params['ids'] ?? []) as string[];
790
- const encoded = encodeIdentifierList(ids);
791
- const bytes = this.callWasmSync('worker_compose', encoded);
792
- const output = decodeComposeOutput(bytes);
793
- return {
794
- data: output.markdown,
795
- total: Number(output.totalChars),
796
- };
797
- }
798
-
799
- // -- Raw UTF-8 string input methods --
800
-
801
- private handleRemoveSection(
802
- params: Record<string, unknown>,
803
- ): unknown {
804
- const kbid = (params['kbid'] as string | undefined) ?? '';
805
- const encoded = new TextEncoder().encode(kbid);
806
- const bytes = this.callWasmSync('worker_remove_section', encoded);
807
- return { removed: decodeRemoveFlag(bytes) };
808
- }
809
-
810
- private handleRetrieveDoc(params: Record<string, unknown>): unknown {
811
- const docid = (params['docid'] as string | undefined) ?? '';
812
- const encoded = new TextEncoder().encode(docid);
813
- const bytes = this.callWasmSync('worker_retrieve_doc', encoded);
814
- return decodeDocumentManifest(bytes);
815
- }
816
-
817
- private handleRemoveGrouping(
818
- params: Record<string, unknown>,
819
- ): unknown {
820
- const docid = (params['docid'] as string | undefined) ?? '';
821
- const encoded = new TextEncoder().encode(docid);
822
- this.callWasmSync('worker_remove_grouping', encoded);
823
- return { ok: true };
824
- }
825
-
826
- private handleInitDirectory(
827
- params: Record<string, unknown>,
828
- ): unknown {
829
- const path =
830
- (params['path'] as string | undefined) ?? this.targetDir;
831
- const encoded = new TextEncoder().encode(path);
832
- this.callWasmSync('worker_init_directory', encoded);
833
- return { ok: true };
834
- }
835
-
836
- private handleInvalidate(params: Record<string, unknown>): unknown {
837
- const kbid = (params['kbid'] as string | undefined) ?? '';
838
- const encoded = new TextEncoder().encode(kbid);
839
- const fn = this.getExport('worker_invalidate');
840
- const ptr = this.wasmAlloc(encoded.length);
841
- this.wasmWrite(ptr, encoded);
842
- const rc = fn(ptr, encoded.length) as number;
843
- this.wasmFree(ptr, encoded.length);
844
- if (rc === -1) {
845
- const errBytes = this.readReturnSlot();
846
- throw new IpcError(
847
- -32000,
848
- new TextDecoder().decode(errBytes) || 'invalidate failed',
849
- );
850
- }
851
- return { ok: true };
852
- }
853
-
854
- private handleListByType(params: Record<string, unknown>): unknown {
855
- const typeStr =
856
- (params['sectionType'] as string | undefined) ?? '';
857
- const encoded = encodeTypeFilterParam(typeStr);
858
- const bytes = this.callWasmSync('worker_list_by_type', encoded);
859
- return decodeSectionRecordList(bytes);
860
- }
861
-
862
- private handleListDocsByType(
863
- params: Record<string, unknown>,
864
- ): unknown {
865
- const typeStr = (params['docType'] as string | undefined) ?? '';
866
- const encoded = encodeTypeFilterParam(typeStr);
867
- const bytes = this.callWasmSync(
868
- 'worker_list_docs_by_type',
869
- encoded,
870
- );
871
- return decodeDocumentManifestList(bytes);
872
- }
873
-
874
- private handleRecall(params: Record<string, unknown>): unknown {
875
- const kbid =
876
- typeof params['kbid'] === 'string'
877
- ? params['kbid']
878
- : undefined;
879
- const kbids = Array.isArray(params['kbids'])
880
- ? (params['kbids'] as string[])
881
- : undefined;
882
- const depth = Number(params['depth'] ?? 0);
883
- const encoded = encodeRecallParams({ kbid, kbids, depth });
884
- const bytes = this.callWasmSync('worker_recall', encoded);
885
- return decodeRecallResult(bytes);
886
- }
887
-
888
- // -- Zero-arg methods --
889
-
890
- private handleInvalidateAll(): unknown {
891
- this.callWasmZeroArg('worker_invalidate_all');
892
- return { ok: true };
893
- }
894
-
895
- private handleDbStatus(): unknown {
896
- this.callWasmZeroArg('worker_status');
897
- const bytes = this.readReturnSlot();
898
- const text = new TextDecoder().decode(bytes);
899
- return decodeKeyValueText(text);
900
- }
901
-
902
- private handleIntegrityCheck(): unknown {
903
- this.callWasmZeroArg('worker_check_integrity');
904
- const bytes = this.readReturnSlot();
905
- const text = new TextDecoder().decode(bytes);
906
- return decodeKeyValueText(text);
907
- }
908
-
909
- private handleGc(): unknown {
910
- const start = Date.now();
911
- this.callWasmZeroArg('worker_garbage_collect');
912
- const bytes = this.readReturnSlot();
913
- const text = new TextDecoder().decode(bytes);
914
- const kv = decodeKeyValueText(text);
915
- const removedCount = Number(kv['removed'] ?? 0);
916
- const staleSources = Number(kv['stale_sources'] ?? 0);
917
- return {
918
- removed_sections: removedCount,
919
- removed_bytes: 0,
920
- elapsed_ms: Date.now() - start,
921
- stale_sources: staleSources,
922
- };
923
- }
924
-
925
- private handleRebuild(): unknown {
926
- const fn = this.getExport('worker_rebuild_indexes');
927
- const rc = fn() as number;
928
- if (rc === -1) {
929
- const errBytes = this.readReturnSlot();
930
- const errMsg = new TextDecoder().decode(errBytes);
931
- throw new IpcError(-32000, errMsg || 'rebuild failed');
932
- }
933
- const resultBytes = this.readReturnSlot();
934
- const reindexed =
935
- resultBytes.length >= 4
936
- ? new DataView(
937
- resultBytes.buffer,
938
- resultBytes.byteOffset,
939
- resultBytes.byteLength,
940
- ).getUint32(0, true)
941
- : 0;
942
- return { ok: true, sections_reindexed: reindexed };
943
- }
944
-
945
- // -- Export (read operation, no lock required) --
946
-
947
- private handleExport(params: Record<string, unknown>): unknown {
948
- const targetPath =
949
- (params['targetPath'] as string | undefined) ??
950
- (params['path'] as string | undefined) ??
951
- './kbdb-export/';
952
- const encoded = new TextEncoder().encode(targetPath);
953
- const start = Date.now();
954
- const bytes = this.callWasmSync('worker_export', encoded);
955
- const elapsed = Date.now() - start;
956
- const text = new TextDecoder().decode(bytes);
957
- const kv = decodeKeyValueText(text);
958
- return {
959
- path: kv['path'] ?? targetPath,
960
- sections_exported: Number(kv['sections_exported'] ?? 0),
961
- documents_exported: Number(kv['documents_exported'] ?? 0),
962
- elapsed_ms: elapsed,
963
- };
964
- }
965
-
966
- // -- Near-duplicate detection --
967
-
968
- private scanNearDuplicates(
969
- content: string,
970
- newKbid: string,
971
- ): { kbid: string; similarity: number }[] {
972
- const newTerms = this.extractTermSet(content);
973
- if (newTerms.size === 0) return [];
974
-
975
- const sectionsDir = join(this.targetDir, 'sections');
976
- let shards: string[];
977
- try {
978
- shards = readdirSync(sectionsDir);
979
- } catch {
980
- return [];
981
- }
982
-
983
- const results: { kbid: string; similarity: number }[] = [];
984
- for (const shard of shards) {
985
- let files: string[];
986
- try {
987
- files = readdirSync(join(sectionsDir, shard));
988
- } catch {
989
- continue;
990
- }
991
- for (const file of files) {
992
- if (!file.endsWith('.section')) continue;
993
- const kbid = file.slice(0, -8);
994
- if (kbid === newKbid) continue;
995
- try {
996
- const data = readFileSync(
997
- join(sectionsDir, shard, file),
998
- 'utf-8',
999
- );
1000
- const sep = data.indexOf('\n---\n');
1001
- const body = sep >= 0 ? data.slice(sep + 5) : data;
1002
- const existing = this.extractTermSet(body);
1003
- let intersection = 0;
1004
- for (const t of newTerms) {
1005
- if (existing.has(t)) intersection++;
1006
- }
1007
- const union =
1008
- newTerms.size + existing.size - intersection;
1009
- const sim = union > 0 ? intersection / union : 0;
1010
- if (sim >= 0.85) {
1011
- results.push({
1012
- kbid,
1013
- similarity: Math.round(sim * 100) / 100,
1014
- });
1015
- }
1016
- } catch {
1017
- continue;
1018
- }
1019
- }
1020
- }
1021
- return results;
1022
- }
1023
-
1024
- private extractTermSet(text: string): Set<string> {
1025
- return new Set(
1026
- text
1027
- .toLowerCase()
1028
- .split(/\W+/)
1029
- .filter((w) => w.length > 2),
1030
- );
1031
- }
1032
-
1033
- // -- Single-writer lock --
1034
-
1035
- /**
1036
- * Acquires the write lock.
1037
- *
1038
- * If the lock is free it is granted immediately. If it is held the
1039
- * caller is queued and its promise resolves once the lock is
1040
- * released by the current holder.
1041
- */
1042
- private acquireWriteLock(): Promise<void> {
1043
- if (!this._writeLocked) {
1044
- this._writeLocked = true;
1045
- return Promise.resolve();
1046
- }
1047
- return new Promise<void>((resolve) => {
1048
- this._writeQueue.push({ resolve });
1049
- });
1050
- }
1051
-
1052
- /**
1053
- * Releases the write lock.
1054
- *
1055
- * If waiters are queued the next one is granted the lock
1056
- * immediately. Otherwise the lock is marked free.
1057
- */
1058
- private releaseWriteLock(): void {
1059
- const next = this._writeQueue.shift();
1060
- if (next !== undefined) {
1061
- next.resolve();
1062
- } else {
1063
- this._writeLocked = false;
1064
- }
1065
- }
1066
-
1067
- // -- WASM lifecycle --
1068
-
1069
- private initWorkerContext(): void {
1070
- const pathBytes = new TextEncoder().encode('.');
1071
- this.callWasmSync('worker_init', pathBytes);
1072
- }
1073
-
1074
- /**
1075
- * Runs a database integrity check immediately after context
1076
- * initialisation.
1077
- *
1078
- * Stores the result in `_integrityOk` and `_integrityErrors`.
1079
- * Logs a warning to stderr when issues are found so operators
1080
- * are alerted without aborting the daemon.
1081
- */
1082
- private runStartupIntegrityCheck(): void {
1083
- try {
1084
- this.callWasmZeroArg('worker_check_integrity');
1085
- const bytes = this.readReturnSlot();
1086
- const text = new TextDecoder().decode(bytes);
1087
- const kv = decodeKeyValueText(text);
1088
- this._integrityOk = kv['ok'] === 'true';
1089
- if (!this._integrityOk) {
1090
- this._integrityErrors = Object.entries(kv)
1091
- .filter(([k]) => k !== 'ok')
1092
- .map(([k, v]) => `${k}=${v}`);
1093
- // eslint-disable-next-line no-console
1094
- console.error(
1095
- '[kbdb-worker] startup integrity check failed:',
1096
- this._integrityErrors.join(', '),
1097
- );
1098
- }
1099
- } catch {
1100
- this._integrityOk = false;
1101
- this._integrityErrors = ['integrity_check_failed'];
1102
- // eslint-disable-next-line no-console
1103
- console.error(
1104
- '[kbdb-worker] startup integrity check threw an error',
1105
- );
1106
- }
1107
- }
1108
-
1109
- // -- WASM bridge primitives --
1110
-
1111
- private getExport(name: string): WasmFn {
1112
- if (this._wasmModules === null) {
1113
- throw new Error('WASM modules not loaded');
1114
- }
1115
- const fn = this._wasmModules.kbWorker.exports[name] as
1116
- | WasmFn
1117
- | undefined;
1118
- if (typeof fn !== 'function') {
1119
- throw new Error(`WASM export not found: ${name}`);
1120
- }
1121
- return fn;
1122
- }
1123
-
1124
- private wasmAlloc(size: number): number {
1125
- if (size === 0) return 0;
1126
- const allocFn = this._wasmModules?.kbWorker.exports[
1127
- 'kbdb_alloc'
1128
- ] as WasmFn | undefined;
1129
- if (typeof allocFn !== 'function') return 0;
1130
- return allocFn(size) as number;
1131
- }
1132
-
1133
- private wasmFree(ptr: number, size: number): void {
1134
- if (ptr === 0 || size === 0) return;
1135
- const freeFn = this._wasmModules?.kbWorker.exports[
1136
- 'kbdb_free'
1137
- ] as WasmFn | undefined;
1138
- if (typeof freeFn === 'function') {
1139
- freeFn(ptr, size);
1140
- }
1141
- }
1142
-
1143
- private wasmWrite(ptr: number, data: Uint8Array): void {
1144
- if (data.length === 0) return;
1145
- const memory = this._wasmModules?.memory;
1146
- if (!memory) return;
1147
- const memView = new Uint8Array(memory.buffer);
1148
- if (ptr + data.length > memView.length) {
1149
- throw new Error('WASM memory overflow');
1150
- }
1151
- memView.set(data, ptr);
1152
- }
1153
-
1154
- private readReturnSlot(): Uint8Array {
1155
- const getPtrFn = this._wasmModules?.kbWorker.exports[
1156
- 'get_return_ptr'
1157
- ] as WasmFn | undefined;
1158
- const getLenFn = this._wasmModules?.kbWorker.exports[
1159
- 'get_return_len'
1160
- ] as WasmFn | undefined;
1161
- if (
1162
- typeof getPtrFn !== 'function' ||
1163
- typeof getLenFn !== 'function'
1164
- ) {
1165
- return new Uint8Array(0);
1166
- }
1167
- const ptr = getPtrFn() as number;
1168
- const len = getLenFn() as number;
1169
- if (ptr === 0 || len === 0) {
1170
- return new Uint8Array(0);
1171
- }
1172
- const memory = this._wasmModules?.memory;
1173
- if (!memory) return new Uint8Array(0);
1174
- const data = new Uint8Array(memory.buffer, ptr, len).slice();
1175
- this.wasmFree(ptr, len);
1176
- return data;
1177
- }
1178
-
1179
- private callWasmSync(
1180
- exportName: string,
1181
- input: Uint8Array,
1182
- ): Uint8Array {
1183
- const fn = this.getExport(exportName);
1184
- const ptr = this.wasmAlloc(input.length);
1185
- this.wasmWrite(ptr, input);
1186
- const rc = fn(ptr, input.length) as number;
1187
- this.wasmFree(ptr, input.length);
1188
- if (rc === -1) {
1189
- const errBytes = this.readReturnSlot();
1190
- const errMsg = new TextDecoder().decode(errBytes);
1191
- throw new IpcError(-32000, errMsg || exportName + ' failed');
1192
- }
1193
- return this.readReturnSlot();
1194
- }
1195
-
1196
- private callWasmZeroArg(exportName: string): void {
1197
- const fn = this.getExport(exportName);
1198
- const rc = fn() as number;
1199
- if (rc === -1) {
1200
- const errBytes = this.readReturnSlot();
1201
- const errMsg = new TextDecoder().decode(errBytes);
1202
- throw new IpcError(-32000, errMsg || exportName + ' failed');
1203
- }
1204
- }
1205
-
1206
- private invokeWasmRaw(
1207
- exportName: string,
1208
- input: Uint8Array,
1209
- ): unknown {
1210
- return this.callWasmSync(exportName, input);
1211
- }
1212
-
1213
- private handleCheckVersion(
1214
- params: Record<string, unknown>,
1215
- ): unknown {
1216
- const targetPath =
1217
- typeof params.targetPath === 'string'
1218
- ? params.targetPath
1219
- : this.targetDir;
1220
- const catalogPath = join(targetPath, 'catalog.toml');
1221
- let text: string;
1222
- try {
1223
- text = readFileSync(catalogPath, 'utf-8');
1224
- } catch {
1225
- return {
1226
- status: 'needs_migration',
1227
- currentVersion: 0,
1228
- requiredVersion: DB_FORMAT_VERSION,
1229
- };
1230
- }
1231
- const version = parseCatalogVersion(text);
1232
- if (version === null) {
1233
- return {
1234
- status: 'needs_migration',
1235
- currentVersion: 0,
1236
- requiredVersion: DB_FORMAT_VERSION,
1237
- };
1238
- }
1239
- if (version > DB_FORMAT_VERSION) {
1240
- return {
1241
- status: 'too_new',
1242
- currentVersion: version,
1243
- requiredVersion: DB_FORMAT_VERSION,
1244
- };
1245
- }
1246
- if (version < DB_FORMAT_VERSION) {
1247
- return {
1248
- status: 'needs_migration',
1249
- currentVersion: version,
1250
- requiredVersion: DB_FORMAT_VERSION,
1251
- };
1252
- }
1253
- return {
1254
- status: 'compatible',
1255
- currentVersion: version,
1256
- requiredVersion: DB_FORMAT_VERSION,
1257
- };
1258
- }
1259
-
1260
- /** Returns a daemon config value by config method name. */
1261
- private handleConfigMethod(method: string): unknown {
1262
- const key = method.slice(CONFIG_PREFIX.length);
1263
- const prop = CONFIG_KEY_MAP[key];
1264
- if (prop === undefined) {
1265
- throw new IpcError(-32601, `Method not found: ${method}`);
1266
- }
1267
- return this.config[prop];
1268
- }
1269
- }
1270
-
1271
- // ---------------------------------------------------------------------------
1272
- // Module-private helpers
1273
- // ---------------------------------------------------------------------------
1274
-
1275
- /**
1276
- * Parses the `version` field from a minimal TOML string.
1277
- *
1278
- * Supports only `version = <integer>` syntax. Returns `null` if the
1279
- * field is absent.
1280
- */
1281
- function parseCatalogVersion(text: string): number | null {
1282
- for (const line of text.split('\n')) {
1283
- const trimmed = line.trim();
1284
- if (trimmed.startsWith('#')) continue;
1285
- const match = /^version\s*=\s*(\d+)/.exec(trimmed);
1286
- if (match?.[1] !== undefined) {
1287
- return parseInt(match[1], 10);
1288
- }
1289
- }
1290
- return null;
1291
- }