@dikolab/kbdb 0.1.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 (308) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +270 -0
  3. package/dist/chunk-QCCN7OZH.mjs +82 -0
  4. package/dist/chunk-QCCN7OZH.mjs.map +7 -0
  5. package/dist/cli.cjs +3598 -0
  6. package/dist/cli.cjs.map +7 -0
  7. package/dist/cli.mjs +3537 -0
  8. package/dist/cli.mjs.map +7 -0
  9. package/dist/kbdb-worker.cjs +1659 -0
  10. package/dist/kbdb-worker.cjs.map +7 -0
  11. package/dist/mod.cjs +538 -0
  12. package/dist/mod.cjs.map +7 -0
  13. package/dist/mod.d.ts +3 -0
  14. package/dist/mod.mjs +507 -0
  15. package/dist/mod.mjs.map +7 -0
  16. package/dist/src/cli.d.ts +1 -0
  17. package/dist/src/shared/cli/constants/defaults.constant.d.ts +11 -0
  18. package/dist/src/shared/cli/constants/help-text.constant.d.ts +2 -0
  19. package/dist/src/shared/cli/functions/dispatch-command.function.d.ts +37 -0
  20. package/dist/src/shared/cli/functions/ensure-db.function.d.ts +11 -0
  21. package/dist/src/shared/cli/functions/error-to-message.function.d.ts +7 -0
  22. package/dist/src/shared/cli/functions/find-db.function.d.ts +13 -0
  23. package/dist/src/shared/cli/functions/format-output.function.d.ts +15 -0
  24. package/dist/src/shared/cli/functions/generate-help.function.d.ts +31 -0
  25. package/dist/src/shared/cli/functions/is-stdin-tty.function.d.ts +7 -0
  26. package/dist/src/shared/cli/functions/parse-args.function.d.ts +25 -0
  27. package/dist/src/shared/cli/functions/prompt-user.function.d.ts +13 -0
  28. package/dist/src/shared/cli/functions/run-agent-create.function.d.ts +58 -0
  29. package/dist/src/shared/cli/functions/run-agent-delete.function.d.ts +32 -0
  30. package/dist/src/shared/cli/functions/run-agent-get.function.d.ts +46 -0
  31. package/dist/src/shared/cli/functions/run-agent-list.function.d.ts +45 -0
  32. package/dist/src/shared/cli/functions/run-check.function.d.ts +64 -0
  33. package/dist/src/shared/cli/functions/run-cli.function.d.ts +39 -0
  34. package/dist/src/shared/cli/functions/run-content.function.d.ts +40 -0
  35. package/dist/src/shared/cli/functions/run-db-init.function.d.ts +23 -0
  36. package/dist/src/shared/cli/functions/run-db-migrate.function.d.ts +32 -0
  37. package/dist/src/shared/cli/functions/run-gc.function.d.ts +38 -0
  38. package/dist/src/shared/cli/functions/run-init.function.d.ts +27 -0
  39. package/dist/src/shared/cli/functions/run-learn.function.d.ts +46 -0
  40. package/dist/src/shared/cli/functions/run-migrate.function.d.ts +57 -0
  41. package/dist/src/shared/cli/functions/run-rebuild.function.d.ts +40 -0
  42. package/dist/src/shared/cli/functions/run-search.function.d.ts +39 -0
  43. package/dist/src/shared/cli/functions/run-skill-delete.function.d.ts +30 -0
  44. package/dist/src/shared/cli/functions/run-skill-get.function.d.ts +49 -0
  45. package/dist/src/shared/cli/functions/run-skill-learn.function.d.ts +36 -0
  46. package/dist/src/shared/cli/functions/run-skill-list.function.d.ts +43 -0
  47. package/dist/src/shared/cli/functions/run-status.function.d.ts +22 -0
  48. package/dist/src/shared/cli/functions/run-unlearn.function.d.ts +45 -0
  49. package/dist/src/shared/cli/index.d.ts +35 -0
  50. package/dist/src/shared/cli/typings/cli-options.interface.d.ts +53 -0
  51. package/dist/src/shared/cli/typings/command-result.model.d.ts +15 -0
  52. package/dist/src/shared/cli/typings/learn-result.model.d.ts +11 -0
  53. package/dist/src/shared/cli/typings/search-display.model.d.ts +17 -0
  54. package/dist/src/shared/dir-resolver/functions/resolve-base-dir.function.d.ts +3 -0
  55. package/dist/src/shared/dir-resolver/functions/resolve-wasm-dir.function.d.ts +1 -0
  56. package/dist/src/shared/dir-resolver/functions/resolve-worker-script.function.d.ts +2 -0
  57. package/dist/src/shared/dir-resolver/index.d.ts +4 -0
  58. package/dist/src/shared/dir-resolver/typings/base-dir.interface.d.ts +4 -0
  59. package/dist/src/shared/hash/functions/compute-sha256.d.ts +10 -0
  60. package/dist/src/shared/hash/index.d.ts +1 -0
  61. package/dist/src/shared/mcp/classes/mcp-server.class.d.ts +55 -0
  62. package/dist/src/shared/mcp/constants/mcp-error-codes.constant.d.ts +26 -0
  63. package/dist/src/shared/mcp/functions/create-mcp-server.function.d.ts +11 -0
  64. package/dist/src/shared/mcp/functions/create-prompt-definitions.function.d.ts +41 -0
  65. package/dist/src/shared/mcp/functions/create-resource-templates.function.d.ts +7 -0
  66. package/dist/src/shared/mcp/functions/create-tool-definitions.function.d.ts +7 -0
  67. package/dist/src/shared/mcp/functions/extract-skill-arguments.function.d.ts +13 -0
  68. package/dist/src/shared/mcp/functions/handle-agent-create.function.d.ts +29 -0
  69. package/dist/src/shared/mcp/functions/handle-agent-delete.function.d.ts +28 -0
  70. package/dist/src/shared/mcp/functions/handle-agent-get.function.d.ts +29 -0
  71. package/dist/src/shared/mcp/functions/handle-agent-list.function.d.ts +31 -0
  72. package/dist/src/shared/mcp/functions/handle-completion.function.d.ts +58 -0
  73. package/dist/src/shared/mcp/functions/handle-prompt-get.function.d.ts +23 -0
  74. package/dist/src/shared/mcp/functions/handle-resource-read.function.d.ts +26 -0
  75. package/dist/src/shared/mcp/functions/handle-roots-list.function.d.ts +21 -0
  76. package/dist/src/shared/mcp/functions/handle-tool-call.function.d.ts +26 -0
  77. package/dist/src/shared/mcp/functions/parse-skill-content.function.d.ts +15 -0
  78. package/dist/src/shared/mcp/functions/serialize-skill-content.function.d.ts +9 -0
  79. package/dist/src/shared/mcp/functions/should-emit-log.function.d.ts +20 -0
  80. package/dist/src/shared/mcp/index.d.ts +9 -0
  81. package/dist/src/shared/mcp/typings/agent-types.interface.d.ts +38 -0
  82. package/dist/src/shared/mcp/typings/log-types.interface.d.ts +17 -0
  83. package/dist/src/shared/mcp/typings/mcp-client.interface.d.ts +217 -0
  84. package/dist/src/shared/mcp/typings/mcp-types.interface.d.ts +149 -0
  85. package/dist/src/shared/mcp/typings/prompt-types.interface.d.ts +37 -0
  86. package/dist/src/shared/mcp/typings/remove-section-result.model.d.ts +10 -0
  87. package/dist/src/shared/mcp/typings/sampling-types.interface.d.ts +46 -0
  88. package/dist/src/shared/mcp/typings/skill-types.interface.d.ts +28 -0
  89. package/dist/src/shared/mod.d.ts +1 -0
  90. package/dist/src/shared/platform/functions/get-ipc-path.function.d.ts +11 -0
  91. package/dist/src/shared/platform/functions/get-tmpdir.function.d.ts +4 -0
  92. package/dist/src/shared/platform/functions/is-process-alive.function.d.ts +10 -0
  93. package/dist/src/shared/platform/index.d.ts +3 -0
  94. package/dist/src/shared/runtime/functions/detect-runtime.d.ts +8 -0
  95. package/dist/src/shared/runtime/functions/get-args.d.ts +7 -0
  96. package/dist/src/shared/runtime/index.d.ts +3 -0
  97. package/dist/src/shared/runtime/typings/runtime.d.ts +2 -0
  98. package/dist/src/shared/version/constants/version.constant.d.ts +2 -0
  99. package/dist/src/shared/version/index.d.ts +1 -0
  100. package/dist/src/shared/wasm-codec/functions/decode-compose-output.function.d.ts +5 -0
  101. package/dist/src/shared/wasm-codec/functions/decode-document-manifest-list.function.d.ts +14 -0
  102. package/dist/src/shared/wasm-codec/functions/decode-document-manifest.function.d.ts +40 -0
  103. package/dist/src/shared/wasm-codec/functions/decode-f32.function.d.ts +2 -0
  104. package/dist/src/shared/wasm-codec/functions/decode-key-value-text.function.d.ts +1 -0
  105. package/dist/src/shared/wasm-codec/functions/decode-remove-flag.function.d.ts +1 -0
  106. package/dist/src/shared/wasm-codec/functions/decode-scored-results.function.d.ts +10 -0
  107. package/dist/src/shared/wasm-codec/functions/decode-section-record-list.function.d.ts +13 -0
  108. package/dist/src/shared/wasm-codec/functions/decode-section-records.function.d.ts +50 -0
  109. package/dist/src/shared/wasm-codec/functions/decode-string.function.d.ts +5 -0
  110. package/dist/src/shared/wasm-codec/functions/decode-u32.function.d.ts +2 -0
  111. package/dist/src/shared/wasm-codec/functions/decode-u64.function.d.ts +2 -0
  112. package/dist/src/shared/wasm-codec/functions/encode-add-section-params.function.d.ts +10 -0
  113. package/dist/src/shared/wasm-codec/functions/encode-group-params.function.d.ts +10 -0
  114. package/dist/src/shared/wasm-codec/functions/encode-identifier-list.function.d.ts +1 -0
  115. package/dist/src/shared/wasm-codec/functions/encode-kbid-list.function.d.ts +1 -0
  116. package/dist/src/shared/wasm-codec/functions/encode-option-string.function.d.ts +1 -0
  117. package/dist/src/shared/wasm-codec/functions/encode-search-params.function.d.ts +1 -0
  118. package/dist/src/shared/wasm-codec/functions/encode-section-type.function.d.ts +1 -0
  119. package/dist/src/shared/wasm-codec/functions/encode-string.function.d.ts +1 -0
  120. package/dist/src/shared/wasm-codec/functions/encode-type-filter-param.function.d.ts +11 -0
  121. package/dist/src/shared/wasm-codec/functions/encode-u32.function.d.ts +1 -0
  122. package/dist/src/shared/wasm-codec/functions/encode-update-section-params.function.d.ts +2 -0
  123. package/dist/src/shared/wasm-codec/index.d.ts +29 -0
  124. package/dist/src/shared/worker-client/classes/worker-client.class.d.ts +230 -0
  125. package/dist/src/shared/worker-client/functions/compute-context-id.function.d.ts +11 -0
  126. package/dist/src/shared/worker-client/functions/create-worker-client.function.d.ts +18 -0
  127. package/dist/src/shared/worker-client/functions/discover-daemon.function.d.ts +14 -0
  128. package/dist/src/shared/worker-client/functions/resolve-db-path.function.d.ts +11 -0
  129. package/dist/src/shared/worker-client/functions/spawn-daemon.function.d.ts +11 -0
  130. package/dist/src/shared/worker-client/functions/wait-for-daemon.function.d.ts +13 -0
  131. package/dist/src/shared/worker-client/index.d.ts +22 -0
  132. package/dist/src/shared/worker-client/typings/add-section-result.model.d.ts +22 -0
  133. package/dist/src/shared/worker-client/typings/content-result.model.d.ts +12 -0
  134. package/dist/src/shared/worker-client/typings/daemon-info.model.d.ts +7 -0
  135. package/dist/src/shared/worker-client/typings/gc-result.model.d.ts +12 -0
  136. package/dist/src/shared/worker-client/typings/integrity-check-result.model.d.ts +36 -0
  137. package/dist/src/shared/worker-client/typings/migrate-result.model.d.ts +11 -0
  138. package/dist/src/shared/worker-client/typings/rebuild-result.model.d.ts +12 -0
  139. package/dist/src/shared/worker-client/typings/remove-section-result.model.d.ts +7 -0
  140. package/dist/src/shared/worker-client/typings/search-params.model.d.ts +12 -0
  141. package/dist/src/shared/worker-client/typings/search-result.model.d.ts +14 -0
  142. package/dist/src/shared/worker-client/typings/section.model.d.ts +26 -0
  143. package/dist/src/shared/worker-client/typings/status-result.model.d.ts +14 -0
  144. package/dist/src/shared/worker-client/typings/version-status.model.d.ts +24 -0
  145. package/dist/src/shared/worker-client/typings/worker-client-error.interface.d.ts +8 -0
  146. package/dist/src/shared/worker-client/typings/worker-client-options.interface.d.ts +30 -0
  147. package/dist/src/shared/worker-daemon/classes/worker-daemon.class.d.ts +147 -0
  148. package/dist/src/shared/worker-daemon/constants/daemon-defaults.constant.d.ts +24 -0
  149. package/dist/src/shared/worker-daemon/functions/create-host-imports.function.d.ts +68 -0
  150. package/dist/src/shared/worker-daemon/functions/create-ipc-server.function.d.ts +18 -0
  151. package/dist/src/shared/worker-daemon/functions/load-wasm-modules.function.d.ts +19 -0
  152. package/dist/src/shared/worker-daemon/functions/read-config.function.d.ts +12 -0
  153. package/dist/src/shared/worker-daemon/functions/run-worker.function.d.ts +26 -0
  154. package/dist/src/shared/worker-daemon/functions/start-daemon.function.d.ts +13 -0
  155. package/dist/src/shared/worker-daemon/index.d.ts +9 -0
  156. package/dist/src/shared/worker-daemon/typings/daemon-config.interface.d.ts +13 -0
  157. package/dist/src/shared/worker-daemon/typings/ipc-handler.interface.d.ts +36 -0
  158. package/dist/src/shared/worker-daemon/typings/wasm-modules.interface.d.ts +7 -0
  159. package/dist/src/worker.d.ts +1 -0
  160. package/dist/vitest.config.d.ts +2 -0
  161. package/dist/worker.mjs +1615 -0
  162. package/dist/worker.mjs.map +7 -0
  163. package/mod.ts +17 -0
  164. package/package.json +85 -0
  165. package/src/cli.ts +62 -0
  166. package/src/shared/cli/constants/defaults.constant.ts +19 -0
  167. package/src/shared/cli/constants/help-text.constant.ts +4 -0
  168. package/src/shared/cli/functions/dispatch-command.function.ts +338 -0
  169. package/src/shared/cli/functions/ensure-db.function.ts +21 -0
  170. package/src/shared/cli/functions/error-to-message.function.ts +9 -0
  171. package/src/shared/cli/functions/find-db.function.ts +20 -0
  172. package/src/shared/cli/functions/format-output.function.ts +64 -0
  173. package/src/shared/cli/functions/generate-help.function.ts +599 -0
  174. package/src/shared/cli/functions/is-stdin-tty.function.ts +12 -0
  175. package/src/shared/cli/functions/parse-args.function.ts +133 -0
  176. package/src/shared/cli/functions/prompt-user.function.ts +36 -0
  177. package/src/shared/cli/functions/run-agent-create.function.ts +114 -0
  178. package/src/shared/cli/functions/run-agent-delete.function.ts +47 -0
  179. package/src/shared/cli/functions/run-agent-get.function.ts +166 -0
  180. package/src/shared/cli/functions/run-agent-list.function.ts +58 -0
  181. package/src/shared/cli/functions/run-check.function.ts +78 -0
  182. package/src/shared/cli/functions/run-cli.function.ts +299 -0
  183. package/src/shared/cli/functions/run-content.function.ts +47 -0
  184. package/src/shared/cli/functions/run-db-init.function.ts +44 -0
  185. package/src/shared/cli/functions/run-db-migrate.function.ts +40 -0
  186. package/src/shared/cli/functions/run-gc.function.ts +45 -0
  187. package/src/shared/cli/functions/run-init.function.ts +91 -0
  188. package/src/shared/cli/functions/run-learn.function.ts +171 -0
  189. package/src/shared/cli/functions/run-migrate.function.ts +85 -0
  190. package/src/shared/cli/functions/run-rebuild.function.ts +47 -0
  191. package/src/shared/cli/functions/run-search.function.ts +62 -0
  192. package/src/shared/cli/functions/run-skill-delete.function.ts +47 -0
  193. package/src/shared/cli/functions/run-skill-get.function.ts +90 -0
  194. package/src/shared/cli/functions/run-skill-learn.function.ts +70 -0
  195. package/src/shared/cli/functions/run-skill-list.function.ts +74 -0
  196. package/src/shared/cli/functions/run-status.function.ts +29 -0
  197. package/src/shared/cli/functions/run-unlearn.function.ts +58 -0
  198. package/src/shared/cli/index.ts +48 -0
  199. package/src/shared/cli/typings/cli-options.interface.ts +55 -0
  200. package/src/shared/cli/typings/command-result.model.ts +15 -0
  201. package/src/shared/cli/typings/learn-result.model.ts +11 -0
  202. package/src/shared/cli/typings/search-display.model.ts +17 -0
  203. package/src/shared/dir-resolver/functions/resolve-base-dir.function.ts +25 -0
  204. package/src/shared/dir-resolver/functions/resolve-wasm-dir.function.ts +5 -0
  205. package/src/shared/dir-resolver/functions/resolve-worker-script.function.ts +13 -0
  206. package/src/shared/dir-resolver/index.ts +7 -0
  207. package/src/shared/dir-resolver/typings/base-dir.interface.ts +4 -0
  208. package/src/shared/hash/functions/compute-sha256.ts +17 -0
  209. package/src/shared/hash/index.ts +1 -0
  210. package/src/shared/mcp/classes/mcp-server.class.ts +448 -0
  211. package/src/shared/mcp/constants/mcp-error-codes.constant.ts +30 -0
  212. package/src/shared/mcp/functions/create-mcp-server.function.ts +14 -0
  213. package/src/shared/mcp/functions/create-prompt-definitions.function.ts +102 -0
  214. package/src/shared/mcp/functions/create-resource-templates.function.ts +23 -0
  215. package/src/shared/mcp/functions/create-tool-definitions.function.ts +401 -0
  216. package/src/shared/mcp/functions/extract-skill-arguments.function.ts +27 -0
  217. package/src/shared/mcp/functions/handle-agent-create.function.ts +116 -0
  218. package/src/shared/mcp/functions/handle-agent-delete.function.ts +50 -0
  219. package/src/shared/mcp/functions/handle-agent-get.function.ts +160 -0
  220. package/src/shared/mcp/functions/handle-agent-list.function.ts +50 -0
  221. package/src/shared/mcp/functions/handle-completion.function.ts +114 -0
  222. package/src/shared/mcp/functions/handle-prompt-get.function.ts +214 -0
  223. package/src/shared/mcp/functions/handle-resource-read.function.ts +56 -0
  224. package/src/shared/mcp/functions/handle-roots-list.function.ts +29 -0
  225. package/src/shared/mcp/functions/handle-tool-call.function.ts +464 -0
  226. package/src/shared/mcp/functions/parse-skill-content.function.ts +38 -0
  227. package/src/shared/mcp/functions/serialize-skill-content.function.ts +12 -0
  228. package/src/shared/mcp/functions/should-emit-log.function.ts +38 -0
  229. package/src/shared/mcp/index.ts +28 -0
  230. package/src/shared/mcp/typings/agent-types.interface.ts +39 -0
  231. package/src/shared/mcp/typings/log-types.interface.ts +26 -0
  232. package/src/shared/mcp/typings/mcp-client.interface.ts +252 -0
  233. package/src/shared/mcp/typings/mcp-types.interface.ts +158 -0
  234. package/src/shared/mcp/typings/prompt-types.interface.ts +39 -0
  235. package/src/shared/mcp/typings/remove-section-result.model.ts +10 -0
  236. package/src/shared/mcp/typings/sampling-types.interface.ts +48 -0
  237. package/src/shared/mcp/typings/skill-types.interface.ts +29 -0
  238. package/src/shared/mod.ts +1 -0
  239. package/src/shared/platform/functions/get-ipc-path.function.ts +19 -0
  240. package/src/shared/platform/functions/get-tmpdir.function.ts +8 -0
  241. package/src/shared/platform/functions/is-process-alive.function.ts +17 -0
  242. package/src/shared/platform/index.ts +3 -0
  243. package/src/shared/runtime/functions/detect-runtime.ts +14 -0
  244. package/src/shared/runtime/functions/get-args.ts +16 -0
  245. package/src/shared/runtime/index.ts +3 -0
  246. package/src/shared/runtime/typings/runtime.ts +2 -0
  247. package/src/shared/version/constants/version.constant.ts +2 -0
  248. package/src/shared/version/index.ts +1 -0
  249. package/src/shared/wasm-codec/functions/decode-compose-output.function.ts +16 -0
  250. package/src/shared/wasm-codec/functions/decode-document-manifest-list.function.ts +70 -0
  251. package/src/shared/wasm-codec/functions/decode-document-manifest.function.ts +87 -0
  252. package/src/shared/wasm-codec/functions/decode-f32.function.ts +16 -0
  253. package/src/shared/wasm-codec/functions/decode-key-value-text.function.ts +15 -0
  254. package/src/shared/wasm-codec/functions/decode-remove-flag.function.ts +3 -0
  255. package/src/shared/wasm-codec/functions/decode-scored-results.function.ts +54 -0
  256. package/src/shared/wasm-codec/functions/decode-section-record-list.function.ts +20 -0
  257. package/src/shared/wasm-codec/functions/decode-section-records.function.ts +162 -0
  258. package/src/shared/wasm-codec/functions/decode-string.function.ts +22 -0
  259. package/src/shared/wasm-codec/functions/decode-u32.function.ts +16 -0
  260. package/src/shared/wasm-codec/functions/decode-u64.function.ts +16 -0
  261. package/src/shared/wasm-codec/functions/encode-add-section-params.function.ts +34 -0
  262. package/src/shared/wasm-codec/functions/encode-group-params.function.ts +28 -0
  263. package/src/shared/wasm-codec/functions/encode-identifier-list.function.ts +17 -0
  264. package/src/shared/wasm-codec/functions/encode-kbid-list.function.ts +17 -0
  265. package/src/shared/wasm-codec/functions/encode-option-string.function.ts +14 -0
  266. package/src/shared/wasm-codec/functions/encode-search-params.function.ts +9 -0
  267. package/src/shared/wasm-codec/functions/encode-section-type.function.ts +18 -0
  268. package/src/shared/wasm-codec/functions/encode-string.function.ts +9 -0
  269. package/src/shared/wasm-codec/functions/encode-type-filter-param.function.ts +13 -0
  270. package/src/shared/wasm-codec/functions/encode-u32.function.ts +5 -0
  271. package/src/shared/wasm-codec/functions/encode-update-section-params.function.ts +16 -0
  272. package/src/shared/wasm-codec/index.ts +36 -0
  273. package/src/shared/worker-client/classes/worker-client.class.ts +427 -0
  274. package/src/shared/worker-client/functions/compute-context-id.function.ts +18 -0
  275. package/src/shared/worker-client/functions/create-worker-client.function.ts +70 -0
  276. package/src/shared/worker-client/functions/discover-daemon.function.ts +47 -0
  277. package/src/shared/worker-client/functions/resolve-db-path.function.ts +21 -0
  278. package/src/shared/worker-client/functions/spawn-daemon.function.ts +35 -0
  279. package/src/shared/worker-client/functions/wait-for-daemon.function.ts +34 -0
  280. package/src/shared/worker-client/index.ts +31 -0
  281. package/src/shared/worker-client/typings/add-section-result.model.ts +22 -0
  282. package/src/shared/worker-client/typings/content-result.model.ts +12 -0
  283. package/src/shared/worker-client/typings/daemon-info.model.ts +7 -0
  284. package/src/shared/worker-client/typings/gc-result.model.ts +12 -0
  285. package/src/shared/worker-client/typings/integrity-check-result.model.ts +43 -0
  286. package/src/shared/worker-client/typings/migrate-result.model.ts +11 -0
  287. package/src/shared/worker-client/typings/rebuild-result.model.ts +12 -0
  288. package/src/shared/worker-client/typings/remove-section-result.model.ts +7 -0
  289. package/src/shared/worker-client/typings/search-params.model.ts +12 -0
  290. package/src/shared/worker-client/typings/search-result.model.ts +14 -0
  291. package/src/shared/worker-client/typings/section.model.ts +27 -0
  292. package/src/shared/worker-client/typings/status-result.model.ts +14 -0
  293. package/src/shared/worker-client/typings/version-status.model.ts +28 -0
  294. package/src/shared/worker-client/typings/worker-client-error.interface.ts +8 -0
  295. package/src/shared/worker-client/typings/worker-client-options.interface.ts +30 -0
  296. package/src/shared/worker-daemon/classes/worker-daemon.class.ts +1001 -0
  297. package/src/shared/worker-daemon/constants/daemon-defaults.constant.ts +29 -0
  298. package/src/shared/worker-daemon/functions/create-host-imports.function.ts +312 -0
  299. package/src/shared/worker-daemon/functions/create-ipc-server.function.ts +83 -0
  300. package/src/shared/worker-daemon/functions/load-wasm-modules.function.ts +98 -0
  301. package/src/shared/worker-daemon/functions/read-config.function.ts +83 -0
  302. package/src/shared/worker-daemon/functions/run-worker.function.ts +57 -0
  303. package/src/shared/worker-daemon/functions/start-daemon.function.ts +74 -0
  304. package/src/shared/worker-daemon/index.ts +16 -0
  305. package/src/shared/worker-daemon/typings/daemon-config.interface.ts +13 -0
  306. package/src/shared/worker-daemon/typings/ipc-handler.interface.ts +39 -0
  307. package/src/shared/worker-daemon/typings/wasm-modules.interface.ts +7 -0
  308. package/src/worker.ts +34 -0
package/dist/cli.mjs ADDED
@@ -0,0 +1,3537 @@
1
+ import {
2
+ computeSha256,
3
+ detectRuntime,
4
+ getArgs,
5
+ getIpcPath,
6
+ resolveBaseDir,
7
+ resolveWorkerScript
8
+ } from "./chunk-QCCN7OZH.mjs";
9
+
10
+ // src/shared/cli/constants/defaults.constant.ts
11
+ var DEFAULT_LIMIT = 20;
12
+ var DEFAULT_FORMAT = "json";
13
+ var DEFAULT_MODE = "sections";
14
+ var SUPPORTED_EXTENSIONS = [
15
+ ".md",
16
+ ".txt",
17
+ ".rst",
18
+ ".adoc"
19
+ ];
20
+
21
+ // src/shared/cli/functions/parse-args.function.ts
22
+ function parseArgs(argv) {
23
+ const options = {
24
+ command: "",
25
+ format: DEFAULT_FORMAT,
26
+ mode: DEFAULT_MODE,
27
+ limit: DEFAULT_LIMIT,
28
+ args: []
29
+ };
30
+ let i = 0;
31
+ while (i < argv.length) {
32
+ const arg = argv[i];
33
+ switch (arg) {
34
+ case "--help":
35
+ case "-h":
36
+ if (options.command) {
37
+ options.args.unshift(options.command);
38
+ options.command = "help";
39
+ } else {
40
+ options.command = "help";
41
+ }
42
+ return options;
43
+ case "--version":
44
+ case "-v":
45
+ options.command = "version";
46
+ return options;
47
+ case "--init":
48
+ console.error(
49
+ 'warning: --init is deprecated, use "kbdb db init"'
50
+ );
51
+ options.command = "init";
52
+ break;
53
+ case "--migrate":
54
+ console.error(
55
+ 'warning: --migrate is deprecated, use "kbdb db migrate"'
56
+ );
57
+ options.command = "migrate";
58
+ break;
59
+ case "--db":
60
+ options.dbPath = argv[++i];
61
+ break;
62
+ case "--format":
63
+ case "-f":
64
+ options.format = argv[++i] ?? DEFAULT_FORMAT;
65
+ break;
66
+ case "--mode":
67
+ case "-m":
68
+ options.mode = argv[++i] ?? DEFAULT_MODE;
69
+ break;
70
+ case "--limit":
71
+ case "-l":
72
+ options.limit = parseInt(argv[++i] ?? "", 10) || DEFAULT_LIMIT;
73
+ break;
74
+ case "--title":
75
+ options.title = argv[++i];
76
+ break;
77
+ case "--description":
78
+ options.description = argv[++i];
79
+ break;
80
+ case "--docid":
81
+ options.docid = argv[++i];
82
+ break;
83
+ case "--name":
84
+ options.name = argv[++i];
85
+ break;
86
+ case "--persona":
87
+ options.persona = argv[++i];
88
+ break;
89
+ case "--body":
90
+ options.body = argv[++i];
91
+ break;
92
+ case "--skills":
93
+ options.skills = (argv[++i] ?? "").split(",");
94
+ break;
95
+ case "--content":
96
+ case "-c":
97
+ options.content = true;
98
+ break;
99
+ default:
100
+ if (!options.command) {
101
+ options.command = arg;
102
+ } else if (!options.args.length && (options.command === "db" || options.command === "skill" || options.command === "agent")) {
103
+ options.command = `${options.command}-${arg}`;
104
+ } else {
105
+ options.args.push(arg);
106
+ }
107
+ }
108
+ i++;
109
+ }
110
+ return options;
111
+ }
112
+
113
+ // src/shared/cli/functions/format-output.function.ts
114
+ function formatOutput(results, format) {
115
+ switch (format) {
116
+ case "json":
117
+ return JSON.stringify(results, null, 2);
118
+ case "text":
119
+ return formatText(results);
120
+ case "mcp":
121
+ return formatMcp(results);
122
+ }
123
+ }
124
+ function formatText(results) {
125
+ if (results.length === 0) return "No results found.";
126
+ return results.map(
127
+ (r, i) => `${String(i + 1)}. [${r.kbid}] (score: ${r.score.toFixed(4)})
128
+ ${r.preview}
129
+ matches: ${r.matches.map((m) => m.term).join(", ")}`
130
+ ).join("\n\n");
131
+ }
132
+ function formatMcp(results) {
133
+ return JSON.stringify({
134
+ type: "text",
135
+ text: results.map(
136
+ (r) => `[${r.kbid}] score=${r.score.toFixed(4)} \u2014 ${r.preview}`
137
+ ).join("\n")
138
+ });
139
+ }
140
+
141
+ // src/shared/cli/functions/run-search.function.ts
142
+ async function runSearch(client, options) {
143
+ const query = options.args.join(" ").trim();
144
+ if (!query) return [];
145
+ const results = await client.search({
146
+ query,
147
+ mode: options.mode,
148
+ limit: options.limit
149
+ });
150
+ return results.map((r) => ({
151
+ kbid: r.kbid,
152
+ score: r.score,
153
+ preview: "",
154
+ matches: r.matches
155
+ }));
156
+ }
157
+
158
+ // src/shared/cli/functions/run-learn.function.ts
159
+ import { readFileSync, readdirSync, statSync } from "node:fs";
160
+ import { basename, extname, join } from "node:path";
161
+ async function runLearn(client, options, io) {
162
+ const results = [];
163
+ let stdinConsumed = false;
164
+ const readStdin = io?.readStdin ?? readProcessStdin;
165
+ for (const target of options.args) {
166
+ if (target === "-") {
167
+ if (stdinConsumed) continue;
168
+ stdinConsumed = true;
169
+ const content = await readStdin();
170
+ const result = await client.addSection({
171
+ sectionType: "text",
172
+ content,
173
+ title: options.title,
174
+ description: options.description,
175
+ docid: options.docid
176
+ });
177
+ results.push({
178
+ kbid: result.kbid,
179
+ path: "-",
180
+ size: content.length,
181
+ skipped: false
182
+ });
183
+ continue;
184
+ }
185
+ const files = collectFiles(target);
186
+ for (const file of files) {
187
+ const content = readFileSync(file, "utf-8");
188
+ const result = await client.addSection({
189
+ sectionType: "text",
190
+ content,
191
+ title: options.title,
192
+ docid: options.docid
193
+ });
194
+ results.push({
195
+ kbid: result.kbid,
196
+ path: file,
197
+ size: content.length,
198
+ skipped: false
199
+ });
200
+ }
201
+ }
202
+ return results;
203
+ }
204
+ function readProcessStdin() {
205
+ return new Promise((resolve4) => {
206
+ const chunks = [];
207
+ process.stdin.on("data", (chunk) => {
208
+ chunks.push(chunk);
209
+ });
210
+ process.stdin.on("end", () => {
211
+ resolve4(Buffer.concat(chunks).toString("utf-8"));
212
+ });
213
+ process.stdin.resume();
214
+ });
215
+ }
216
+ function collectFiles(target) {
217
+ try {
218
+ const stat = statSync(target);
219
+ if (stat.isFile()) {
220
+ return isSupportedFile(target) ? [target] : [];
221
+ }
222
+ if (stat.isDirectory()) {
223
+ return scanDirectory(target);
224
+ }
225
+ } catch {
226
+ }
227
+ return [];
228
+ }
229
+ function scanDirectory(dir) {
230
+ const files = [];
231
+ for (const entry of readdirSync(dir)) {
232
+ if (entry.startsWith(".")) continue;
233
+ const full = join(dir, entry);
234
+ try {
235
+ const stat = statSync(full);
236
+ if (stat.isDirectory()) {
237
+ files.push(...scanDirectory(full));
238
+ } else if (isSupportedFile(full)) {
239
+ files.push(full);
240
+ }
241
+ } catch {
242
+ }
243
+ }
244
+ return files;
245
+ }
246
+ function isSupportedFile(path) {
247
+ if (basename(path).startsWith(".")) return false;
248
+ const ext = extname(path).toLowerCase();
249
+ return SUPPORTED_EXTENSIONS.includes(ext);
250
+ }
251
+
252
+ // src/shared/cli/functions/run-unlearn.function.ts
253
+ async function runUnlearn(client, options) {
254
+ const results = [];
255
+ for (const kbid of options.args) {
256
+ const result = await client.removeSection(kbid);
257
+ results.push({ kbid, removed: result.removed });
258
+ }
259
+ return results;
260
+ }
261
+
262
+ // src/shared/cli/functions/run-content.function.ts
263
+ async function runContent(client, options) {
264
+ return client.content(options.args);
265
+ }
266
+
267
+ // src/shared/cli/functions/run-check.function.ts
268
+ async function runCheck(client, _options) {
269
+ return client.integrityCheck();
270
+ }
271
+
272
+ // src/shared/cli/functions/run-gc.function.ts
273
+ async function runGc(client, _options) {
274
+ return client.gc();
275
+ }
276
+
277
+ // src/shared/cli/functions/run-rebuild.function.ts
278
+ async function runRebuild(client, _options) {
279
+ return client.rebuildIndexes();
280
+ }
281
+
282
+ // src/shared/cli/functions/find-db.function.ts
283
+ import { existsSync } from "node:fs";
284
+ import { join as join2, resolve } from "node:path";
285
+ function findDb(dbPath) {
286
+ const base = dbPath ? resolve(dbPath) : process.cwd();
287
+ const kbdbDir = join2(base, ".kbdb");
288
+ return existsSync(kbdbDir) ? kbdbDir : null;
289
+ }
290
+
291
+ // src/shared/cli/functions/run-init.function.ts
292
+ import { existsSync as existsSync2, mkdirSync, writeFileSync } from "node:fs";
293
+ import { join as join3, resolve as resolve2 } from "node:path";
294
+ var DB_FORMAT_VERSION = 1;
295
+ var CATALOG_TOML = `version = ${DB_FORMAT_VERSION.toString()}
296
+ section_count = 0
297
+ document_count = 0
298
+ created_at = 0
299
+ updated_at = 0
300
+ checksum = ""
301
+ `;
302
+ var WORKER_TOML = "# kbdb worker configuration\n";
303
+ var GITIGNORE = [
304
+ "# kbdb binary indexes (auto-generated)",
305
+ "corpus.bin",
306
+ "inverted.idx",
307
+ "positional.idx",
308
+ ""
309
+ ].join("\n");
310
+ function createScaffold(dbDir) {
311
+ mkdirSync(dbDir, { recursive: true });
312
+ mkdirSync(join3(dbDir, "sections"));
313
+ mkdirSync(join3(dbDir, "documents"));
314
+ writeFileSync(join3(dbDir, "catalog.toml"), CATALOG_TOML);
315
+ writeFileSync(join3(dbDir, "corpus.bin"), "");
316
+ writeFileSync(join3(dbDir, "inverted.idx"), "");
317
+ writeFileSync(join3(dbDir, "positional.idx"), "");
318
+ writeFileSync(join3(dbDir, "worker.toml"), WORKER_TOML);
319
+ writeFileSync(join3(dbDir, ".gitignore"), GITIGNORE);
320
+ }
321
+ function runInit(options) {
322
+ const basePath = options.dbPath ? resolve2(options.dbPath) : process.cwd();
323
+ const dbDir = join3(basePath, ".kbdb");
324
+ try {
325
+ if (existsSync2(dbDir)) {
326
+ return {
327
+ ok: false,
328
+ targetPath: dbDir,
329
+ errorMessage: `database directory already exists: ${dbDir}`
330
+ };
331
+ }
332
+ createScaffold(dbDir);
333
+ return { ok: true, targetPath: dbDir };
334
+ } catch (err) {
335
+ const errorMessage = err instanceof Error ? err.message : String(err);
336
+ return { ok: false, targetPath: dbDir, errorMessage };
337
+ }
338
+ }
339
+
340
+ // src/shared/cli/functions/error-to-message.function.ts
341
+ function errorToMessage(err) {
342
+ return err instanceof Error ? err.message : String(err);
343
+ }
344
+
345
+ // src/shared/cli/functions/is-stdin-tty.function.ts
346
+ function isStdinTty(stdin = process.stdin) {
347
+ return stdin.isTTY ?? false;
348
+ }
349
+
350
+ // src/shared/cli/functions/prompt-user.function.ts
351
+ import { createInterface } from "node:readline";
352
+ async function promptUser(question, io) {
353
+ const ask = io?.ask ?? askReadline;
354
+ const answer = await ask(question);
355
+ return answer.trim();
356
+ }
357
+ function askReadline(question) {
358
+ return new Promise((resolve4) => {
359
+ const rl = createInterface({
360
+ input: process.stdin,
361
+ output: process.stdout
362
+ });
363
+ rl.question(question, (answer) => {
364
+ rl.close();
365
+ resolve4(answer);
366
+ });
367
+ });
368
+ }
369
+
370
+ // src/shared/cli/functions/run-status.function.ts
371
+ async function runStatus(client, _options) {
372
+ return client.dbStatus();
373
+ }
374
+
375
+ // src/shared/cli/functions/run-db-init.function.ts
376
+ function runDbInit(options, runInitFn) {
377
+ const result = runInitFn(options);
378
+ if (result.ok) {
379
+ return {
380
+ output: JSON.stringify(
381
+ { path: result.targetPath, created: true },
382
+ null,
383
+ 2
384
+ ),
385
+ exitCode: 0
386
+ };
387
+ }
388
+ return {
389
+ error: result.errorMessage ?? "init failed",
390
+ exitCode: 1
391
+ };
392
+ }
393
+
394
+ // src/shared/cli/functions/run-db-migrate.function.ts
395
+ async function runDbMigrate(client, options) {
396
+ const dbPath = options.dbPath ?? process.cwd();
397
+ return client.migrateDatabase(dbPath);
398
+ }
399
+
400
+ // src/shared/mcp/functions/extract-skill-arguments.function.ts
401
+ function extractSkillArguments(body) {
402
+ const seen = /* @__PURE__ */ new Set();
403
+ const args = [];
404
+ const re = /\{\{(\w+)\}\}/g;
405
+ let match;
406
+ while ((match = re.exec(body)) !== null) {
407
+ const name = match[1];
408
+ if (!seen.has(name)) {
409
+ seen.add(name);
410
+ args.push({ name, required: true });
411
+ }
412
+ }
413
+ return args;
414
+ }
415
+
416
+ // src/shared/mcp/functions/serialize-skill-content.function.ts
417
+ function serializeSkillContent(skill) {
418
+ return JSON.stringify(skill);
419
+ }
420
+
421
+ // src/shared/cli/functions/run-skill-learn.function.ts
422
+ async function runSkillLearn(client, options) {
423
+ const name = options.name;
424
+ if (!name) {
425
+ return { error: "--name is required", exitCode: 1 };
426
+ }
427
+ const body = options.body;
428
+ if (!body) {
429
+ return { error: "--body is required", exitCode: 1 };
430
+ }
431
+ const args = extractSkillArguments(body);
432
+ const skill = {
433
+ name,
434
+ description: options.description,
435
+ arguments: args.length > 0 ? args : void 0,
436
+ body
437
+ };
438
+ const json = serializeSkillContent(skill);
439
+ const result = await client.addSection({
440
+ sectionType: "skill",
441
+ content: json,
442
+ title: name,
443
+ description: options.description
444
+ });
445
+ return {
446
+ output: JSON.stringify(result, null, 2),
447
+ exitCode: 0
448
+ };
449
+ }
450
+
451
+ // src/shared/cli/functions/run-skill-list.function.ts
452
+ async function runSkillList(client, _options) {
453
+ const records = await client.listByType("skill");
454
+ const items = records.map((r) => {
455
+ let argumentCount = 0;
456
+ try {
457
+ const parsed = JSON.parse(r.content);
458
+ if (Array.isArray(parsed["arguments"])) {
459
+ argumentCount = parsed["arguments"].length;
460
+ }
461
+ } catch {
462
+ }
463
+ return {
464
+ kbid: r.kbid,
465
+ name: r.title,
466
+ description: r.description,
467
+ argumentCount
468
+ };
469
+ });
470
+ return {
471
+ output: JSON.stringify(items, null, 2),
472
+ exitCode: 0
473
+ };
474
+ }
475
+
476
+ // src/shared/mcp/functions/parse-skill-content.function.ts
477
+ function parseSkillContent(json) {
478
+ const raw = JSON.parse(json);
479
+ if (typeof raw["name"] !== "string" || !raw["name"]) {
480
+ throw new Error("skill name is required");
481
+ }
482
+ if (typeof raw["body"] !== "string") {
483
+ throw new Error("skill body is required");
484
+ }
485
+ return {
486
+ name: raw["name"],
487
+ description: typeof raw["description"] === "string" ? raw["description"] : void 0,
488
+ arguments: Array.isArray(raw["arguments"]) ? raw["arguments"] : void 0,
489
+ body: raw["body"]
490
+ };
491
+ }
492
+
493
+ // src/shared/cli/functions/run-skill-get.function.ts
494
+ async function runSkillGet(client, options) {
495
+ const identifier = options.args[0] ?? options.name;
496
+ if (!identifier) {
497
+ return {
498
+ error: "skill name or kbid required",
499
+ exitCode: 1
500
+ };
501
+ }
502
+ let content;
503
+ if (/^[0-9a-f]{16,}$/i.test(identifier)) {
504
+ const sections = await client.readSections([identifier]);
505
+ if (sections.length > 0) {
506
+ content = sections[0]?.content;
507
+ }
508
+ }
509
+ if (content === void 0) {
510
+ const records = await client.listByType("skill");
511
+ const match = records.filter((r) => r.title === identifier).pop();
512
+ if (match) {
513
+ content = match.content;
514
+ }
515
+ }
516
+ if (content === void 0) {
517
+ return {
518
+ error: `skill not found: ${identifier}`,
519
+ exitCode: 1
520
+ };
521
+ }
522
+ const skill = parseSkillContent(content);
523
+ return {
524
+ output: JSON.stringify(skill, null, 2),
525
+ exitCode: 0
526
+ };
527
+ }
528
+
529
+ // src/shared/cli/functions/run-skill-delete.function.ts
530
+ async function runSkillDelete(client, options) {
531
+ const kbid = options.args[0];
532
+ if (!kbid) {
533
+ return { error: "kbid is required", exitCode: 1 };
534
+ }
535
+ const result = await client.removeSection(kbid);
536
+ return {
537
+ output: JSON.stringify(
538
+ { kbid, removed: result.removed },
539
+ null,
540
+ 2
541
+ ),
542
+ exitCode: 0
543
+ };
544
+ }
545
+
546
+ // src/shared/cli/functions/run-agent-create.function.ts
547
+ async function runAgentCreate(client, options) {
548
+ const name = options.name;
549
+ if (!name) {
550
+ return { error: "--name is required", exitCode: 1 };
551
+ }
552
+ const persona = options.persona;
553
+ if (!persona) {
554
+ return { error: "--persona is required", exitCode: 1 };
555
+ }
556
+ const skills = options.skills ?? [];
557
+ if (skills.length > 0) {
558
+ const sections = await client.readSections(skills);
559
+ const found = new Set(sections.map((s) => s.kbid));
560
+ const missing = skills.filter((k) => !found.has(k));
561
+ if (missing.length > 0) {
562
+ return {
563
+ error: `skill not found: ${missing.join(", ")}`,
564
+ exitCode: 1
565
+ };
566
+ }
567
+ }
568
+ const metadata = JSON.stringify({
569
+ name,
570
+ description: options.description ?? "",
571
+ persona
572
+ });
573
+ const metaResult = await client.addSection({
574
+ sectionType: "text",
575
+ content: metadata,
576
+ title: name,
577
+ description: options.description
578
+ });
579
+ const allKbids = [metaResult.kbid, ...skills];
580
+ const docid = await client.groupSections(name, allKbids, "agent");
581
+ return {
582
+ output: JSON.stringify(
583
+ { docid, name, skillCount: skills.length },
584
+ null,
585
+ 2
586
+ ),
587
+ exitCode: 0
588
+ };
589
+ }
590
+
591
+ // src/shared/cli/functions/run-agent-list.function.ts
592
+ async function runAgentList(client, _options) {
593
+ const docs = await client.listDocumentsByType("agent");
594
+ const items = docs.map((d) => ({
595
+ docid: d.docid,
596
+ name: d.title,
597
+ skillCount: Math.max(0, d.sections.length - 1)
598
+ }));
599
+ return {
600
+ output: JSON.stringify(items, null, 2),
601
+ exitCode: 0
602
+ };
603
+ }
604
+
605
+ // src/shared/cli/functions/run-agent-get.function.ts
606
+ async function readAgentMeta(client, metaKbid, fallbackName) {
607
+ const sections = await client.readSections([metaKbid]);
608
+ const first = sections.at(0);
609
+ if (!first) {
610
+ return { name: fallbackName, description: "", persona: "" };
611
+ }
612
+ try {
613
+ const meta = JSON.parse(first.content);
614
+ return {
615
+ name: typeof meta["name"] === "string" ? meta["name"] : fallbackName,
616
+ description: typeof meta["description"] === "string" ? meta["description"] : "",
617
+ persona: typeof meta["persona"] === "string" ? meta["persona"] : ""
618
+ };
619
+ } catch {
620
+ return { name: fallbackName, description: "", persona: "" };
621
+ }
622
+ }
623
+ async function resolveSkills(client, skillRefs) {
624
+ if (skillRefs.length === 0) {
625
+ return [];
626
+ }
627
+ const kbids = skillRefs.map((r) => r.kbid);
628
+ const sections = await client.readSections(kbids);
629
+ const sectionMap = new Map(sections.map((s) => [s.kbid, s]));
630
+ return skillRefs.map((ref) => {
631
+ const sec = sectionMap.get(ref.kbid);
632
+ if (!sec) {
633
+ return { kbid: ref.kbid, name: null, position: ref.position };
634
+ }
635
+ try {
636
+ const parsed = JSON.parse(sec.content);
637
+ const skillName = typeof parsed["name"] === "string" ? parsed["name"] : null;
638
+ return {
639
+ kbid: ref.kbid,
640
+ name: skillName,
641
+ position: ref.position
642
+ };
643
+ } catch {
644
+ return { kbid: ref.kbid, name: null, position: ref.position };
645
+ }
646
+ });
647
+ }
648
+ async function runAgentGet(client, options) {
649
+ const docid = options.args[0];
650
+ if (!docid) {
651
+ return { error: "docid is required", exitCode: 1 };
652
+ }
653
+ const doc = await client.retrieveDocument(docid);
654
+ const metaKbid = doc.sections[0]?.kbid;
655
+ const skillRefs = doc.sections.slice(1);
656
+ const { name, description, persona } = metaKbid ? await readAgentMeta(client, metaKbid, doc.title) : { name: doc.title, description: "", persona: "" };
657
+ const skills = await resolveSkills(client, skillRefs);
658
+ return {
659
+ output: JSON.stringify(
660
+ { docid, name, description, persona, skills },
661
+ null,
662
+ 2
663
+ ),
664
+ exitCode: 0
665
+ };
666
+ }
667
+
668
+ // src/shared/cli/functions/run-agent-delete.function.ts
669
+ async function runAgentDelete(client, options) {
670
+ const docid = options.args[0];
671
+ if (!docid) {
672
+ return { error: "docid is required", exitCode: 1 };
673
+ }
674
+ await client.removeGrouping(docid);
675
+ return {
676
+ output: JSON.stringify({ docid, removed: true }, null, 2),
677
+ exitCode: 0
678
+ };
679
+ }
680
+
681
+ // src/shared/cli/functions/dispatch-command.function.ts
682
+ async function dispatchCommand(client, options, io) {
683
+ switch (options.command) {
684
+ case "learn":
685
+ return handleLearn(client, options, io);
686
+ case "unlearn":
687
+ return handleUnlearn(client, options);
688
+ case "search":
689
+ return handleSearch(client, options);
690
+ case "content":
691
+ return handleContent(client, options);
692
+ case "check":
693
+ return handleCheck(client, options);
694
+ case "gc":
695
+ return handleGc(client, options);
696
+ case "rebuild":
697
+ return handleRebuild(client, options);
698
+ case "status":
699
+ return handleStatus(client, options);
700
+ case "db-init":
701
+ return handleDbInit(options);
702
+ case "db-migrate":
703
+ return handleDbMigrate(client, options);
704
+ case "skill-learn": {
705
+ const result = await runSkillLearn(client, options);
706
+ return result;
707
+ }
708
+ case "skill-list": {
709
+ const result = await runSkillList(client, options);
710
+ return result;
711
+ }
712
+ case "skill-get": {
713
+ const result = await runSkillGet(client, options);
714
+ return result;
715
+ }
716
+ case "skill-delete": {
717
+ const result = await runSkillDelete(client, options);
718
+ return result;
719
+ }
720
+ case "agent-create": {
721
+ const result = await runAgentCreate(client, options);
722
+ return result;
723
+ }
724
+ case "agent-list": {
725
+ const result = await runAgentList(client, options);
726
+ return result;
727
+ }
728
+ case "agent-get": {
729
+ const result = await runAgentGet(client, options);
730
+ return result;
731
+ }
732
+ case "agent-delete": {
733
+ const result = await runAgentDelete(client, options);
734
+ return result;
735
+ }
736
+ default:
737
+ return {
738
+ error: `unknown command: ${options.command}`,
739
+ exitCode: 1
740
+ };
741
+ }
742
+ }
743
+ async function handleLearn(client, options, io) {
744
+ try {
745
+ const results = await runLearn(client, options, io);
746
+ return {
747
+ output: JSON.stringify(results, null, 2),
748
+ exitCode: 0
749
+ };
750
+ } catch (err) {
751
+ return {
752
+ error: `learn failed: ${errorToMessage(err)}`,
753
+ exitCode: 1
754
+ };
755
+ }
756
+ }
757
+ async function handleUnlearn(client, options) {
758
+ try {
759
+ const results = await runUnlearn(client, options);
760
+ return {
761
+ output: JSON.stringify(results, null, 2),
762
+ exitCode: 0
763
+ };
764
+ } catch (err) {
765
+ return {
766
+ error: `unlearn failed: ${errorToMessage(err)}`,
767
+ exitCode: 1
768
+ };
769
+ }
770
+ }
771
+ async function handleSearch(client, options) {
772
+ try {
773
+ const results = await runSearch(client, options);
774
+ if (options.content) {
775
+ await hydrateSearchPreviews(client, results);
776
+ }
777
+ return {
778
+ output: formatOutput(results, options.format),
779
+ exitCode: 0
780
+ };
781
+ } catch (err) {
782
+ return {
783
+ error: `search failed: ${errorToMessage(err)}`,
784
+ exitCode: 1
785
+ };
786
+ }
787
+ }
788
+ async function handleContent(client, options) {
789
+ try {
790
+ const result = await runContent(client, options);
791
+ return {
792
+ output: JSON.stringify(result, null, 2),
793
+ exitCode: 0
794
+ };
795
+ } catch (err) {
796
+ return {
797
+ error: `content failed: ${errorToMessage(err)}`,
798
+ exitCode: 1
799
+ };
800
+ }
801
+ }
802
+ async function handleCheck(client, options) {
803
+ try {
804
+ const result = await runCheck(client, options);
805
+ return {
806
+ output: JSON.stringify(result, null, 2),
807
+ exitCode: result.ok ? 0 : 1
808
+ };
809
+ } catch (err) {
810
+ return {
811
+ error: `check failed: ${errorToMessage(err)}`,
812
+ exitCode: 1
813
+ };
814
+ }
815
+ }
816
+ async function handleGc(client, options) {
817
+ try {
818
+ const result = await runGc(client, options);
819
+ return {
820
+ output: JSON.stringify(result, null, 2),
821
+ exitCode: 0
822
+ };
823
+ } catch (err) {
824
+ return {
825
+ error: `gc failed: ${errorToMessage(err)}`,
826
+ exitCode: 1
827
+ };
828
+ }
829
+ }
830
+ async function handleRebuild(client, options) {
831
+ try {
832
+ const result = await runRebuild(client, options);
833
+ return {
834
+ output: JSON.stringify(result, null, 2),
835
+ exitCode: 0
836
+ };
837
+ } catch (err) {
838
+ return {
839
+ error: `rebuild failed: ${errorToMessage(err)}`,
840
+ exitCode: 1
841
+ };
842
+ }
843
+ }
844
+ async function handleStatus(client, options) {
845
+ try {
846
+ const result = await runStatus(client, options);
847
+ return {
848
+ output: JSON.stringify(result, null, 2),
849
+ exitCode: 0
850
+ };
851
+ } catch (err) {
852
+ return {
853
+ error: `status failed: ${errorToMessage(err)}`,
854
+ exitCode: 1
855
+ };
856
+ }
857
+ }
858
+ function handleDbInit(options) {
859
+ return runDbInit(options, runInit);
860
+ }
861
+ async function handleDbMigrate(client, options) {
862
+ try {
863
+ const result = await runDbMigrate(client, options);
864
+ return {
865
+ output: JSON.stringify(result, null, 2),
866
+ exitCode: 0
867
+ };
868
+ } catch (err) {
869
+ return {
870
+ error: `db-migrate failed: ${errorToMessage(err)}`,
871
+ exitCode: 1
872
+ };
873
+ }
874
+ }
875
+ async function hydrateSearchPreviews(client, results) {
876
+ await Promise.all(
877
+ results.map(async (result) => {
878
+ try {
879
+ const contentResult = await client.content([result.kbid]);
880
+ result.preview = contentResult.data;
881
+ } catch {
882
+ }
883
+ })
884
+ );
885
+ }
886
+
887
+ // src/shared/version/constants/version.constant.ts
888
+ var VERSION = "0.1.0";
889
+
890
+ // src/shared/cli/functions/generate-help.function.ts
891
+ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
892
+ "learn",
893
+ "unlearn",
894
+ "search",
895
+ "content",
896
+ "check",
897
+ "gc",
898
+ "rebuild",
899
+ "status",
900
+ "mcp",
901
+ "db",
902
+ "skill",
903
+ "agent"
904
+ ]);
905
+ var GROUP_SUBCOMMANDS = {
906
+ db: [
907
+ ["init", "Initialise a new .kbdb directory"],
908
+ ["migrate", "Migrate database to current format"]
909
+ ],
910
+ skill: [
911
+ ["learn", "Create a new skill definition"],
912
+ ["list", "List all skills"],
913
+ ["get", "Retrieve a skill by name or kbid"],
914
+ ["delete", "Remove a skill"]
915
+ ],
916
+ agent: [
917
+ ["create", "Create an agent with skill refs"],
918
+ ["list", "List all agents"],
919
+ ["get", "Retrieve an agent by docid"],
920
+ ["delete", "Remove an agent"]
921
+ ]
922
+ };
923
+ function isKnownCommand(cmd) {
924
+ if (KNOWN_COMMANDS.has(cmd)) {
925
+ return true;
926
+ }
927
+ const dashIdx = cmd.indexOf("-");
928
+ if (dashIdx < 0) {
929
+ return false;
930
+ }
931
+ const group = cmd.slice(0, dashIdx);
932
+ return group in GROUP_SUBCOMMANDS;
933
+ }
934
+ function generateHelp(command, subcommand) {
935
+ if (!command) {
936
+ return generateGlobalHelp();
937
+ }
938
+ if (!subcommand && command.includes("-")) {
939
+ const dashIdx = command.indexOf("-");
940
+ const group = command.slice(0, dashIdx);
941
+ const sub = command.slice(dashIdx + 1);
942
+ if (group in GROUP_SUBCOMMANDS) {
943
+ return generateSubcommandHelp(group, sub);
944
+ }
945
+ }
946
+ if (subcommand) {
947
+ return generateSubcommandHelp(command, subcommand);
948
+ }
949
+ return generateCommandHelp(command);
950
+ }
951
+ function generateGlobalHelp() {
952
+ return `kbdb v${VERSION} - File-based knowledge base database for AI agents
953
+
954
+ Usage: kbdb [options]
955
+ kbdb <command> [options] ...[parameters]
956
+ kbdb <command> <subcommand> [options] ...[params]
957
+
958
+ Knowledge Base:
959
+ learn Import content from files/stdin
960
+ unlearn Remove sections by kbid
961
+ search Query the knowledge base
962
+ content Compose rendered content from ids
963
+
964
+ Database:
965
+ db init Initialise a new .kbdb directory
966
+ db migrate Migrate database to current format
967
+
968
+ Maintenance:
969
+ check Verify knowledge base integrity
970
+ gc Garbage collect unreferenced
971
+ sections
972
+ rebuild Reconstruct all index files
973
+ status Show database status
974
+
975
+ Skills:
976
+ skill learn Create a new skill definition
977
+ skill list List all skills
978
+ skill get Retrieve a skill by name or kbid
979
+ skill delete Remove a skill
980
+
981
+ Agents:
982
+ agent create Create an agent with skill refs
983
+ agent list List all agents
984
+ agent get Retrieve an agent by docid
985
+ agent delete Remove an agent
986
+
987
+ Server:
988
+ mcp Start MCP server mode (stdio)
989
+
990
+ Global Options:
991
+ -h, --help Show this help message
992
+ -v, --version Show version information
993
+ --db <path> Path to .kbdb directory
994
+ --format <fmt> Output format (json|text|mcp)
995
+
996
+ Run "kbdb <command> --help" for detailed information.
997
+ `;
998
+ }
999
+ function generateCommandHelp(command) {
1000
+ if (command in GROUP_SUBCOMMANDS) {
1001
+ return generateGroupHelp(command);
1002
+ }
1003
+ const leaf = LEAF_HELP[command];
1004
+ if (leaf) {
1005
+ return leaf;
1006
+ }
1007
+ return `Unknown command: ${command}
1008
+
1009
+ ` + generateGlobalHelp();
1010
+ }
1011
+ function generateGroupHelp(group) {
1012
+ const subs = GROUP_SUBCOMMANDS[group] ?? [];
1013
+ const subLines = subs.map(([name, desc2]) => ` ${name.padEnd(20)}${desc2}`).join("\n");
1014
+ const desc = GROUP_DESCRIPTIONS[group] ?? group;
1015
+ return `kbdb ${group} - ${desc}
1016
+
1017
+ Usage: kbdb ${group} <subcommand> [options]
1018
+
1019
+ Subcommands:
1020
+ ${subLines}
1021
+
1022
+ Global Options:
1023
+ --db <path> Path to .kbdb directory
1024
+ -h, --help Show this help message
1025
+
1026
+ Run "kbdb ${group} <subcommand> --help" for details.
1027
+ `;
1028
+ }
1029
+ var GROUP_DESCRIPTIONS = {
1030
+ db: "Database management",
1031
+ skill: "Skill management",
1032
+ agent: "Agent management"
1033
+ };
1034
+ var LEAF_HELP = {
1035
+ learn: `kbdb learn - Import content from files or stdin
1036
+
1037
+ Usage: kbdb learn [options] <path | ->...
1038
+
1039
+ Arguments:
1040
+ <path | -> File path, directory, or - for stdin
1041
+
1042
+ Options:
1043
+ --title <title> Section title
1044
+ --description <d> Section description
1045
+ --docid <docid> Document ID to group under
1046
+ --db <path> Path to .kbdb directory
1047
+
1048
+ Output:
1049
+ JSON array of { kbid, path, size, skipped }
1050
+
1051
+ Examples:
1052
+ kbdb learn README.md
1053
+ kbdb learn ./docs/
1054
+ cat notes.txt | kbdb learn -
1055
+ `,
1056
+ unlearn: `kbdb unlearn - Remove sections by kbid
1057
+
1058
+ Usage: kbdb unlearn [options] <kbid>...
1059
+
1060
+ Arguments:
1061
+ <kbid> 26-character knowledge base identifier
1062
+
1063
+ Options:
1064
+ --db <path> Path to .kbdb directory
1065
+
1066
+ Output:
1067
+ JSON array of { kbid, removed }
1068
+
1069
+ Examples:
1070
+ kbdb unlearn abcdef1234567890abcdef1234
1071
+ kbdb unlearn id1 id2 id3
1072
+ `,
1073
+ search: `kbdb search - Query the knowledge base
1074
+
1075
+ Usage: kbdb search [options] <query>...
1076
+
1077
+ Arguments:
1078
+ <query> One or more query terms
1079
+
1080
+ Options:
1081
+ --mode <mode> Result granularity (sections|documents|stats)
1082
+ --limit <n> Max results (default: 20)
1083
+ --format <fmt> Output format (json|text|mcp)
1084
+ --content, -c Hydrate results with section content
1085
+ --db <path> Path to .kbdb directory
1086
+
1087
+ Output:
1088
+ JSON array of { kbid, score, preview, matches }
1089
+
1090
+ Examples:
1091
+ kbdb search "machine learning"
1092
+ kbdb search --limit 5 --format text query
1093
+ kbdb search --mode documents --content term
1094
+ `,
1095
+ content: `kbdb content - Compose rendered content from ids
1096
+
1097
+ Usage: kbdb content [options] <id>...
1098
+
1099
+ Arguments:
1100
+ <id> kbid or docid identifier
1101
+
1102
+ Options:
1103
+ --db <path> Path to .kbdb directory
1104
+
1105
+ Output:
1106
+ JSON { type, data, total }
1107
+
1108
+ Examples:
1109
+ kbdb content abcdef1234567890abcdef1234
1110
+ kbdb content id1 id2
1111
+ `,
1112
+ check: `kbdb check - Verify knowledge base integrity
1113
+
1114
+ Usage: kbdb check [options]
1115
+
1116
+ Options:
1117
+ --db <path> Path to .kbdb directory
1118
+
1119
+ Output:
1120
+ JSON { ok, errors }
1121
+
1122
+ Examples:
1123
+ kbdb check
1124
+ kbdb check --db /path/to/project
1125
+ `,
1126
+ gc: `kbdb gc - Garbage collect unreferenced sections
1127
+
1128
+ Usage: kbdb gc [options]
1129
+
1130
+ Options:
1131
+ --db <path> Path to .kbdb directory
1132
+
1133
+ Output:
1134
+ JSON { removed_sections, removed_bytes }
1135
+
1136
+ Examples:
1137
+ kbdb gc
1138
+ kbdb gc --db /path/to/project
1139
+ `,
1140
+ rebuild: `kbdb rebuild - Reconstruct all index files
1141
+
1142
+ Usage: kbdb rebuild [options]
1143
+
1144
+ Options:
1145
+ --db <path> Path to .kbdb directory
1146
+
1147
+ Output:
1148
+ JSON { sections_reindexed, terms_indexed }
1149
+
1150
+ Examples:
1151
+ kbdb rebuild
1152
+ kbdb rebuild --db /path/to/project
1153
+ `,
1154
+ status: `kbdb status - Show database status
1155
+
1156
+ Usage: kbdb status [options]
1157
+
1158
+ Options:
1159
+ --db <path> Path to .kbdb directory
1160
+
1161
+ Output:
1162
+ JSON database status object
1163
+
1164
+ Examples:
1165
+ kbdb status
1166
+ kbdb status --db /path/to/project
1167
+ `,
1168
+ mcp: `kbdb mcp - Start MCP server mode (stdio)
1169
+
1170
+ Usage: kbdb mcp [options]
1171
+
1172
+ Options:
1173
+ --db <path> Path to .kbdb directory
1174
+
1175
+ Environment:
1176
+ KBDB_DIR Fallback database path
1177
+
1178
+ Examples:
1179
+ kbdb mcp --db /path/to/project
1180
+ KBDB_DIR=/path/to/project kbdb mcp
1181
+ `
1182
+ };
1183
+ var SUBCOMMAND_HELP = {
1184
+ "db-init": `kbdb db init - Initialise a new .kbdb directory
1185
+
1186
+ Usage: kbdb db init [options]
1187
+
1188
+ Options:
1189
+ --db <path> Path to create .kbdb in
1190
+ (default: current directory)
1191
+ -h, --help Show this help message
1192
+
1193
+ Output:
1194
+ JSON { path, created }
1195
+
1196
+ Examples:
1197
+ kbdb db init
1198
+ kbdb db init --db /path/to/project
1199
+ `,
1200
+ "db-migrate": `kbdb db migrate - Migrate database to current format
1201
+
1202
+ Usage: kbdb db migrate [options]
1203
+
1204
+ Options:
1205
+ --db <path> Path containing .kbdb
1206
+ (default: current directory)
1207
+ -h, --help Show this help message
1208
+
1209
+ Output:
1210
+ JSON MigrateResult or "already up to date"
1211
+
1212
+ Examples:
1213
+ kbdb db migrate
1214
+ kbdb db migrate --db /path/to/project
1215
+ `,
1216
+ "skill-learn": `kbdb skill learn - Create a new skill definition
1217
+
1218
+ Usage: kbdb skill learn [options] --name <n> --body <file|->
1219
+
1220
+ Options:
1221
+ --name <name> Skill name (required)
1222
+ --description <d> Skill description
1223
+ --body <file|-> Template body file or stdin (required)
1224
+ --db <path> Path to .kbdb directory
1225
+
1226
+ Output:
1227
+ JSON { kbid, name, arguments }
1228
+
1229
+ Examples:
1230
+ kbdb skill learn --name summarize --body prompt.txt
1231
+ cat body.txt | kbdb skill learn --name my-skill --body -
1232
+ `,
1233
+ "skill-list": `kbdb skill list - List all skills
1234
+
1235
+ Usage: kbdb skill list [options]
1236
+
1237
+ Options:
1238
+ --db <path> Path to .kbdb directory
1239
+
1240
+ Output:
1241
+ JSON array of { kbid, name, description, argumentCount }
1242
+
1243
+ Examples:
1244
+ kbdb skill list
1245
+ kbdb skill list --db /path/to/project
1246
+ `,
1247
+ "skill-get": `kbdb skill get - Retrieve a skill by name or kbid
1248
+
1249
+ Usage: kbdb skill get [options] <name-or-kbid>
1250
+
1251
+ Arguments:
1252
+ <name-or-kbid> Skill name or 26-char kbid
1253
+
1254
+ Options:
1255
+ --db <path> Path to .kbdb directory
1256
+
1257
+ Output:
1258
+ JSON SkillDefinition object
1259
+
1260
+ Examples:
1261
+ kbdb skill get summarize-document
1262
+ kbdb skill get abcdef1234567890abcdef1234
1263
+ `,
1264
+ "skill-delete": `kbdb skill delete - Remove a skill
1265
+
1266
+ Usage: kbdb skill delete [options] <kbid>
1267
+
1268
+ Arguments:
1269
+ <kbid> 26-character kbid of the skill to remove
1270
+
1271
+ Options:
1272
+ --db <path> Path to .kbdb directory
1273
+
1274
+ Output:
1275
+ JSON { kbid, removed }
1276
+
1277
+ Examples:
1278
+ kbdb skill delete abcdef1234567890abcdef1234
1279
+ `,
1280
+ "agent-create": `kbdb agent create - Create an agent with skill refs
1281
+
1282
+ Usage: kbdb agent create [options] --name <n> --persona <file|-> --skills <kbid,...>
1283
+
1284
+ Options:
1285
+ --name <name> Agent name (required)
1286
+ --description <d> Agent description
1287
+ --persona <file|-> Persona file or stdin (required)
1288
+ --skills <kbid,...> Comma-separated skill kbids (required)
1289
+ --db <path> Path to .kbdb directory
1290
+
1291
+ Output:
1292
+ JSON { docid, name, skills }
1293
+
1294
+ Examples:
1295
+ kbdb agent create --name code-reviewer --persona ./p.txt --skills abc123
1296
+ cat persona.txt | kbdb agent create --name my-agent --persona - --skills abc123
1297
+ `,
1298
+ "agent-list": `kbdb agent list - List all agents
1299
+
1300
+ Usage: kbdb agent list [options]
1301
+
1302
+ Options:
1303
+ --db <path> Path to .kbdb directory
1304
+
1305
+ Output:
1306
+ JSON array of { docid, name, description, skillCount }
1307
+
1308
+ Examples:
1309
+ kbdb agent list
1310
+ kbdb agent list --db /path/to/project
1311
+ `,
1312
+ "agent-get": `kbdb agent get - Retrieve an agent by docid
1313
+
1314
+ Usage: kbdb agent get [options] <docid>
1315
+
1316
+ Arguments:
1317
+ <docid> Agent document identifier
1318
+
1319
+ Options:
1320
+ --db <path> Path to .kbdb directory
1321
+
1322
+ Output:
1323
+ JSON AgentDefinition object with resolved skills
1324
+
1325
+ Examples:
1326
+ kbdb agent get agent-code-reviewer
1327
+ `,
1328
+ "agent-delete": `kbdb agent delete - Remove an agent
1329
+
1330
+ Usage: kbdb agent delete [options] <docid>
1331
+
1332
+ Arguments:
1333
+ <docid> Agent document identifier
1334
+
1335
+ Options:
1336
+ --db <path> Path to .kbdb directory
1337
+
1338
+ Output:
1339
+ JSON { docid, removed }
1340
+
1341
+ Examples:
1342
+ kbdb agent delete agent-code-reviewer
1343
+ `
1344
+ };
1345
+ function generateSubcommandHelp(command, subcommand) {
1346
+ const key = `${command}-${subcommand}`;
1347
+ const text = SUBCOMMAND_HELP[key];
1348
+ if (text) {
1349
+ return text;
1350
+ }
1351
+ return generateCommandHelp(command);
1352
+ }
1353
+
1354
+ // src/shared/cli/functions/run-cli.function.ts
1355
+ async function runCli(argv, deps2) {
1356
+ const options = parseArgs(argv);
1357
+ if (options.command === "help" || !options.command) {
1358
+ const helpCommand = options.args[0];
1359
+ const helpSubcommand = options.args[1];
1360
+ const helpText = generateHelp(helpCommand, helpSubcommand);
1361
+ if (helpCommand && !isKnownCommand(helpCommand)) {
1362
+ return { output: helpText, exitCode: 1 };
1363
+ }
1364
+ return { output: helpText, exitCode: 0 };
1365
+ }
1366
+ if (options.command === "version") {
1367
+ return { output: VERSION, exitCode: 0 };
1368
+ }
1369
+ if (options.command === "init" || options.command === "db-init") {
1370
+ return handleInit(options, deps2);
1371
+ }
1372
+ if (options.command === "mcp") {
1373
+ return handleMcp(options, deps2);
1374
+ }
1375
+ if (options.command === "migrate" || options.command === "db-migrate") {
1376
+ return handleMigrate(options, deps2);
1377
+ }
1378
+ return handleDataCommand(options, deps2);
1379
+ }
1380
+ function handleInit(options, deps2) {
1381
+ const result = deps2.runInit(options);
1382
+ if (result.ok) {
1383
+ return {
1384
+ output: result.targetPath,
1385
+ exitCode: 0
1386
+ };
1387
+ }
1388
+ return {
1389
+ error: `error: ${result.errorMessage ?? "init failed"}`,
1390
+ exitCode: 1
1391
+ };
1392
+ }
1393
+ async function handleMcp(options, deps2) {
1394
+ const rawDbPath = options.dbPath ?? process.env["KBDB_DIR"];
1395
+ if (!rawDbPath) {
1396
+ return {
1397
+ error: "error: --db or KBDB_DIR required in MCP mode",
1398
+ exitCode: 1
1399
+ };
1400
+ }
1401
+ const dbDir = deps2.findDb(rawDbPath);
1402
+ if (!dbDir) {
1403
+ return {
1404
+ error: `error: no .kbdb database found at ${rawDbPath}`,
1405
+ exitCode: 1
1406
+ };
1407
+ }
1408
+ let client;
1409
+ try {
1410
+ client = await deps2.createWorkerClient({
1411
+ contextPath: dbDir
1412
+ });
1413
+ } catch (err) {
1414
+ return {
1415
+ error: `error: ${errorToMessage(err)}`,
1416
+ exitCode: 1
1417
+ };
1418
+ }
1419
+ try {
1420
+ const gateResult = await versionGate(client, dbDir);
1421
+ if (gateResult) return gateResult;
1422
+ if (deps2.startMcpServer) {
1423
+ await deps2.startMcpServer(dbDir);
1424
+ }
1425
+ return { exitCode: 0 };
1426
+ } catch (err) {
1427
+ return {
1428
+ error: `error: mcp failed: ${errorToMessage(err)}`,
1429
+ exitCode: 1
1430
+ };
1431
+ } finally {
1432
+ client.disconnect();
1433
+ }
1434
+ }
1435
+ async function handleMigrate(options, deps2) {
1436
+ const dbDir = deps2.findDb(options.dbPath);
1437
+ if (!dbDir) {
1438
+ const basePath = options.dbPath ?? process.cwd();
1439
+ return {
1440
+ error: `error: no .kbdb database found at ${basePath}`,
1441
+ exitCode: 1
1442
+ };
1443
+ }
1444
+ let client;
1445
+ try {
1446
+ client = await deps2.createWorkerClient({
1447
+ contextPath: dbDir
1448
+ });
1449
+ } catch (err) {
1450
+ return {
1451
+ error: `error: ${errorToMessage(err)}`,
1452
+ exitCode: 1
1453
+ };
1454
+ }
1455
+ try {
1456
+ const versionStatus = await client.checkVersion(dbDir);
1457
+ if (versionStatus.status === "too_new") {
1458
+ return {
1459
+ error: `error: database version ${versionStatus.currentVersion.toString()} is newer than kbdb version ${versionStatus.requiredVersion.toString()} -- upgrade kbdb`,
1460
+ exitCode: 1
1461
+ };
1462
+ }
1463
+ if (versionStatus.status === "needs_migration") {
1464
+ const migrateResult = await client.migrateDatabase(dbDir);
1465
+ return {
1466
+ output: JSON.stringify(migrateResult, null, 2),
1467
+ exitCode: 0
1468
+ };
1469
+ }
1470
+ return { output: "already up to date", exitCode: 0 };
1471
+ } catch (err) {
1472
+ return {
1473
+ error: `error: migrate failed: ${errorToMessage(err)}`,
1474
+ exitCode: 1
1475
+ };
1476
+ } finally {
1477
+ client.disconnect();
1478
+ }
1479
+ }
1480
+ async function handleDataCommand(options, deps2) {
1481
+ let dbDir = deps2.findDb(options.dbPath);
1482
+ if (!dbDir) {
1483
+ const basePath = options.dbPath ?? process.cwd();
1484
+ if (!deps2.isStdinTty()) {
1485
+ return {
1486
+ error: `error: no .kbdb database found at ${basePath} -- run \`kbdb --init\` to create one`,
1487
+ exitCode: 1
1488
+ };
1489
+ }
1490
+ const answer = await deps2.promptUser(
1491
+ `No .kbdb database found. Create one in ${basePath}? [y/N] `
1492
+ );
1493
+ if (answer.toLowerCase() !== "y") {
1494
+ return {
1495
+ error: "aborted: no database created",
1496
+ exitCode: 1
1497
+ };
1498
+ }
1499
+ const initResult = deps2.runInit(options);
1500
+ if (!initResult.ok) {
1501
+ return {
1502
+ error: `error: ${initResult.errorMessage ?? "init failed"}`,
1503
+ exitCode: 1
1504
+ };
1505
+ }
1506
+ dbDir = initResult.targetPath;
1507
+ }
1508
+ let client;
1509
+ try {
1510
+ client = await deps2.createWorkerClient({
1511
+ contextPath: dbDir
1512
+ });
1513
+ } catch (err) {
1514
+ return {
1515
+ error: `error: ${errorToMessage(err)}`,
1516
+ exitCode: 1
1517
+ };
1518
+ }
1519
+ try {
1520
+ const gateResult = await versionGate(client, dbDir);
1521
+ if (gateResult) return gateResult;
1522
+ return await dispatchCommand(client, options);
1523
+ } finally {
1524
+ client.disconnect();
1525
+ }
1526
+ }
1527
+ async function versionGate(client, dbDir) {
1528
+ const versionStatus = await client.checkVersion(dbDir);
1529
+ if (versionStatus.status === "needs_migration") {
1530
+ return {
1531
+ error: "error: database needs migration -- run `kbdb --migrate`",
1532
+ exitCode: 1
1533
+ };
1534
+ }
1535
+ if (versionStatus.status === "too_new") {
1536
+ return {
1537
+ error: `error: database version ${versionStatus.currentVersion.toString()} is newer than kbdb version ${versionStatus.requiredVersion.toString()} -- upgrade kbdb`,
1538
+ exitCode: 1
1539
+ };
1540
+ }
1541
+ return null;
1542
+ }
1543
+
1544
+ // src/shared/cli/constants/help-text.constant.ts
1545
+ var HELP_TEXT = generateHelp();
1546
+
1547
+ // src/shared/worker-client/classes/worker-client.class.ts
1548
+ import { connect } from "node:net";
1549
+ var WorkerClient = class {
1550
+ /**
1551
+ * @param socketPath - absolute path to the daemon's IPC socket
1552
+ * (or Windows named pipe path)
1553
+ * @param contextId - 16-character context identifier sent as
1554
+ * `ctx` in every JSON-RPC request
1555
+ */
1556
+ constructor(socketPath, contextId) {
1557
+ this.socketPath = socketPath;
1558
+ this.contextId = contextId;
1559
+ }
1560
+ /** Underlying socket; `null` when not connected. */
1561
+ socket = null;
1562
+ /** Monotonically increasing request ID counter. */
1563
+ nextId = 1;
1564
+ /** Map of outstanding request IDs to their resolve/reject pairs. */
1565
+ pending = /* @__PURE__ */ new Map();
1566
+ /** Partial line buffer for split TCP/IPC frames. */
1567
+ buffer = "";
1568
+ /**
1569
+ * Establishes the IPC connection to the worker daemon.
1570
+ *
1571
+ * @throws {Error} if the connection cannot be established
1572
+ */
1573
+ async connect() {
1574
+ return new Promise((resolve4, reject) => {
1575
+ this.socket = connect(this.socketPath, () => {
1576
+ resolve4();
1577
+ });
1578
+ this.socket.on("error", (err) => {
1579
+ reject(err);
1580
+ });
1581
+ this.socket.on("data", (chunk) => {
1582
+ this.handleData(chunk.toString());
1583
+ });
1584
+ });
1585
+ }
1586
+ /** Destroys the IPC socket and clears the connection state. */
1587
+ disconnect() {
1588
+ if (this.socket) {
1589
+ this.socket.destroy();
1590
+ this.socket = null;
1591
+ }
1592
+ }
1593
+ /**
1594
+ * Searches the knowledge base.
1595
+ *
1596
+ * @param params - query parameters including the search string
1597
+ * @returns ranked list of matching sections
1598
+ */
1599
+ async search(params) {
1600
+ return this.call("search", params);
1601
+ }
1602
+ /**
1603
+ * Adds a new section to the knowledge base.
1604
+ *
1605
+ * @param params - section content and metadata
1606
+ * @returns the result including the assigned knowledge-base
1607
+ * identifier and indexing statistics
1608
+ */
1609
+ async addSection(params) {
1610
+ return this.call(
1611
+ "addSection",
1612
+ params
1613
+ );
1614
+ }
1615
+ /**
1616
+ * Replaces an existing section's content and metadata.
1617
+ *
1618
+ * @param kbid - identifier of the section to update
1619
+ * @param params - new content and metadata
1620
+ * @returns the knowledge-base identifier of the updated section
1621
+ */
1622
+ async updateSection(kbid, params) {
1623
+ return this.call("updateSection", {
1624
+ kbid,
1625
+ ...params
1626
+ });
1627
+ }
1628
+ /**
1629
+ * Removes a section from the knowledge base.
1630
+ *
1631
+ * @param kbid - identifier of the section to remove
1632
+ * @returns removal result with `removed` flag and elapsed time
1633
+ */
1634
+ async removeSection(kbid) {
1635
+ return this.call("removeSection", {
1636
+ kbid
1637
+ });
1638
+ }
1639
+ /**
1640
+ * Retrieves multiple sections by their identifiers.
1641
+ *
1642
+ * @param kbids - list of knowledge-base identifiers to fetch
1643
+ * @returns sections in the order their IDs were requested
1644
+ */
1645
+ async readSections(kbids) {
1646
+ return this.call("readSections", {
1647
+ kbids
1648
+ });
1649
+ }
1650
+ /**
1651
+ * Groups a set of sections under a named document.
1652
+ *
1653
+ * @param title - human-readable document title
1654
+ * @param kbids - identifiers of the sections to group
1655
+ * @param docType - application-level document type tag; omit or
1656
+ * pass an empty string for untagged documents
1657
+ * @returns the assigned document identifier
1658
+ */
1659
+ async groupSections(title, kbids, docType) {
1660
+ const result = await this.call("groupSections", {
1661
+ title,
1662
+ kbids,
1663
+ docType: docType ?? ""
1664
+ });
1665
+ return typeof result === "string" ? result : result.docid;
1666
+ }
1667
+ /**
1668
+ * Removes the document grouping for the given document.
1669
+ *
1670
+ * The sections themselves are not deleted; only the grouping
1671
+ * record is removed.
1672
+ *
1673
+ * @param docid - identifier of the document grouping to remove
1674
+ */
1675
+ async removeGrouping(docid) {
1676
+ await this.call("removeGrouping", { docid });
1677
+ }
1678
+ /**
1679
+ * Retrieves a full document record including its sections.
1680
+ *
1681
+ * @param docid - identifier of the document to retrieve
1682
+ * @returns the document record as returned by the daemon
1683
+ */
1684
+ async retrieveDocument(docid) {
1685
+ return this.call("retrieveDocument", { docid });
1686
+ }
1687
+ /**
1688
+ * Composes a rendered Markdown document from one or more kbid
1689
+ * or docid identifiers.
1690
+ *
1691
+ * @param ids - list of kbid or docid identifiers (may be mixed)
1692
+ * @returns composed Markdown result with character count
1693
+ */
1694
+ async content(ids) {
1695
+ return this.call("content", { ids });
1696
+ }
1697
+ /**
1698
+ * Runs an integrity check on the knowledge-base database.
1699
+ *
1700
+ * @returns a report of all issues found; `ok` is `true` when
1701
+ * no errors were detected
1702
+ */
1703
+ async integrityCheck() {
1704
+ return this.call(
1705
+ "integrityCheck",
1706
+ {}
1707
+ );
1708
+ }
1709
+ /**
1710
+ * Removes unreferenced sections from the database.
1711
+ *
1712
+ * @returns a report of sections removed and bytes freed
1713
+ */
1714
+ async gc() {
1715
+ return this.call("gc", {});
1716
+ }
1717
+ /**
1718
+ * Reconstructs all index files from section files and document
1719
+ * manifests on disk. Text and code sections are re-tokenized;
1720
+ * image sections are skipped.
1721
+ *
1722
+ * @returns a report of sections and terms re-indexed
1723
+ */
1724
+ async rebuildIndexes() {
1725
+ return this.call("rebuildIndexes", {});
1726
+ }
1727
+ /**
1728
+ * Invalidates the in-memory cache entry for a single section.
1729
+ *
1730
+ * @param kbid - identifier of the section to evict from cache
1731
+ */
1732
+ async invalidate(kbid) {
1733
+ await this.call("invalidate", { kbid });
1734
+ }
1735
+ /** Clears all entries from the daemon's in-memory cache. */
1736
+ async invalidateAll() {
1737
+ await this.call("invalidateAll", {});
1738
+ }
1739
+ /**
1740
+ * Retrieves diagnostic status information from the daemon.
1741
+ *
1742
+ * @returns current initialization state and cache statistics
1743
+ */
1744
+ async status() {
1745
+ return this.call("status", {});
1746
+ }
1747
+ /**
1748
+ * Returns database metadata and status from the daemon,
1749
+ * including document count, section count, index size, and
1750
+ * cache statistics.
1751
+ *
1752
+ * @returns database metadata from the daemon's cached state
1753
+ */
1754
+ async dbStatus() {
1755
+ return this.call("dbStatus", {});
1756
+ }
1757
+ /**
1758
+ * Initialises a new `.kbdb` database directory at the given path
1759
+ * by sending an init request to the worker daemon.
1760
+ *
1761
+ * The daemon creates all required subdirectories and seed files via
1762
+ * the `worker_init_directory` WASM export.
1763
+ *
1764
+ * @param targetPath - absolute path to the directory that will
1765
+ * contain the new `.kbdb` database
1766
+ * @throws {Error} if the `.kbdb` directory already exists or the
1767
+ * daemon cannot create the layout
1768
+ */
1769
+ async initDirectory(targetPath) {
1770
+ await this.call("initDirectory", { targetPath });
1771
+ }
1772
+ /**
1773
+ * Runs all pending database migrations for the `.kbdb` directory
1774
+ * at the given path.
1775
+ *
1776
+ * Delegates to the `worker_migrate` WASM export on the daemon.
1777
+ * Each migration step updates `catalog.toml` on success, so
1778
+ * retrying after a partial failure is safe.
1779
+ *
1780
+ * @param targetPath - absolute path to the `.kbdb` database root
1781
+ * @returns migration report with old version, new version, and
1782
+ * number of migration steps applied
1783
+ */
1784
+ async migrateDatabase(targetPath) {
1785
+ return this.call("migrateDatabase", {
1786
+ targetPath
1787
+ });
1788
+ }
1789
+ /**
1790
+ * Checks the format version of the `.kbdb` database at the given
1791
+ * path against the version required by the current WASM engine.
1792
+ *
1793
+ * This is a read-only operation: it reads `catalog.toml` and
1794
+ * returns the compatibility status without making any changes.
1795
+ *
1796
+ * @param targetPath - absolute path to the `.kbdb` database root
1797
+ * @returns version compatibility report
1798
+ */
1799
+ async checkVersion(targetPath) {
1800
+ return this.call("checkVersion", {
1801
+ targetPath
1802
+ });
1803
+ }
1804
+ /**
1805
+ * Retrieves all sections whose type name matches the given string.
1806
+ *
1807
+ * @param sectionType - the application-level type name to filter by
1808
+ * @returns all section records with a matching type name
1809
+ */
1810
+ async listByType(sectionType) {
1811
+ return this.call("listByType", {
1812
+ sectionType
1813
+ });
1814
+ }
1815
+ /**
1816
+ * Retrieves all documents whose type name matches the given string.
1817
+ *
1818
+ * @param docType - the application-level document type to filter by
1819
+ * @returns all document manifests with a matching type name
1820
+ */
1821
+ async listDocumentsByType(docType) {
1822
+ return this.call("listDocumentsByType", {
1823
+ docType
1824
+ });
1825
+ }
1826
+ /**
1827
+ * Sends a JSON-RPC 2.0 request and awaits the response.
1828
+ *
1829
+ * @param method - the RPC method name
1830
+ * @param params - parameters to include in the request
1831
+ * @throws {Error} if not connected
1832
+ * @throws {Error} when the daemon returns an error response
1833
+ */
1834
+ async call(method, params) {
1835
+ const socket = this.socket;
1836
+ if (!socket) {
1837
+ throw new Error("not connected");
1838
+ }
1839
+ const id = this.nextId++;
1840
+ const request = {
1841
+ jsonrpc: "2.0",
1842
+ id,
1843
+ method,
1844
+ params: { ctx: this.contextId, ...params }
1845
+ };
1846
+ return new Promise((resolve4, reject) => {
1847
+ this.pending.set(id, { resolve: resolve4, reject });
1848
+ socket.write(JSON.stringify(request) + "\n");
1849
+ });
1850
+ }
1851
+ /**
1852
+ * Processes incoming data from the socket, splitting on newlines
1853
+ * and dispatching complete JSON-RPC response objects.
1854
+ *
1855
+ * @param data - raw string chunk received from the socket
1856
+ */
1857
+ handleData(data) {
1858
+ this.buffer += data;
1859
+ const lines = this.buffer.split("\n");
1860
+ this.buffer = lines.pop() ?? "";
1861
+ for (const line of lines) {
1862
+ if (!line.trim()) continue;
1863
+ try {
1864
+ const response = JSON.parse(line);
1865
+ const pending = this.pending.get(response.id);
1866
+ if (pending) {
1867
+ this.pending.delete(response.id);
1868
+ if (response.error) {
1869
+ const err = new Error(response.error.message);
1870
+ err.code = response.error.code;
1871
+ pending.reject(err);
1872
+ } else {
1873
+ pending.resolve(response.result);
1874
+ }
1875
+ }
1876
+ } catch {
1877
+ }
1878
+ }
1879
+ }
1880
+ };
1881
+
1882
+ // src/shared/worker-client/functions/create-worker-client.function.ts
1883
+ import { existsSync as existsSync6, readFileSync as readFileSync3, unlinkSync as unlinkSync2 } from "node:fs";
1884
+ import { join as join7 } from "node:path";
1885
+ import { tmpdir as tmpdir3 } from "node:os";
1886
+
1887
+ // src/shared/worker-client/functions/resolve-db-path.function.ts
1888
+ import { existsSync as existsSync3 } from "node:fs";
1889
+ import { join as join4, resolve as resolve3 } from "node:path";
1890
+ function resolveDbPath(targetDir) {
1891
+ const base = targetDir ? resolve3(targetDir) : process.cwd();
1892
+ const dbPath = join4(base, ".kbdb");
1893
+ if (!existsSync3(dbPath)) {
1894
+ throw new Error(`database not found: ${dbPath}`);
1895
+ }
1896
+ return dbPath;
1897
+ }
1898
+
1899
+ // src/shared/worker-client/functions/compute-context-id.function.ts
1900
+ async function computeContextId(absolutePath) {
1901
+ const hash = await computeSha256(absolutePath);
1902
+ return hash.slice(0, 16);
1903
+ }
1904
+
1905
+ // src/shared/worker-client/functions/discover-daemon.function.ts
1906
+ import { existsSync as existsSync4, readFileSync as readFileSync2, unlinkSync } from "node:fs";
1907
+ import { join as join5 } from "node:path";
1908
+ import { tmpdir } from "node:os";
1909
+
1910
+ // src/shared/platform/functions/is-process-alive.function.ts
1911
+ function isProcessAlive(pid) {
1912
+ try {
1913
+ process.kill(pid, 0);
1914
+ return true;
1915
+ } catch {
1916
+ return false;
1917
+ }
1918
+ }
1919
+
1920
+ // src/shared/worker-client/functions/discover-daemon.function.ts
1921
+ function discoverDaemon(contextId) {
1922
+ const pidPath = join5(tmpdir(), `kbdb-${contextId}.pid`);
1923
+ if (!existsSync4(pidPath)) return null;
1924
+ const pidStr = readFileSync2(pidPath, "utf-8").trim();
1925
+ const pid = parseInt(pidStr, 10);
1926
+ if (isNaN(pid) || !isProcessAlive(pid)) {
1927
+ try {
1928
+ unlinkSync(pidPath);
1929
+ } catch {
1930
+ }
1931
+ return null;
1932
+ }
1933
+ const socketPath = join5(tmpdir(), `kbdb-${contextId}.sock`);
1934
+ const crashPath = join5(tmpdir(), `kbdb-${contextId}.crash`);
1935
+ try {
1936
+ unlinkSync(crashPath);
1937
+ } catch {
1938
+ }
1939
+ return { pid, socketPath };
1940
+ }
1941
+
1942
+ // src/shared/worker-client/functions/spawn-daemon.function.ts
1943
+ import { spawn } from "node:child_process";
1944
+ function spawnDaemon(contextPath, runtime2, workerScript2) {
1945
+ if (!workerScript2) {
1946
+ throw new Error(
1947
+ "workerScript must be provided (resolve at entry point)"
1948
+ );
1949
+ }
1950
+ const execPath = runtime2 === "deno" ? "deno" : process.execPath;
1951
+ const args = runtime2 === "deno" ? ["run", "--allow-all", workerScript2, contextPath] : [workerScript2, contextPath];
1952
+ const child = spawn(execPath, args, {
1953
+ detached: true,
1954
+ stdio: "ignore"
1955
+ });
1956
+ child.unref();
1957
+ }
1958
+
1959
+ // src/shared/worker-client/functions/wait-for-daemon.function.ts
1960
+ import { existsSync as existsSync5 } from "node:fs";
1961
+ import { join as join6 } from "node:path";
1962
+ import { tmpdir as tmpdir2 } from "node:os";
1963
+ var DEFAULT_TIMEOUT_MS = 1e4;
1964
+ var POLL_INTERVAL_MS = 100;
1965
+ async function waitForDaemon(contextId, timeoutMs = DEFAULT_TIMEOUT_MS) {
1966
+ const pidPath = join6(tmpdir2(), `kbdb-${contextId}.pid`);
1967
+ const start = Date.now();
1968
+ while (Date.now() - start < timeoutMs) {
1969
+ if (existsSync5(pidPath)) return true;
1970
+ await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
1971
+ }
1972
+ return false;
1973
+ }
1974
+
1975
+ // src/shared/worker-client/functions/create-worker-client.function.ts
1976
+ async function createWorkerClient(options) {
1977
+ const dbPath = options?.contextPath ?? resolveDbPath(options?.dbPath);
1978
+ const contextId = await computeContextId(dbPath);
1979
+ const socketPath = getIpcPath(contextId);
1980
+ let daemon = discoverDaemon(contextId);
1981
+ if (!daemon && options?.autoSpawn !== false) {
1982
+ const runtime2 = detectRuntime();
1983
+ spawnDaemon(dbPath, runtime2, options?.workerScript);
1984
+ await waitForDaemon(contextId, options?.connectTimeoutMs);
1985
+ daemon = discoverDaemon(contextId);
1986
+ }
1987
+ if (!daemon) {
1988
+ throw new Error(
1989
+ `kbdb worker daemon did not start: ${readCrashReason(contextId)}`
1990
+ );
1991
+ }
1992
+ const client = new WorkerClient(socketPath, contextId);
1993
+ await client.connect();
1994
+ return client;
1995
+ }
1996
+ function readCrashReason(contextId) {
1997
+ const crashPath = join7(tmpdir3(), `kbdb-${contextId}.crash`);
1998
+ if (!existsSync6(crashPath)) {
1999
+ return "daemon failed to start (no details available)";
2000
+ }
2001
+ try {
2002
+ const raw = readFileSync3(crashPath, "utf-8");
2003
+ const crash = JSON.parse(raw);
2004
+ unlinkSync2(crashPath);
2005
+ return crash.error ?? "unknown error (crash log empty)";
2006
+ } catch {
2007
+ return "daemon failed to start (crash log unreadable)";
2008
+ }
2009
+ }
2010
+
2011
+ // src/shared/mcp/classes/mcp-server.class.ts
2012
+ import { createInterface as createInterface2 } from "node:readline";
2013
+
2014
+ // src/shared/mcp/functions/create-tool-definitions.function.ts
2015
+ function createToolDefinitions() {
2016
+ return [
2017
+ {
2018
+ name: "search",
2019
+ description: "Search the knowledge base for relevant sections using natural language queries.",
2020
+ inputSchema: {
2021
+ type: "object",
2022
+ properties: {
2023
+ query: {
2024
+ type: "string",
2025
+ description: "Search query text"
2026
+ },
2027
+ mode: {
2028
+ type: "string",
2029
+ enum: ["sections", "documents", "stats"],
2030
+ description: "Search mode (default: sections)"
2031
+ },
2032
+ limit: {
2033
+ type: "number",
2034
+ description: "Maximum results (default: 20)"
2035
+ }
2036
+ },
2037
+ required: ["query"]
2038
+ },
2039
+ annotations: {
2040
+ title: "Search KB",
2041
+ readOnlyHint: true,
2042
+ destructiveHint: false,
2043
+ idempotentHint: true
2044
+ }
2045
+ },
2046
+ {
2047
+ name: "learn",
2048
+ description: "Add a text section to the knowledge base.",
2049
+ inputSchema: {
2050
+ type: "object",
2051
+ properties: {
2052
+ content: {
2053
+ type: "string",
2054
+ description: "Text content to add"
2055
+ },
2056
+ type: {
2057
+ type: "string",
2058
+ description: "MIME type (default: text/markdown). Use image/* for images."
2059
+ },
2060
+ title: {
2061
+ type: "string",
2062
+ description: "Section title. Required for image/* types."
2063
+ },
2064
+ description: {
2065
+ type: "string",
2066
+ description: "Optional section description"
2067
+ },
2068
+ docid: {
2069
+ type: "string",
2070
+ description: "Document ID to group under"
2071
+ }
2072
+ },
2073
+ required: ["content"]
2074
+ },
2075
+ annotations: {
2076
+ title: "Import Content",
2077
+ readOnlyHint: false,
2078
+ destructiveHint: false,
2079
+ idempotentHint: true
2080
+ }
2081
+ },
2082
+ {
2083
+ name: "unlearn",
2084
+ description: "Remove a section from the knowledge base by its kb-id.",
2085
+ inputSchema: {
2086
+ type: "object",
2087
+ properties: {
2088
+ kbid: {
2089
+ type: "string",
2090
+ description: "Knowledge base ID of the section"
2091
+ }
2092
+ },
2093
+ required: ["kbid"]
2094
+ },
2095
+ annotations: {
2096
+ title: "Remove Section",
2097
+ readOnlyHint: false,
2098
+ destructiveHint: true,
2099
+ idempotentHint: true
2100
+ }
2101
+ },
2102
+ {
2103
+ name: "retrieve",
2104
+ description: "Retrieve a section or document by ID. Provide kbid or docid.",
2105
+ inputSchema: {
2106
+ type: "object",
2107
+ properties: {
2108
+ kbid: {
2109
+ type: "string",
2110
+ description: "Section kb-id"
2111
+ },
2112
+ docid: {
2113
+ type: "string",
2114
+ description: "Document ID"
2115
+ }
2116
+ }
2117
+ },
2118
+ annotations: {
2119
+ title: "Fetch Content",
2120
+ readOnlyHint: true,
2121
+ destructiveHint: false,
2122
+ idempotentHint: true
2123
+ }
2124
+ },
2125
+ {
2126
+ name: "status",
2127
+ description: "Get database metadata including document count, section count, index size, and cache statistics.",
2128
+ inputSchema: {
2129
+ type: "object",
2130
+ properties: {}
2131
+ },
2132
+ annotations: {
2133
+ title: "DB Status",
2134
+ readOnlyHint: true,
2135
+ destructiveHint: false,
2136
+ idempotentHint: true
2137
+ }
2138
+ },
2139
+ {
2140
+ name: "content",
2141
+ description: "Compose a rendered Markdown document from one or more kbid or docid identifiers.",
2142
+ inputSchema: {
2143
+ type: "object",
2144
+ properties: {
2145
+ ids: {
2146
+ type: "array",
2147
+ items: { type: "string" },
2148
+ description: "One or more kbid or docid identifiers (may be mixed)"
2149
+ }
2150
+ },
2151
+ required: ["ids"]
2152
+ },
2153
+ annotations: {
2154
+ title: "Compose Content",
2155
+ readOnlyHint: true,
2156
+ destructiveHint: false,
2157
+ idempotentHint: true
2158
+ }
2159
+ },
2160
+ {
2161
+ name: "check",
2162
+ description: "Verify the integrity of the knowledge base. Reports checksum mismatches, orphan sections, broken references, and circular reference chains.",
2163
+ inputSchema: {
2164
+ type: "object",
2165
+ properties: {}
2166
+ },
2167
+ annotations: {
2168
+ title: "Integrity Check",
2169
+ readOnlyHint: true,
2170
+ destructiveHint: false,
2171
+ idempotentHint: true
2172
+ }
2173
+ },
2174
+ {
2175
+ name: "gc",
2176
+ description: "Remove unreferenced sections from the knowledge base. A section is eligible when no document manifest references it.",
2177
+ inputSchema: {
2178
+ type: "object",
2179
+ properties: {}
2180
+ },
2181
+ annotations: {
2182
+ title: "Garbage Collect",
2183
+ readOnlyHint: false,
2184
+ destructiveHint: true,
2185
+ idempotentHint: false
2186
+ }
2187
+ },
2188
+ {
2189
+ name: "rebuild",
2190
+ description: "Reconstruct all index files from section files and document manifests on disk. Use this to recover from index corruption.",
2191
+ inputSchema: {
2192
+ type: "object",
2193
+ properties: {}
2194
+ },
2195
+ annotations: {
2196
+ title: "Rebuild Indexes",
2197
+ readOnlyHint: false,
2198
+ destructiveHint: false,
2199
+ idempotentHint: false
2200
+ }
2201
+ },
2202
+ {
2203
+ name: "skill-learn",
2204
+ description: "Create or update a skill definition. Skills are reusable AI agent capabilities with template placeholders.",
2205
+ inputSchema: {
2206
+ type: "object",
2207
+ properties: {
2208
+ name: {
2209
+ type: "string",
2210
+ description: "Skill name"
2211
+ },
2212
+ description: {
2213
+ type: "string",
2214
+ description: "Skill description"
2215
+ },
2216
+ body: {
2217
+ type: "string",
2218
+ description: "Skill body template. Use {{argName}} for placeholders."
2219
+ }
2220
+ },
2221
+ required: ["name", "body"]
2222
+ },
2223
+ annotations: {
2224
+ title: "Create Skill",
2225
+ readOnlyHint: false,
2226
+ destructiveHint: false,
2227
+ idempotentHint: true
2228
+ }
2229
+ },
2230
+ {
2231
+ name: "skill-list",
2232
+ description: "List all skills in the knowledge base.",
2233
+ inputSchema: {
2234
+ type: "object",
2235
+ properties: {}
2236
+ },
2237
+ annotations: {
2238
+ title: "List Skills",
2239
+ readOnlyHint: true,
2240
+ destructiveHint: false,
2241
+ idempotentHint: true
2242
+ }
2243
+ },
2244
+ {
2245
+ name: "skill-get",
2246
+ description: "Get a skill definition by name or kbid.",
2247
+ inputSchema: {
2248
+ type: "object",
2249
+ properties: {
2250
+ name: {
2251
+ type: "string",
2252
+ description: "Skill name"
2253
+ },
2254
+ kbid: {
2255
+ type: "string",
2256
+ description: "Knowledge base ID"
2257
+ }
2258
+ }
2259
+ },
2260
+ annotations: {
2261
+ title: "Get Skill",
2262
+ readOnlyHint: true,
2263
+ destructiveHint: false,
2264
+ idempotentHint: true
2265
+ }
2266
+ },
2267
+ {
2268
+ name: "skill-delete",
2269
+ description: "Delete a skill by its kbid.",
2270
+ inputSchema: {
2271
+ type: "object",
2272
+ properties: {
2273
+ kbid: {
2274
+ type: "string",
2275
+ description: "Knowledge base ID"
2276
+ }
2277
+ },
2278
+ required: ["kbid"]
2279
+ },
2280
+ annotations: {
2281
+ title: "Delete Skill",
2282
+ readOnlyHint: false,
2283
+ destructiveHint: true,
2284
+ idempotentHint: true
2285
+ }
2286
+ },
2287
+ {
2288
+ name: "agent-create",
2289
+ description: "Create an AI agent with a persona and optional skill references.",
2290
+ inputSchema: {
2291
+ type: "object",
2292
+ properties: {
2293
+ name: {
2294
+ type: "string",
2295
+ description: "Agent name"
2296
+ },
2297
+ description: {
2298
+ type: "string",
2299
+ description: "Agent description"
2300
+ },
2301
+ persona: {
2302
+ type: "string",
2303
+ description: "Agent persona prompt"
2304
+ },
2305
+ skills: {
2306
+ type: "array",
2307
+ items: { type: "string" },
2308
+ description: "Skill kbid references to attach"
2309
+ }
2310
+ },
2311
+ required: ["name", "persona"]
2312
+ },
2313
+ annotations: {
2314
+ title: "Create Agent",
2315
+ readOnlyHint: false,
2316
+ destructiveHint: false,
2317
+ idempotentHint: true
2318
+ }
2319
+ },
2320
+ {
2321
+ name: "agent-list",
2322
+ description: "List all agents in the knowledge base.",
2323
+ inputSchema: {
2324
+ type: "object",
2325
+ properties: {}
2326
+ },
2327
+ annotations: {
2328
+ title: "List Agents",
2329
+ readOnlyHint: true,
2330
+ destructiveHint: false,
2331
+ idempotentHint: true
2332
+ }
2333
+ },
2334
+ {
2335
+ name: "agent-get",
2336
+ description: "Get an agent definition by document ID.",
2337
+ inputSchema: {
2338
+ type: "object",
2339
+ properties: {
2340
+ docid: {
2341
+ type: "string",
2342
+ description: "Document ID of the agent"
2343
+ }
2344
+ },
2345
+ required: ["docid"]
2346
+ },
2347
+ annotations: {
2348
+ title: "Get Agent",
2349
+ readOnlyHint: true,
2350
+ destructiveHint: false,
2351
+ idempotentHint: true
2352
+ }
2353
+ },
2354
+ {
2355
+ name: "agent-delete",
2356
+ description: "Delete an agent by its document ID. Skill sections are not removed.",
2357
+ inputSchema: {
2358
+ type: "object",
2359
+ properties: {
2360
+ docid: {
2361
+ type: "string",
2362
+ description: "Document ID of the agent"
2363
+ }
2364
+ },
2365
+ required: ["docid"]
2366
+ },
2367
+ annotations: {
2368
+ title: "Delete Agent",
2369
+ readOnlyHint: false,
2370
+ destructiveHint: true,
2371
+ idempotentHint: true
2372
+ }
2373
+ }
2374
+ ];
2375
+ }
2376
+
2377
+ // src/shared/mcp/functions/create-resource-templates.function.ts
2378
+ function createResourceTemplates() {
2379
+ return [
2380
+ {
2381
+ uriTemplate: "kbdb://section/{kb_id}",
2382
+ name: "Section",
2383
+ description: "A knowledge base section by its kb-id.",
2384
+ mimeType: "text/plain"
2385
+ },
2386
+ {
2387
+ uriTemplate: "kbdb://document/{doc_id}",
2388
+ name: "Document",
2389
+ description: "A document with its ordered sections.",
2390
+ mimeType: "application/json"
2391
+ }
2392
+ ];
2393
+ }
2394
+
2395
+ // src/shared/mcp/functions/handle-agent-create.function.ts
2396
+ function asString(value, fallback) {
2397
+ return typeof value === "string" ? value : fallback;
2398
+ }
2399
+ function asStringArray(value) {
2400
+ if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
2401
+ return value;
2402
+ }
2403
+ return [];
2404
+ }
2405
+ async function handleAgentCreate(client, args) {
2406
+ const name = asString(args["name"], "");
2407
+ const description = asString(args["description"], "");
2408
+ const persona = asString(args["persona"], "");
2409
+ const skills = asStringArray(args["skills"]);
2410
+ if (!name) {
2411
+ return {
2412
+ content: [{ type: "text", text: "name is required" }],
2413
+ isError: true
2414
+ };
2415
+ }
2416
+ if (!persona) {
2417
+ return {
2418
+ content: [{ type: "text", text: "persona is required" }],
2419
+ isError: true
2420
+ };
2421
+ }
2422
+ if (skills.length > 0) {
2423
+ const sections = await client.readSections(skills);
2424
+ const found = new Set(sections.map((s) => s.kbid));
2425
+ const missing = skills.filter((k) => !found.has(k));
2426
+ if (missing.length > 0) {
2427
+ return {
2428
+ content: [
2429
+ {
2430
+ type: "text",
2431
+ text: `skill not found: ${missing.join(", ")}`
2432
+ }
2433
+ ],
2434
+ isError: true
2435
+ };
2436
+ }
2437
+ }
2438
+ const metadata = JSON.stringify({ name, description, persona });
2439
+ const metaResult = await client.addSection({
2440
+ sectionType: "text",
2441
+ content: metadata,
2442
+ title: name,
2443
+ description
2444
+ });
2445
+ const allKbids = [metaResult.kbid, ...skills];
2446
+ const docid = await client.groupSections(name, allKbids);
2447
+ return {
2448
+ content: [
2449
+ {
2450
+ type: "text",
2451
+ text: JSON.stringify({
2452
+ docid,
2453
+ name,
2454
+ skillCount: skills.length
2455
+ })
2456
+ }
2457
+ ]
2458
+ };
2459
+ }
2460
+
2461
+ // src/shared/mcp/functions/handle-agent-list.function.ts
2462
+ async function handleAgentList(client) {
2463
+ const docs = await client.listDocumentsByType("agent");
2464
+ const items = docs.map((d) => ({
2465
+ docid: d.docid,
2466
+ name: d.title,
2467
+ skillCount: Math.max(0, d.sections.length - 1)
2468
+ }));
2469
+ return {
2470
+ content: [
2471
+ {
2472
+ type: "text",
2473
+ text: JSON.stringify(items, null, 2)
2474
+ }
2475
+ ]
2476
+ };
2477
+ }
2478
+
2479
+ // src/shared/mcp/functions/handle-agent-get.function.ts
2480
+ async function readAgentMeta2(client, metaKbid, fallbackName) {
2481
+ const metaSections = await client.readSections([metaKbid]);
2482
+ const first = metaSections.at(0);
2483
+ if (!first) {
2484
+ return { name: fallbackName, description: "", persona: "" };
2485
+ }
2486
+ try {
2487
+ const meta = JSON.parse(first.content);
2488
+ return {
2489
+ name: typeof meta["name"] === "string" ? meta["name"] : fallbackName,
2490
+ description: typeof meta["description"] === "string" ? meta["description"] : "",
2491
+ persona: typeof meta["persona"] === "string" ? meta["persona"] : ""
2492
+ };
2493
+ } catch {
2494
+ return { name: fallbackName, description: "", persona: "" };
2495
+ }
2496
+ }
2497
+ async function resolveSkillRefs(client, skillRefs) {
2498
+ if (skillRefs.length === 0) {
2499
+ return [];
2500
+ }
2501
+ const skillKbids = skillRefs.map((s) => s.kbid);
2502
+ const skillSections = await client.readSections(skillKbids);
2503
+ const sectionMap = new Map(skillSections.map((s) => [s.kbid, s]));
2504
+ return skillRefs.map((ref) => {
2505
+ const sec = sectionMap.get(ref.kbid);
2506
+ if (!sec) {
2507
+ return { kbid: ref.kbid, name: null, position: ref.position };
2508
+ }
2509
+ try {
2510
+ const parsed = JSON.parse(sec.content);
2511
+ const skillName = typeof parsed["name"] === "string" ? parsed["name"] : null;
2512
+ return {
2513
+ kbid: ref.kbid,
2514
+ name: skillName,
2515
+ position: ref.position
2516
+ };
2517
+ } catch {
2518
+ return { kbid: ref.kbid, name: null, position: ref.position };
2519
+ }
2520
+ });
2521
+ }
2522
+ async function handleAgentGet(client, args) {
2523
+ const docid = typeof args["docid"] === "string" ? args["docid"] : "";
2524
+ if (!docid) {
2525
+ return {
2526
+ content: [{ type: "text", text: "docid is required" }],
2527
+ isError: true
2528
+ };
2529
+ }
2530
+ const doc = await client.retrieveDocument(docid);
2531
+ const metaKbid = doc.sections[0]?.kbid;
2532
+ const skillRefs = doc.sections.slice(1);
2533
+ const { name, description, persona } = metaKbid ? await readAgentMeta2(client, metaKbid, doc.title) : { name: doc.title, description: "", persona: "" };
2534
+ const skills = await resolveSkillRefs(client, skillRefs);
2535
+ const agent = {
2536
+ docid,
2537
+ name,
2538
+ description,
2539
+ persona,
2540
+ skills
2541
+ };
2542
+ return {
2543
+ content: [
2544
+ {
2545
+ type: "text",
2546
+ text: JSON.stringify(agent, null, 2)
2547
+ }
2548
+ ]
2549
+ };
2550
+ }
2551
+
2552
+ // src/shared/mcp/functions/handle-agent-delete.function.ts
2553
+ async function handleAgentDelete(client, args) {
2554
+ const docid = typeof args["docid"] === "string" ? args["docid"] : "";
2555
+ if (!docid) {
2556
+ return {
2557
+ content: [{ type: "text", text: "docid is required" }],
2558
+ isError: true
2559
+ };
2560
+ }
2561
+ await client.removeGrouping(docid);
2562
+ return {
2563
+ content: [
2564
+ {
2565
+ type: "text",
2566
+ text: JSON.stringify({ docid, removed: true })
2567
+ }
2568
+ ]
2569
+ };
2570
+ }
2571
+
2572
+ // src/shared/mcp/functions/handle-tool-call.function.ts
2573
+ function asString2(value, fallback) {
2574
+ return typeof value === "string" ? value : fallback;
2575
+ }
2576
+ function asStringArray2(value) {
2577
+ if (Array.isArray(value) && value.every((item) => typeof item === "string")) {
2578
+ return value;
2579
+ }
2580
+ return [];
2581
+ }
2582
+ async function handleToolCall(client, name, args) {
2583
+ try {
2584
+ switch (name) {
2585
+ case "search":
2586
+ return await handleSearch2(client, args);
2587
+ case "learn":
2588
+ return await handleLearn2(client, args);
2589
+ case "unlearn":
2590
+ return await handleUnlearn2(client, args);
2591
+ case "retrieve":
2592
+ return await handleRetrieve(client, args);
2593
+ case "status":
2594
+ return await handleStatus2(client);
2595
+ case "content":
2596
+ return await handleContent2(client, args);
2597
+ case "check":
2598
+ return await handleCheck2(client);
2599
+ case "gc":
2600
+ return await handleGc2(client);
2601
+ case "rebuild":
2602
+ return await handleRebuild2(client);
2603
+ case "skill-learn":
2604
+ return await handleSkillLearn(client, args);
2605
+ case "skill-list":
2606
+ return await handleSkillList(client);
2607
+ case "skill-get":
2608
+ return await handleSkillGet(client, args);
2609
+ case "skill-delete":
2610
+ return await handleSkillDelete(client, args);
2611
+ case "agent-create":
2612
+ return await handleAgentCreate(client, args);
2613
+ case "agent-list":
2614
+ return await handleAgentList(client);
2615
+ case "agent-get":
2616
+ return await handleAgentGet(client, args);
2617
+ case "agent-delete":
2618
+ return await handleAgentDelete(client, args);
2619
+ default:
2620
+ return {
2621
+ content: [
2622
+ {
2623
+ type: "text",
2624
+ text: `Unknown tool: ${name}`
2625
+ }
2626
+ ],
2627
+ isError: true
2628
+ };
2629
+ }
2630
+ } catch (err) {
2631
+ return {
2632
+ content: [
2633
+ {
2634
+ type: "text",
2635
+ text: err instanceof Error ? err.message : String(err)
2636
+ }
2637
+ ],
2638
+ isError: true
2639
+ };
2640
+ }
2641
+ }
2642
+ async function handleSearch2(client, args) {
2643
+ const results = await client.search({
2644
+ query: asString2(args["query"], ""),
2645
+ mode: args["mode"],
2646
+ limit: args["limit"]
2647
+ });
2648
+ return {
2649
+ content: [
2650
+ {
2651
+ type: "text",
2652
+ text: JSON.stringify(results, null, 2)
2653
+ }
2654
+ ]
2655
+ };
2656
+ }
2657
+ async function handleLearn2(client, args) {
2658
+ const sectionType = asString2(args["type"], "text/markdown");
2659
+ const title = typeof args["title"] === "string" ? args["title"] : void 0;
2660
+ const description = typeof args["description"] === "string" ? args["description"] : void 0;
2661
+ const docid = typeof args["docid"] === "string" ? args["docid"] : void 0;
2662
+ if (sectionType.startsWith("image/") && !title) {
2663
+ return {
2664
+ content: [
2665
+ {
2666
+ type: "text",
2667
+ text: "title is required for image/* types"
2668
+ }
2669
+ ],
2670
+ isError: true
2671
+ };
2672
+ }
2673
+ const result = await client.addSection({
2674
+ sectionType,
2675
+ content: asString2(args["content"], ""),
2676
+ title,
2677
+ description,
2678
+ docid
2679
+ });
2680
+ return {
2681
+ content: [
2682
+ {
2683
+ type: "text",
2684
+ text: JSON.stringify(result)
2685
+ }
2686
+ ]
2687
+ };
2688
+ }
2689
+ async function handleUnlearn2(client, args) {
2690
+ const result = await client.removeSection(
2691
+ asString2(args["kbid"], "")
2692
+ );
2693
+ return {
2694
+ content: [
2695
+ {
2696
+ type: "text",
2697
+ text: JSON.stringify(result)
2698
+ }
2699
+ ]
2700
+ };
2701
+ }
2702
+ async function handleRetrieve(client, args) {
2703
+ if (typeof args["kbid"] === "string") {
2704
+ const sections = await client.readSections([args["kbid"]]);
2705
+ return {
2706
+ content: [
2707
+ {
2708
+ type: "text",
2709
+ text: JSON.stringify(sections, null, 2)
2710
+ }
2711
+ ]
2712
+ };
2713
+ }
2714
+ if (typeof args["docid"] === "string") {
2715
+ const doc = await client.retrieveDocument(args["docid"]);
2716
+ return {
2717
+ content: [
2718
+ {
2719
+ type: "text",
2720
+ text: JSON.stringify(doc, null, 2)
2721
+ }
2722
+ ]
2723
+ };
2724
+ }
2725
+ return {
2726
+ content: [
2727
+ {
2728
+ type: "text",
2729
+ text: "Provide kbid or docid"
2730
+ }
2731
+ ],
2732
+ isError: true
2733
+ };
2734
+ }
2735
+ async function handleStatus2(client) {
2736
+ const status = await client.dbStatus();
2737
+ return {
2738
+ content: [
2739
+ {
2740
+ type: "text",
2741
+ text: JSON.stringify(status, null, 2)
2742
+ }
2743
+ ]
2744
+ };
2745
+ }
2746
+ async function handleContent2(client, args) {
2747
+ const ids = asStringArray2(args["ids"]);
2748
+ const result = await client.content(ids);
2749
+ return {
2750
+ content: [
2751
+ {
2752
+ type: "text",
2753
+ text: JSON.stringify(result)
2754
+ }
2755
+ ]
2756
+ };
2757
+ }
2758
+ async function handleCheck2(client) {
2759
+ const report = await client.integrityCheck();
2760
+ return {
2761
+ content: [
2762
+ {
2763
+ type: "text",
2764
+ text: JSON.stringify(report, null, 2)
2765
+ }
2766
+ ]
2767
+ };
2768
+ }
2769
+ async function handleGc2(client) {
2770
+ const report = await client.gc();
2771
+ return {
2772
+ content: [
2773
+ {
2774
+ type: "text",
2775
+ text: JSON.stringify(report, null, 2)
2776
+ }
2777
+ ]
2778
+ };
2779
+ }
2780
+ async function handleRebuild2(client) {
2781
+ const report = await client.rebuildIndexes();
2782
+ return {
2783
+ content: [
2784
+ {
2785
+ type: "text",
2786
+ text: JSON.stringify(report, null, 2)
2787
+ }
2788
+ ]
2789
+ };
2790
+ }
2791
+ async function handleSkillLearn(client, args) {
2792
+ const name = asString2(args["name"], "");
2793
+ if (!name) {
2794
+ return {
2795
+ content: [{ type: "text", text: "name is required" }],
2796
+ isError: true
2797
+ };
2798
+ }
2799
+ const body = asString2(args["body"], "");
2800
+ if (!body) {
2801
+ return {
2802
+ content: [{ type: "text", text: "body is required" }],
2803
+ isError: true
2804
+ };
2805
+ }
2806
+ const description = typeof args["description"] === "string" ? args["description"] : void 0;
2807
+ const skillArgs = extractSkillArguments(body);
2808
+ const skill = {
2809
+ name,
2810
+ description,
2811
+ arguments: skillArgs.length > 0 ? skillArgs : void 0,
2812
+ body
2813
+ };
2814
+ const json = serializeSkillContent(skill);
2815
+ const result = await client.addSection({
2816
+ sectionType: "skill",
2817
+ content: json,
2818
+ title: name,
2819
+ description
2820
+ });
2821
+ return {
2822
+ content: [
2823
+ {
2824
+ type: "text",
2825
+ text: JSON.stringify({ kbid: result.kbid, name })
2826
+ }
2827
+ ]
2828
+ };
2829
+ }
2830
+ async function handleSkillList(client) {
2831
+ const records = await client.listByType("skill");
2832
+ const items = records.map((r) => {
2833
+ let argumentCount = 0;
2834
+ try {
2835
+ const parsed = JSON.parse(r.content);
2836
+ if (Array.isArray(parsed["arguments"])) {
2837
+ argumentCount = parsed["arguments"].length;
2838
+ }
2839
+ } catch {
2840
+ }
2841
+ return {
2842
+ kbid: r.kbid,
2843
+ name: r.title,
2844
+ description: r.description,
2845
+ argumentCount
2846
+ };
2847
+ });
2848
+ return {
2849
+ content: [
2850
+ {
2851
+ type: "text",
2852
+ text: JSON.stringify(items, null, 2)
2853
+ }
2854
+ ]
2855
+ };
2856
+ }
2857
+ async function handleSkillGet(client, args) {
2858
+ const kbid = typeof args["kbid"] === "string" ? args["kbid"] : void 0;
2859
+ const name = typeof args["name"] === "string" ? args["name"] : void 0;
2860
+ if (!kbid && !name) {
2861
+ return {
2862
+ content: [
2863
+ {
2864
+ type: "text",
2865
+ text: "name or kbid is required"
2866
+ }
2867
+ ],
2868
+ isError: true
2869
+ };
2870
+ }
2871
+ let content;
2872
+ if (kbid) {
2873
+ const sections = await client.readSections([kbid]);
2874
+ if (sections.length > 0) {
2875
+ content = sections[0]?.content;
2876
+ }
2877
+ }
2878
+ if (content === void 0 && name) {
2879
+ const records = await client.listByType("skill");
2880
+ const match = records.filter((r) => r.title === name).pop();
2881
+ if (match) {
2882
+ content = match.content;
2883
+ }
2884
+ }
2885
+ if (content === void 0) {
2886
+ const identifier = kbid ?? name ?? "";
2887
+ return {
2888
+ content: [
2889
+ {
2890
+ type: "text",
2891
+ text: `skill not found: ${identifier}`
2892
+ }
2893
+ ],
2894
+ isError: true
2895
+ };
2896
+ }
2897
+ const skill = parseSkillContent(content);
2898
+ return {
2899
+ content: [
2900
+ {
2901
+ type: "text",
2902
+ text: JSON.stringify(skill, null, 2)
2903
+ }
2904
+ ]
2905
+ };
2906
+ }
2907
+ async function handleSkillDelete(client, args) {
2908
+ const kbid = asString2(args["kbid"], "");
2909
+ if (!kbid) {
2910
+ return {
2911
+ content: [{ type: "text", text: "kbid is required" }],
2912
+ isError: true
2913
+ };
2914
+ }
2915
+ const result = await client.removeSection(kbid);
2916
+ return {
2917
+ content: [
2918
+ {
2919
+ type: "text",
2920
+ text: JSON.stringify({ kbid, removed: result.removed })
2921
+ }
2922
+ ]
2923
+ };
2924
+ }
2925
+
2926
+ // src/shared/mcp/functions/handle-resource-read.function.ts
2927
+ async function handleResourceRead(client, uri) {
2928
+ const sectionMatch = uri.match(/^kbdb:\/\/section\/(.+)$/);
2929
+ if (sectionMatch) {
2930
+ const sections = await client.readSections([sectionMatch[1]]);
2931
+ const text = sections.length > 0 ? sections[0].content : "";
2932
+ return {
2933
+ contents: [{ uri, mimeType: "text/plain", text }]
2934
+ };
2935
+ }
2936
+ const docMatch = uri.match(/^kbdb:\/\/document\/(.+)$/);
2937
+ if (docMatch) {
2938
+ const doc = await client.retrieveDocument(docMatch[1]);
2939
+ return {
2940
+ contents: [
2941
+ {
2942
+ uri,
2943
+ mimeType: "application/json",
2944
+ text: JSON.stringify(doc, null, 2)
2945
+ }
2946
+ ]
2947
+ };
2948
+ }
2949
+ throw new Error(`Unknown resource URI: ${uri}`);
2950
+ }
2951
+
2952
+ // src/shared/mcp/functions/create-prompt-definitions.function.ts
2953
+ function parseSkillArguments(content) {
2954
+ try {
2955
+ const parsed = JSON.parse(content);
2956
+ if (!Array.isArray(parsed["arguments"])) {
2957
+ return void 0;
2958
+ }
2959
+ return parsed["arguments"].map(
2960
+ (arg) => ({
2961
+ name: typeof arg["name"] === "string" ? arg["name"] : "",
2962
+ description: typeof arg["description"] === "string" ? arg["description"] : void 0,
2963
+ required: typeof arg["required"] === "boolean" ? arg["required"] : void 0
2964
+ })
2965
+ );
2966
+ } catch {
2967
+ return void 0;
2968
+ }
2969
+ }
2970
+ function createPromptDefinitions(skills, agents) {
2971
+ const skillPrompts = skills.filter(
2972
+ (r) => r.title !== null
2973
+ ).map((record) => {
2974
+ const args = parseSkillArguments(record.content);
2975
+ const prompt = {
2976
+ name: record.title,
2977
+ description: record.description ?? void 0,
2978
+ arguments: args
2979
+ };
2980
+ return prompt;
2981
+ });
2982
+ const agentPrompts = agents.map((doc) => ({
2983
+ name: `agent:${doc.title}`,
2984
+ arguments: []
2985
+ }));
2986
+ return [...skillPrompts, ...agentPrompts];
2987
+ }
2988
+
2989
+ // src/shared/mcp/functions/handle-prompt-get.function.ts
2990
+ function parseAgentMeta(content) {
2991
+ try {
2992
+ const parsed = JSON.parse(content);
2993
+ return {
2994
+ persona: typeof parsed["persona"] === "string" ? parsed["persona"] : ""
2995
+ };
2996
+ } catch {
2997
+ return { persona: "" };
2998
+ }
2999
+ }
3000
+ function buildSkillsText(skillSections) {
3001
+ const lines = [];
3002
+ for (const sec of skillSections) {
3003
+ try {
3004
+ const parsed = JSON.parse(sec.content);
3005
+ const name = typeof parsed["name"] === "string" ? parsed["name"] : null;
3006
+ if (name === null) {
3007
+ continue;
3008
+ }
3009
+ const description = typeof parsed["description"] === "string" ? parsed["description"] : "";
3010
+ lines.push(`- ${name}: ${description}`);
3011
+ } catch {
3012
+ }
3013
+ }
3014
+ if (lines.length === 0) {
3015
+ return null;
3016
+ }
3017
+ return `Available skills:
3018
+ ${lines.join("\n")}`;
3019
+ }
3020
+ async function handleAgentPrompt(name, client) {
3021
+ const docid = name.slice(6);
3022
+ const doc = await client.retrieveDocument(docid);
3023
+ const sections = doc.sections;
3024
+ const metaSection = sections.at(0);
3025
+ const skillRefs = sections.slice(1);
3026
+ let persona = "";
3027
+ if (metaSection !== void 0) {
3028
+ const metaSections = await client.readSections([
3029
+ metaSection.kbid
3030
+ ]);
3031
+ const metaContent = metaSections.at(0);
3032
+ if (metaContent !== void 0) {
3033
+ persona = parseAgentMeta(metaContent.content).persona;
3034
+ }
3035
+ }
3036
+ const messages = [
3037
+ {
3038
+ role: "assistant",
3039
+ content: { type: "text", text: persona }
3040
+ }
3041
+ ];
3042
+ if (skillRefs.length === 0) {
3043
+ return messages;
3044
+ }
3045
+ const skillKbids = skillRefs.map((s) => s.kbid);
3046
+ const skillSections = await client.readSections(skillKbids);
3047
+ const skillsText = buildSkillsText(skillSections);
3048
+ if (skillsText !== null) {
3049
+ messages.push({
3050
+ role: "user",
3051
+ content: { type: "text", text: skillsText }
3052
+ });
3053
+ }
3054
+ return messages;
3055
+ }
3056
+ async function handleSkillPrompt(name, promptArgs, client) {
3057
+ const sections = await client.listByType("skill");
3058
+ let matchContent;
3059
+ for (const sec of sections) {
3060
+ if (sec.title === name) {
3061
+ matchContent = sec.content;
3062
+ }
3063
+ }
3064
+ if (matchContent === void 0) {
3065
+ throw new Error(`Prompt not found: ${name}`);
3066
+ }
3067
+ const parsed = JSON.parse(matchContent);
3068
+ const body = typeof parsed["body"] === "string" ? parsed["body"] : "";
3069
+ const rendered = body.replace(
3070
+ /\{\{(\w+)\}\}/g,
3071
+ (_match, key) => key in promptArgs ? promptArgs[key] ?? _match : _match
3072
+ );
3073
+ return [
3074
+ {
3075
+ role: "user",
3076
+ content: { type: "text", text: rendered }
3077
+ }
3078
+ ];
3079
+ }
3080
+ async function handlePromptGet(name, promptArgs, client) {
3081
+ if (name.startsWith("agent:")) {
3082
+ return handleAgentPrompt(name, client);
3083
+ }
3084
+ return handleSkillPrompt(name, promptArgs, client);
3085
+ }
3086
+
3087
+ // src/shared/mcp/functions/handle-completion.function.ts
3088
+ async function handleCompletion(ref, argument, client) {
3089
+ if (ref.type !== "ref/prompt") {
3090
+ return { completion: { values: [], hasMore: false, total: 0 } };
3091
+ }
3092
+ const [skills, agents] = await Promise.all([
3093
+ client.listByType("skill"),
3094
+ client.listDocumentsByType("agent")
3095
+ ]);
3096
+ const names = [];
3097
+ for (const skill of skills) {
3098
+ if (skill.title !== null) {
3099
+ names.push(skill.title);
3100
+ }
3101
+ }
3102
+ for (const agent of agents) {
3103
+ names.push(`agent:${agent.title}`);
3104
+ }
3105
+ const prefix = argument.value;
3106
+ function matchesPrefix(candidate) {
3107
+ if (prefix.length === 0) {
3108
+ return true;
3109
+ }
3110
+ if (candidate.startsWith(prefix)) {
3111
+ return true;
3112
+ }
3113
+ const AGENT_PREFIX = "agent:";
3114
+ if (candidate.startsWith(AGENT_PREFIX)) {
3115
+ return candidate.slice(AGENT_PREFIX.length).startsWith(prefix);
3116
+ }
3117
+ return false;
3118
+ }
3119
+ const values = names.filter(matchesPrefix);
3120
+ return {
3121
+ completion: {
3122
+ values,
3123
+ hasMore: false,
3124
+ total: values.length
3125
+ }
3126
+ };
3127
+ }
3128
+
3129
+ // src/shared/mcp/functions/handle-roots-list.function.ts
3130
+ function handleRootsList(contextPath) {
3131
+ return [
3132
+ {
3133
+ uri: `file://${contextPath}`,
3134
+ name: "kbdb database"
3135
+ }
3136
+ ];
3137
+ }
3138
+
3139
+ // src/shared/mcp/functions/should-emit-log.function.ts
3140
+ var LOG_LEVEL_ORDER = [
3141
+ "debug",
3142
+ "info",
3143
+ "notice",
3144
+ "warning",
3145
+ "error",
3146
+ "critical",
3147
+ "alert",
3148
+ "emergency"
3149
+ ];
3150
+ function shouldEmitLog(messageLevel, threshold) {
3151
+ const messageIndex = LOG_LEVEL_ORDER.indexOf(messageLevel);
3152
+ const thresholdIndex = LOG_LEVEL_ORDER.indexOf(threshold);
3153
+ return messageIndex >= thresholdIndex;
3154
+ }
3155
+
3156
+ // src/shared/mcp/constants/mcp-error-codes.constant.ts
3157
+ var PARSE_ERROR = -32700;
3158
+ var METHOD_NOT_FOUND = -32601;
3159
+ var RESOURCE_NOT_FOUND = -32002;
3160
+
3161
+ // src/shared/mcp/classes/mcp-server.class.ts
3162
+ var McpServer = class {
3163
+ client;
3164
+ contextPath;
3165
+ initialized = false;
3166
+ hostCapabilities = null;
3167
+ logLevel = null;
3168
+ subscriptions = /* @__PURE__ */ new Set();
3169
+ nextRequestId = 1;
3170
+ pendingRequests = /* @__PURE__ */ new Map();
3171
+ constructor(client, contextPath) {
3172
+ this.client = client;
3173
+ this.contextPath = contextPath ?? "";
3174
+ }
3175
+ async listen() {
3176
+ const rl = createInterface2({
3177
+ input: process.stdin,
3178
+ terminal: false
3179
+ });
3180
+ await new Promise((resolve4) => {
3181
+ rl.on("line", (line) => {
3182
+ void this.dispatchLine(line);
3183
+ });
3184
+ rl.on("close", () => {
3185
+ this.client.disconnect();
3186
+ resolve4();
3187
+ });
3188
+ });
3189
+ }
3190
+ async handleLineForTest(line) {
3191
+ return this.processLine(line);
3192
+ }
3193
+ /**
3194
+ * Sends a JSON-RPC notification (no `id`, no response
3195
+ * expected) to stdout.
3196
+ */
3197
+ notify(method, params) {
3198
+ const notification = {
3199
+ jsonrpc: "2.0",
3200
+ method
3201
+ };
3202
+ if (params !== void 0) {
3203
+ notification["params"] = params;
3204
+ }
3205
+ process.stdout.write(JSON.stringify(notification) + "\n");
3206
+ }
3207
+ /**
3208
+ * Emits a log notification if the message severity meets or
3209
+ * exceeds the configured log level threshold.
3210
+ */
3211
+ log(level, message, logger) {
3212
+ if (this.logLevel === null) return;
3213
+ if (!shouldEmitLog(level, this.logLevel)) return;
3214
+ this.notify("notifications/message", {
3215
+ level,
3216
+ logger: logger ?? "kbdb",
3217
+ data: message
3218
+ });
3219
+ }
3220
+ /**
3221
+ * Sends a JSON-RPC request to the host (server-to-client)
3222
+ * and returns a Promise that resolves with the response
3223
+ * result. Times out after 30 seconds.
3224
+ */
3225
+ sendRequest(method, params) {
3226
+ const id = this.nextRequestId++;
3227
+ const request = { jsonrpc: "2.0", id, method, params };
3228
+ process.stdout.write(JSON.stringify(request) + "\n");
3229
+ return new Promise((resolve4, reject) => {
3230
+ const timer = setTimeout(() => {
3231
+ this.pendingRequests.delete(id);
3232
+ reject(new Error(`Request ${method} timed out`));
3233
+ }, 3e4);
3234
+ this.pendingRequests.set(id, {
3235
+ resolve: resolve4,
3236
+ reject,
3237
+ timer
3238
+ });
3239
+ });
3240
+ }
3241
+ /**
3242
+ * Requests the host to generate text via the sampling
3243
+ * capability. Throws if the host did not advertise sampling
3244
+ * support during initialization.
3245
+ */
3246
+ async requestSampling(messages, maxTokens) {
3247
+ if (!this.hostCapabilities?.["sampling"]) {
3248
+ throw new Error("Host does not support sampling");
3249
+ }
3250
+ return this.sendRequest("sampling/createMessage", {
3251
+ messages,
3252
+ maxTokens
3253
+ });
3254
+ }
3255
+ async dispatchLine(line) {
3256
+ const response = await this.processLine(line);
3257
+ if (response !== null) {
3258
+ this.send(response);
3259
+ }
3260
+ }
3261
+ async processLine(line) {
3262
+ if (!line.trim()) return null;
3263
+ let parsed;
3264
+ try {
3265
+ parsed = JSON.parse(line);
3266
+ } catch {
3267
+ return {
3268
+ jsonrpc: "2.0",
3269
+ id: 0,
3270
+ error: {
3271
+ code: PARSE_ERROR,
3272
+ message: "Parse error"
3273
+ }
3274
+ };
3275
+ }
3276
+ if (parsed["id"] !== void 0 && typeof parsed["method"] !== "string") {
3277
+ const responseId = parsed["id"];
3278
+ const pending = this.pendingRequests.get(responseId);
3279
+ if (pending) {
3280
+ this.pendingRequests.delete(responseId);
3281
+ clearTimeout(pending.timer);
3282
+ if (parsed["error"]) {
3283
+ const err = parsed["error"];
3284
+ pending.reject(
3285
+ new Error(err.message ?? "Request failed")
3286
+ );
3287
+ } else {
3288
+ pending.resolve(parsed["result"]);
3289
+ }
3290
+ }
3291
+ return null;
3292
+ }
3293
+ const request = parsed;
3294
+ if (request.id === void 0) {
3295
+ if (request.method === "notifications/initialized" || request.method === "notifications/cancelled") {
3296
+ if (request.method === "notifications/initialized") {
3297
+ this.initialized = true;
3298
+ }
3299
+ }
3300
+ return null;
3301
+ }
3302
+ const id = request.id;
3303
+ if (!this.initialized && request.method !== "initialize" && request.method !== "ping") {
3304
+ return {
3305
+ jsonrpc: "2.0",
3306
+ id,
3307
+ error: {
3308
+ code: RESOURCE_NOT_FOUND,
3309
+ message: "Server not initialized"
3310
+ }
3311
+ };
3312
+ }
3313
+ const response = await this.handleRequest(request);
3314
+ return response;
3315
+ }
3316
+ async handleRequest(request) {
3317
+ const id = request.id;
3318
+ switch (request.method) {
3319
+ case "initialize": {
3320
+ const params = request.params ?? {};
3321
+ const caps = params["capabilities"];
3322
+ this.hostCapabilities = caps ? caps : null;
3323
+ return {
3324
+ jsonrpc: "2.0",
3325
+ id,
3326
+ result: {
3327
+ protocolVersion: "2025-11-25",
3328
+ serverInfo: {
3329
+ name: "kbdb",
3330
+ version: "0.1.0"
3331
+ },
3332
+ capabilities: {
3333
+ tools: {},
3334
+ resources: { subscribe: true },
3335
+ prompts: {},
3336
+ logging: {},
3337
+ completions: {}
3338
+ }
3339
+ }
3340
+ };
3341
+ }
3342
+ case "ping":
3343
+ return { jsonrpc: "2.0", id, result: {} };
3344
+ case "tools/list":
3345
+ return {
3346
+ jsonrpc: "2.0",
3347
+ id,
3348
+ result: {
3349
+ tools: createToolDefinitions()
3350
+ }
3351
+ };
3352
+ case "resources/list":
3353
+ return {
3354
+ jsonrpc: "2.0",
3355
+ id,
3356
+ result: { resources: [] }
3357
+ };
3358
+ case "resources/templates/list":
3359
+ return {
3360
+ jsonrpc: "2.0",
3361
+ id,
3362
+ result: {
3363
+ resourceTemplates: createResourceTemplates()
3364
+ }
3365
+ };
3366
+ case "tools/call": {
3367
+ const params = request.params ?? {};
3368
+ const rawName = params["name"];
3369
+ const name = typeof rawName === "string" ? rawName : "";
3370
+ const args = params["arguments"] ?? {};
3371
+ const result = await handleToolCall(
3372
+ this.client,
3373
+ name,
3374
+ args
3375
+ );
3376
+ return { jsonrpc: "2.0", id, result };
3377
+ }
3378
+ case "resources/read": {
3379
+ const params = request.params ?? {};
3380
+ const rawUri = params["uri"];
3381
+ const uri = typeof rawUri === "string" ? rawUri : "";
3382
+ try {
3383
+ const result = await handleResourceRead(
3384
+ this.client,
3385
+ uri
3386
+ );
3387
+ return { jsonrpc: "2.0", id, result };
3388
+ } catch (err) {
3389
+ return {
3390
+ jsonrpc: "2.0",
3391
+ id,
3392
+ error: {
3393
+ code: RESOURCE_NOT_FOUND,
3394
+ message: err instanceof Error ? err.message : String(err)
3395
+ }
3396
+ };
3397
+ }
3398
+ }
3399
+ case "prompts/list": {
3400
+ const skills = await this.client.listByType("skill");
3401
+ const agents = await this.client.listDocumentsByType("agent");
3402
+ const prompts = createPromptDefinitions(skills, agents);
3403
+ return {
3404
+ jsonrpc: "2.0",
3405
+ id,
3406
+ result: { prompts }
3407
+ };
3408
+ }
3409
+ case "prompts/get": {
3410
+ const params = request.params ?? {};
3411
+ const name = typeof params["name"] === "string" ? params["name"] : "";
3412
+ const promptArgs = params["arguments"] ?? {};
3413
+ try {
3414
+ const messages = await handlePromptGet(
3415
+ name,
3416
+ promptArgs,
3417
+ this.client
3418
+ );
3419
+ return {
3420
+ jsonrpc: "2.0",
3421
+ id,
3422
+ result: { messages }
3423
+ };
3424
+ } catch (err) {
3425
+ return {
3426
+ jsonrpc: "2.0",
3427
+ id,
3428
+ error: {
3429
+ code: RESOURCE_NOT_FOUND,
3430
+ message: err instanceof Error ? err.message : String(err)
3431
+ }
3432
+ };
3433
+ }
3434
+ }
3435
+ case "completion/complete": {
3436
+ const params = request.params ?? {};
3437
+ const ref = params["ref"];
3438
+ const argument = params["argument"] ?? {
3439
+ name: "",
3440
+ value: ""
3441
+ };
3442
+ const result = await handleCompletion(
3443
+ ref,
3444
+ argument,
3445
+ this.client
3446
+ );
3447
+ return { jsonrpc: "2.0", id, result };
3448
+ }
3449
+ case "roots/list": {
3450
+ const roots = handleRootsList(this.contextPath);
3451
+ return {
3452
+ jsonrpc: "2.0",
3453
+ id,
3454
+ result: { roots }
3455
+ };
3456
+ }
3457
+ case "logging/setLevel": {
3458
+ const params = request.params ?? {};
3459
+ const level = params["level"];
3460
+ this.logLevel = level ?? null;
3461
+ return { jsonrpc: "2.0", id, result: {} };
3462
+ }
3463
+ case "resources/subscribe": {
3464
+ const params = request.params ?? {};
3465
+ const uri = typeof params["uri"] === "string" ? params["uri"] : "";
3466
+ this.subscriptions.add(uri);
3467
+ return { jsonrpc: "2.0", id, result: {} };
3468
+ }
3469
+ case "resources/unsubscribe": {
3470
+ const params = request.params ?? {};
3471
+ const uri = typeof params["uri"] === "string" ? params["uri"] : "";
3472
+ this.subscriptions.delete(uri);
3473
+ return { jsonrpc: "2.0", id, result: {} };
3474
+ }
3475
+ default:
3476
+ return {
3477
+ jsonrpc: "2.0",
3478
+ id,
3479
+ error: {
3480
+ code: METHOD_NOT_FOUND,
3481
+ message: `Method not found: ` + request.method
3482
+ }
3483
+ };
3484
+ }
3485
+ }
3486
+ send(response) {
3487
+ const json = JSON.stringify(response);
3488
+ process.stdout.write(json + "\n");
3489
+ }
3490
+ };
3491
+
3492
+ // src/shared/mcp/functions/create-mcp-server.function.ts
3493
+ function createMcpServer(client) {
3494
+ return new McpServer(client);
3495
+ }
3496
+
3497
+ // src/cli.ts
3498
+ var runtime = detectRuntime();
3499
+ var baseDir = resolveBaseDir(import.meta.url, import.meta.dirname);
3500
+ var workerScript = resolveWorkerScript(baseDir.scriptDir, runtime);
3501
+ var deps = {
3502
+ isStdinTty,
3503
+ promptUser,
3504
+ createWorkerClient: (opts) => createWorkerClient({ ...opts, workerScript }),
3505
+ findDb,
3506
+ runInit,
3507
+ startMcpServer: async (contextPath) => {
3508
+ const client = await createWorkerClient({
3509
+ contextPath,
3510
+ workerScript
3511
+ });
3512
+ try {
3513
+ const server = createMcpServer(client);
3514
+ await server.listen();
3515
+ } finally {
3516
+ client.disconnect();
3517
+ }
3518
+ }
3519
+ };
3520
+ async function main() {
3521
+ const result = await runCli(getArgs(), deps);
3522
+ if (result.output) {
3523
+ console.log(result.output);
3524
+ }
3525
+ if (result.error) {
3526
+ console.error(result.error);
3527
+ }
3528
+ if (result.exitCode !== 0) {
3529
+ process.exitCode = result.exitCode;
3530
+ }
3531
+ }
3532
+ main().catch((err) => {
3533
+ const msg = err instanceof Error ? err.message : String(err);
3534
+ console.error(`error: ${msg}`);
3535
+ process.exitCode = 1;
3536
+ });
3537
+ //# sourceMappingURL=cli.mjs.map