bikky 0.3.13 → 0.4.1

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 (362) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/CODE_OF_CONDUCT.md +80 -0
  3. package/CONTRIBUTING.md +206 -0
  4. package/README.md +94 -20
  5. package/SECURITY.md +58 -0
  6. package/SUPPORT.md +22 -0
  7. package/dist/config.d.ts +68 -1
  8. package/dist/config.js +197 -4
  9. package/dist/daemon/extraction.d.ts +12 -2
  10. package/dist/daemon/extraction.js +85 -133
  11. package/dist/daemon/loop.js +15 -1
  12. package/dist/daemon/qdrant.js +0 -1
  13. package/dist/daemon/transcript-sources.d.ts +26 -0
  14. package/dist/daemon/transcript-sources.js +193 -0
  15. package/dist/daemon/watcher.d.ts +3 -2
  16. package/dist/daemon/watcher.js +51 -2
  17. package/dist/install.d.ts +9 -1
  18. package/dist/install.js +62 -34
  19. package/dist/lib/qdrant-pool.d.ts +57 -0
  20. package/dist/lib/qdrant-pool.js +104 -0
  21. package/dist/mcp/api.d.ts +57 -19
  22. package/dist/mcp/api.js +134 -72
  23. package/dist/mcp/helpers.d.ts +0 -1
  24. package/dist/mcp/helpers.js +2 -15
  25. package/dist/mcp/index.js +29 -14
  26. package/dist/mcp/tools.d.ts +0 -7
  27. package/dist/mcp/tools.js +618 -276
  28. package/dist/mcp/types.d.ts +0 -3
  29. package/dist/routing.d.ts +53 -0
  30. package/dist/routing.js +129 -0
  31. package/dist/search-scope.d.ts +24 -0
  32. package/dist/search-scope.js +174 -0
  33. package/docs/config/fully-hosted.md +57 -0
  34. package/docs/config/hosted-models.md +50 -0
  35. package/docs/config/hosted-qdrant-local-models.md +39 -0
  36. package/docs/config/local.md +34 -0
  37. package/docs/configuration.md +403 -0
  38. package/docs/privacy-first.md +140 -0
  39. package/docs/screenshots/dashboard.png +0 -0
  40. package/docs/screenshots/graph.png +0 -0
  41. package/docs/screenshots/memory.png +0 -0
  42. package/package.json +28 -7
  43. package/dist/cli.d.ts.map +0 -1
  44. package/dist/cli.js.map +0 -1
  45. package/dist/config.d.ts.map +0 -1
  46. package/dist/config.js.map +0 -1
  47. package/dist/config.test.d.ts +0 -9
  48. package/dist/config.test.d.ts.map +0 -1
  49. package/dist/config.test.js +0 -576
  50. package/dist/config.test.js.map +0 -1
  51. package/dist/daemon/capture-policy.d.ts.map +0 -1
  52. package/dist/daemon/capture-policy.js.map +0 -1
  53. package/dist/daemon/capture-policy.test.d.ts +0 -2
  54. package/dist/daemon/capture-policy.test.d.ts.map +0 -1
  55. package/dist/daemon/capture-policy.test.js +0 -48
  56. package/dist/daemon/capture-policy.test.js.map +0 -1
  57. package/dist/daemon/consolidation.d.ts.map +0 -1
  58. package/dist/daemon/consolidation.js.map +0 -1
  59. package/dist/daemon/entity-typing.d.ts.map +0 -1
  60. package/dist/daemon/entity-typing.js.map +0 -1
  61. package/dist/daemon/entity-typing.test.d.ts +0 -2
  62. package/dist/daemon/entity-typing.test.d.ts.map +0 -1
  63. package/dist/daemon/entity-typing.test.js +0 -50
  64. package/dist/daemon/entity-typing.test.js.map +0 -1
  65. package/dist/daemon/episode-summary.d.ts.map +0 -1
  66. package/dist/daemon/episode-summary.js.map +0 -1
  67. package/dist/daemon/episode-summary.test.d.ts +0 -2
  68. package/dist/daemon/episode-summary.test.d.ts.map +0 -1
  69. package/dist/daemon/episode-summary.test.js +0 -104
  70. package/dist/daemon/episode-summary.test.js.map +0 -1
  71. package/dist/daemon/extraction-quality.test.d.ts +0 -2
  72. package/dist/daemon/extraction-quality.test.d.ts.map +0 -1
  73. package/dist/daemon/extraction-quality.test.js +0 -283
  74. package/dist/daemon/extraction-quality.test.js.map +0 -1
  75. package/dist/daemon/extraction-rules.d.ts.map +0 -1
  76. package/dist/daemon/extraction-rules.js.map +0 -1
  77. package/dist/daemon/extraction-rules.test.d.ts +0 -2
  78. package/dist/daemon/extraction-rules.test.d.ts.map +0 -1
  79. package/dist/daemon/extraction-rules.test.js +0 -203
  80. package/dist/daemon/extraction-rules.test.js.map +0 -1
  81. package/dist/daemon/extraction.d.ts.map +0 -1
  82. package/dist/daemon/extraction.js.map +0 -1
  83. package/dist/daemon/extraction.test.d.ts +0 -2
  84. package/dist/daemon/extraction.test.d.ts.map +0 -1
  85. package/dist/daemon/extraction.test.js +0 -225
  86. package/dist/daemon/extraction.test.js.map +0 -1
  87. package/dist/daemon/index.d.ts.map +0 -1
  88. package/dist/daemon/index.js.map +0 -1
  89. package/dist/daemon/loop.d.ts.map +0 -1
  90. package/dist/daemon/loop.js.map +0 -1
  91. package/dist/daemon/loop.test.d.ts +0 -2
  92. package/dist/daemon/loop.test.d.ts.map +0 -1
  93. package/dist/daemon/loop.test.js +0 -85
  94. package/dist/daemon/loop.test.js.map +0 -1
  95. package/dist/daemon/maintenance-state.d.ts.map +0 -1
  96. package/dist/daemon/maintenance-state.js.map +0 -1
  97. package/dist/daemon/maintenance-state.test.d.ts +0 -2
  98. package/dist/daemon/maintenance-state.test.d.ts.map +0 -1
  99. package/dist/daemon/maintenance-state.test.js +0 -56
  100. package/dist/daemon/maintenance-state.test.js.map +0 -1
  101. package/dist/daemon/qdrant.d.ts.map +0 -1
  102. package/dist/daemon/qdrant.js.map +0 -1
  103. package/dist/daemon/qdrant.test.d.ts +0 -8
  104. package/dist/daemon/qdrant.test.d.ts.map +0 -1
  105. package/dist/daemon/qdrant.test.js +0 -265
  106. package/dist/daemon/qdrant.test.js.map +0 -1
  107. package/dist/daemon/relations-vocab.d.ts.map +0 -1
  108. package/dist/daemon/relations-vocab.js.map +0 -1
  109. package/dist/daemon/relations-vocab.test.d.ts +0 -2
  110. package/dist/daemon/relations-vocab.test.d.ts.map +0 -1
  111. package/dist/daemon/relations-vocab.test.js +0 -69
  112. package/dist/daemon/relations-vocab.test.js.map +0 -1
  113. package/dist/daemon/relations.d.ts.map +0 -1
  114. package/dist/daemon/relations.js.map +0 -1
  115. package/dist/daemon/relations.test.d.ts +0 -2
  116. package/dist/daemon/relations.test.d.ts.map +0 -1
  117. package/dist/daemon/relations.test.js +0 -36
  118. package/dist/daemon/relations.test.js.map +0 -1
  119. package/dist/daemon/session-index.d.ts.map +0 -1
  120. package/dist/daemon/session-index.js.map +0 -1
  121. package/dist/daemon/session-index.test.d.ts +0 -2
  122. package/dist/daemon/session-index.test.d.ts.map +0 -1
  123. package/dist/daemon/session-index.test.js +0 -60
  124. package/dist/daemon/session-index.test.js.map +0 -1
  125. package/dist/daemon/session-summary.d.ts.map +0 -1
  126. package/dist/daemon/session-summary.js.map +0 -1
  127. package/dist/daemon/session-summary.test.d.ts +0 -2
  128. package/dist/daemon/session-summary.test.d.ts.map +0 -1
  129. package/dist/daemon/session-summary.test.js +0 -162
  130. package/dist/daemon/session-summary.test.js.map +0 -1
  131. package/dist/daemon/staleness.d.ts.map +0 -1
  132. package/dist/daemon/staleness.js.map +0 -1
  133. package/dist/daemon/staleness.test.d.ts +0 -7
  134. package/dist/daemon/staleness.test.d.ts.map +0 -1
  135. package/dist/daemon/staleness.test.js +0 -128
  136. package/dist/daemon/staleness.test.js.map +0 -1
  137. package/dist/daemon/watcher-health.d.ts.map +0 -1
  138. package/dist/daemon/watcher-health.js.map +0 -1
  139. package/dist/daemon/watcher-health.test.d.ts +0 -5
  140. package/dist/daemon/watcher-health.test.d.ts.map +0 -1
  141. package/dist/daemon/watcher-health.test.js +0 -119
  142. package/dist/daemon/watcher-health.test.js.map +0 -1
  143. package/dist/daemon/watcher.d.ts.map +0 -1
  144. package/dist/daemon/watcher.js.map +0 -1
  145. package/dist/daemon/watcher.test.d.ts +0 -9
  146. package/dist/daemon/watcher.test.d.ts.map +0 -1
  147. package/dist/daemon/watcher.test.js +0 -204
  148. package/dist/daemon/watcher.test.js.map +0 -1
  149. package/dist/daemon/workstream-resolver.d.ts.map +0 -1
  150. package/dist/daemon/workstream-resolver.js.map +0 -1
  151. package/dist/daemon/workstream-resolver.test.d.ts +0 -2
  152. package/dist/daemon/workstream-resolver.test.d.ts.map +0 -1
  153. package/dist/daemon/workstream-resolver.test.js +0 -128
  154. package/dist/daemon/workstream-resolver.test.js.map +0 -1
  155. package/dist/daemon/workstream-summary.d.ts.map +0 -1
  156. package/dist/daemon/workstream-summary.js.map +0 -1
  157. package/dist/daemon/workstream-summary.test.d.ts +0 -2
  158. package/dist/daemon/workstream-summary.test.d.ts.map +0 -1
  159. package/dist/daemon/workstream-summary.test.js +0 -89
  160. package/dist/daemon/workstream-summary.test.js.map +0 -1
  161. package/dist/install.d.ts.map +0 -1
  162. package/dist/install.js.map +0 -1
  163. package/dist/install.test.d.ts +0 -9
  164. package/dist/install.test.d.ts.map +0 -1
  165. package/dist/install.test.js +0 -126
  166. package/dist/install.test.js.map +0 -1
  167. package/dist/lib/qdrant-client.d.ts.map +0 -1
  168. package/dist/lib/qdrant-client.js.map +0 -1
  169. package/dist/lib/qdrant-client.test.d.ts +0 -8
  170. package/dist/lib/qdrant-client.test.d.ts.map +0 -1
  171. package/dist/lib/qdrant-client.test.js +0 -274
  172. package/dist/lib/qdrant-client.test.js.map +0 -1
  173. package/dist/lifecycle.d.ts.map +0 -1
  174. package/dist/lifecycle.js.map +0 -1
  175. package/dist/lifecycle.test.d.ts +0 -8
  176. package/dist/lifecycle.test.d.ts.map +0 -1
  177. package/dist/lifecycle.test.js +0 -74
  178. package/dist/lifecycle.test.js.map +0 -1
  179. package/dist/llm/embedding/index.d.ts.map +0 -1
  180. package/dist/llm/embedding/index.js.map +0 -1
  181. package/dist/llm/embedding/index.test.d.ts +0 -8
  182. package/dist/llm/embedding/index.test.d.ts.map +0 -1
  183. package/dist/llm/embedding/index.test.js +0 -100
  184. package/dist/llm/embedding/index.test.js.map +0 -1
  185. package/dist/llm/embedding/providers/bedrock.d.ts.map +0 -1
  186. package/dist/llm/embedding/providers/bedrock.js.map +0 -1
  187. package/dist/llm/embedding/providers/bedrock.test.d.ts +0 -2
  188. package/dist/llm/embedding/providers/bedrock.test.d.ts.map +0 -1
  189. package/dist/llm/embedding/providers/bedrock.test.js +0 -24
  190. package/dist/llm/embedding/providers/bedrock.test.js.map +0 -1
  191. package/dist/llm/embedding/providers/index.d.ts.map +0 -1
  192. package/dist/llm/embedding/providers/index.js.map +0 -1
  193. package/dist/llm/embedding/providers/ollama.d.ts.map +0 -1
  194. package/dist/llm/embedding/providers/ollama.js.map +0 -1
  195. package/dist/llm/embedding/providers/ollama.test.d.ts +0 -2
  196. package/dist/llm/embedding/providers/ollama.test.d.ts.map +0 -1
  197. package/dist/llm/embedding/providers/ollama.test.js +0 -54
  198. package/dist/llm/embedding/providers/ollama.test.js.map +0 -1
  199. package/dist/llm/embedding/providers/openai.d.ts.map +0 -1
  200. package/dist/llm/embedding/providers/openai.js.map +0 -1
  201. package/dist/llm/embedding/providers/openai.test.d.ts +0 -2
  202. package/dist/llm/embedding/providers/openai.test.d.ts.map +0 -1
  203. package/dist/llm/embedding/providers/openai.test.js +0 -48
  204. package/dist/llm/embedding/providers/openai.test.js.map +0 -1
  205. package/dist/llm/embedding/providers/portkey.d.ts.map +0 -1
  206. package/dist/llm/embedding/providers/portkey.js.map +0 -1
  207. package/dist/llm/embedding/providers/portkey.test.d.ts +0 -2
  208. package/dist/llm/embedding/providers/portkey.test.d.ts.map +0 -1
  209. package/dist/llm/embedding/providers/portkey.test.js +0 -56
  210. package/dist/llm/embedding/providers/portkey.test.js.map +0 -1
  211. package/dist/llm/embedding/registry.d.ts.map +0 -1
  212. package/dist/llm/embedding/registry.js.map +0 -1
  213. package/dist/llm/embedding/registry.test.d.ts +0 -7
  214. package/dist/llm/embedding/registry.test.d.ts.map +0 -1
  215. package/dist/llm/embedding/registry.test.js +0 -68
  216. package/dist/llm/embedding/registry.test.js.map +0 -1
  217. package/dist/llm/embedding/types.d.ts.map +0 -1
  218. package/dist/llm/embedding/types.js.map +0 -1
  219. package/dist/llm/errors.d.ts.map +0 -1
  220. package/dist/llm/errors.js.map +0 -1
  221. package/dist/llm/errors.test.d.ts +0 -2
  222. package/dist/llm/errors.test.d.ts.map +0 -1
  223. package/dist/llm/errors.test.js +0 -103
  224. package/dist/llm/errors.test.js.map +0 -1
  225. package/dist/llm/fetch.d.ts.map +0 -1
  226. package/dist/llm/fetch.js.map +0 -1
  227. package/dist/llm/index.d.ts.map +0 -1
  228. package/dist/llm/index.js.map +0 -1
  229. package/dist/llm/inference/index.d.ts.map +0 -1
  230. package/dist/llm/inference/index.js.map +0 -1
  231. package/dist/llm/inference/index.test.d.ts +0 -6
  232. package/dist/llm/inference/index.test.d.ts.map +0 -1
  233. package/dist/llm/inference/index.test.js +0 -150
  234. package/dist/llm/inference/index.test.js.map +0 -1
  235. package/dist/llm/inference/providers/bedrock.d.ts.map +0 -1
  236. package/dist/llm/inference/providers/bedrock.js.map +0 -1
  237. package/dist/llm/inference/providers/bedrock.test.d.ts +0 -2
  238. package/dist/llm/inference/providers/bedrock.test.d.ts.map +0 -1
  239. package/dist/llm/inference/providers/bedrock.test.js +0 -68
  240. package/dist/llm/inference/providers/bedrock.test.js.map +0 -1
  241. package/dist/llm/inference/providers/index.d.ts.map +0 -1
  242. package/dist/llm/inference/providers/index.js.map +0 -1
  243. package/dist/llm/inference/providers/ollama.d.ts.map +0 -1
  244. package/dist/llm/inference/providers/ollama.js.map +0 -1
  245. package/dist/llm/inference/providers/ollama.test.d.ts +0 -2
  246. package/dist/llm/inference/providers/ollama.test.d.ts.map +0 -1
  247. package/dist/llm/inference/providers/ollama.test.js +0 -57
  248. package/dist/llm/inference/providers/ollama.test.js.map +0 -1
  249. package/dist/llm/inference/providers/openai.d.ts.map +0 -1
  250. package/dist/llm/inference/providers/openai.js.map +0 -1
  251. package/dist/llm/inference/providers/openai.test.d.ts +0 -2
  252. package/dist/llm/inference/providers/openai.test.d.ts.map +0 -1
  253. package/dist/llm/inference/providers/openai.test.js +0 -82
  254. package/dist/llm/inference/providers/openai.test.js.map +0 -1
  255. package/dist/llm/inference/providers/portkey.d.ts.map +0 -1
  256. package/dist/llm/inference/providers/portkey.js.map +0 -1
  257. package/dist/llm/inference/providers/portkey.test.d.ts +0 -2
  258. package/dist/llm/inference/providers/portkey.test.d.ts.map +0 -1
  259. package/dist/llm/inference/providers/portkey.test.js +0 -48
  260. package/dist/llm/inference/providers/portkey.test.js.map +0 -1
  261. package/dist/llm/inference/registry.d.ts.map +0 -1
  262. package/dist/llm/inference/registry.js.map +0 -1
  263. package/dist/llm/inference/registry.test.d.ts +0 -6
  264. package/dist/llm/inference/registry.test.d.ts.map +0 -1
  265. package/dist/llm/inference/registry.test.js +0 -63
  266. package/dist/llm/inference/registry.test.js.map +0 -1
  267. package/dist/llm/inference/types.d.ts.map +0 -1
  268. package/dist/llm/inference/types.js.map +0 -1
  269. package/dist/llm/telemetry.d.ts.map +0 -1
  270. package/dist/llm/telemetry.js.map +0 -1
  271. package/dist/llm/telemetry.test.d.ts +0 -5
  272. package/dist/llm/telemetry.test.d.ts.map +0 -1
  273. package/dist/llm/telemetry.test.js +0 -89
  274. package/dist/llm/telemetry.test.js.map +0 -1
  275. package/dist/llm/types.d.ts.map +0 -1
  276. package/dist/llm/types.js.map +0 -1
  277. package/dist/logger.d.ts.map +0 -1
  278. package/dist/logger.js.map +0 -1
  279. package/dist/logger.test.d.ts +0 -5
  280. package/dist/logger.test.d.ts.map +0 -1
  281. package/dist/logger.test.js +0 -103
  282. package/dist/logger.test.js.map +0 -1
  283. package/dist/mcp/api.d.ts.map +0 -1
  284. package/dist/mcp/api.js.map +0 -1
  285. package/dist/mcp/api.test.d.ts +0 -6
  286. package/dist/mcp/api.test.d.ts.map +0 -1
  287. package/dist/mcp/api.test.js +0 -130
  288. package/dist/mcp/api.test.js.map +0 -1
  289. package/dist/mcp/helpers.d.ts.map +0 -1
  290. package/dist/mcp/helpers.js.map +0 -1
  291. package/dist/mcp/helpers.test.d.ts +0 -5
  292. package/dist/mcp/helpers.test.d.ts.map +0 -1
  293. package/dist/mcp/helpers.test.js +0 -548
  294. package/dist/mcp/helpers.test.js.map +0 -1
  295. package/dist/mcp/index.d.ts.map +0 -1
  296. package/dist/mcp/index.js.map +0 -1
  297. package/dist/mcp/taxonomy.d.ts.map +0 -1
  298. package/dist/mcp/taxonomy.js.map +0 -1
  299. package/dist/mcp/taxonomy.test.d.ts +0 -5
  300. package/dist/mcp/taxonomy.test.d.ts.map +0 -1
  301. package/dist/mcp/taxonomy.test.js +0 -215
  302. package/dist/mcp/taxonomy.test.js.map +0 -1
  303. package/dist/mcp/tools.d.ts.map +0 -1
  304. package/dist/mcp/tools.integration.itest.d.ts +0 -23
  305. package/dist/mcp/tools.integration.itest.d.ts.map +0 -1
  306. package/dist/mcp/tools.integration.itest.js +0 -171
  307. package/dist/mcp/tools.integration.itest.js.map +0 -1
  308. package/dist/mcp/tools.js.map +0 -1
  309. package/dist/mcp/tools.test.d.ts +0 -16
  310. package/dist/mcp/tools.test.d.ts.map +0 -1
  311. package/dist/mcp/tools.test.js +0 -908
  312. package/dist/mcp/tools.test.js.map +0 -1
  313. package/dist/mcp/types.d.ts.map +0 -1
  314. package/dist/mcp/types.js.map +0 -1
  315. package/dist/postinstall.d.ts.map +0 -1
  316. package/dist/postinstall.js.map +0 -1
  317. package/dist/privacy/redaction.d.ts.map +0 -1
  318. package/dist/privacy/redaction.js.map +0 -1
  319. package/dist/privacy/redaction.test.d.ts +0 -2
  320. package/dist/privacy/redaction.test.d.ts.map +0 -1
  321. package/dist/privacy/redaction.test.js +0 -51
  322. package/dist/privacy/redaction.test.js.map +0 -1
  323. package/dist/prompts/brief.d.ts.map +0 -1
  324. package/dist/prompts/brief.js.map +0 -1
  325. package/dist/prompts/contradiction.d.ts.map +0 -1
  326. package/dist/prompts/contradiction.js.map +0 -1
  327. package/dist/prompts/distill.d.ts.map +0 -1
  328. package/dist/prompts/distill.js.map +0 -1
  329. package/dist/prompts/entity-typing.d.ts.map +0 -1
  330. package/dist/prompts/entity-typing.js.map +0 -1
  331. package/dist/prompts/episode-summary.d.ts.map +0 -1
  332. package/dist/prompts/episode-summary.js.map +0 -1
  333. package/dist/prompts/extraction.d.ts.map +0 -1
  334. package/dist/prompts/extraction.js.map +0 -1
  335. package/dist/prompts/index.d.ts.map +0 -1
  336. package/dist/prompts/index.js.map +0 -1
  337. package/dist/prompts/prompts.test.d.ts +0 -8
  338. package/dist/prompts/prompts.test.d.ts.map +0 -1
  339. package/dist/prompts/prompts.test.js +0 -140
  340. package/dist/prompts/prompts.test.js.map +0 -1
  341. package/dist/prompts/relations.d.ts.map +0 -1
  342. package/dist/prompts/relations.js.map +0 -1
  343. package/dist/prompts/workstream-summary.d.ts.map +0 -1
  344. package/dist/prompts/workstream-summary.js.map +0 -1
  345. package/dist/provenance/actor.d.ts.map +0 -1
  346. package/dist/provenance/actor.js.map +0 -1
  347. package/dist/provenance/actor.test.d.ts +0 -2
  348. package/dist/provenance/actor.test.d.ts.map +0 -1
  349. package/dist/provenance/actor.test.js +0 -49
  350. package/dist/provenance/actor.test.js.map +0 -1
  351. package/dist/render.d.ts.map +0 -1
  352. package/dist/render.js.map +0 -1
  353. package/dist/render.test.d.ts +0 -8
  354. package/dist/render.test.d.ts.map +0 -1
  355. package/dist/render.test.js +0 -244
  356. package/dist/render.test.js.map +0 -1
  357. package/dist/status.d.ts.map +0 -1
  358. package/dist/status.js.map +0 -1
  359. package/dist/status.test.d.ts +0 -5
  360. package/dist/status.test.d.ts.map +0 -1
  361. package/dist/status.test.js +0 -203
  362. package/dist/status.test.js.map +0 -1
package/dist/config.d.ts CHANGED
@@ -76,11 +76,67 @@ export interface WatcherConfig {
76
76
  path: string;
77
77
  };
78
78
  }
79
+ /**
80
+ * One Qdrant routing target. Each destination is fully self-contained: its own
81
+ * URL, API key, collection name, and match rules. All fields in `match` are
82
+ * arrays of regex strings; OR semantics within a destination's match block,
83
+ * first-match-wins across destinations.
84
+ */
85
+ export interface DestinationMatch {
86
+ /** Match against `process.cwd()`. */
87
+ cwd?: string[];
88
+ /** Match against any of the input `entities`. */
89
+ entity?: string[];
90
+ /** Match against the input `content`. */
91
+ content?: string[];
92
+ /** Per-key match against the input `metadata`. */
93
+ metadata?: Record<string, string[]>;
94
+ }
95
+ export interface Destination {
96
+ /** Stable, unique name. Used as the `destination` override on tool calls. */
97
+ name: string;
98
+ /** Human-readable guidance for LLMs/users about when to use this destination. */
99
+ description?: string;
100
+ qdrant_url: string;
101
+ qdrant_api_key: string | null;
102
+ collection: string;
103
+ /** Marks this destination as the fallback when no rule matches. */
104
+ default?: boolean;
105
+ /** Routing rules. Omit for a destination that is only reachable by override. */
106
+ match?: DestinationMatch;
107
+ }
108
+ export type SearchScopeTarget = "routed" | "all" | string | string[];
109
+ export interface SearchScopeDefinition {
110
+ /** Stable scope name that MCP clients can pass as `search_scope`. */
111
+ name: string;
112
+ /** Guidance for LLMs/users about when this scope should be used. */
113
+ description: string;
114
+ /** Destination selector: "routed", "all", a destination name, or destination names. */
115
+ destinations: SearchScopeTarget;
116
+ }
79
117
  export interface BikkyConfig {
118
+ /**
119
+ * Top-level Qdrant fields. When `destinations` is empty, a single default
120
+ * destination is synthesized from these — keeps single-Qdrant configs
121
+ * working without changes.
122
+ */
80
123
  qdrant_url: string | null;
81
124
  qdrant_api_key: string | null;
82
125
  collection: string;
83
- default_workspace: string | null;
126
+ /**
127
+ * One or more Qdrant routing targets. Memory operations resolve to a
128
+ * destination via override → cwd/entity/content/metadata regex match →
129
+ * default flag → first entry.
130
+ */
131
+ destinations: Destination[];
132
+ /**
133
+ * Default read/search scope. "routed" preserves historical behavior
134
+ * (one destination via routing rules); "all" fans out to every destination;
135
+ * a destination name or list searches only those destinations.
136
+ */
137
+ default_search_scope: SearchScopeTarget;
138
+ /** Optional named search scopes exposed to MCP clients with descriptions. */
139
+ search_scopes: SearchScopeDefinition[];
84
140
  aws_profile: string | null;
85
141
  embedding: EmbeddingConfig;
86
142
  llm: LLMConfig;
@@ -107,6 +163,17 @@ export declare function validateConfigObject(raw: unknown): ConfigIssue[];
107
163
  export declare function inspectConfigFile(configPath?: string): ConfigFileDiagnostics;
108
164
  export declare function getActiveConfigEnvOverrides(env?: NodeJS.ProcessEnv): string[];
109
165
  export declare function loadConfig(): BikkyConfig;
166
+ /**
167
+ * Resolve the effective list of destinations from the loaded config.
168
+ *
169
+ * - If `destinations` is non-empty, return as-is.
170
+ * - Otherwise synthesize a single fallback destination from the top-level
171
+ * `qdrant_url` / `qdrant_api_key` / `collection` so existing single-Qdrant
172
+ * configs keep working without changes.
173
+ * - If neither is configured, returns an empty array — callers should treat
174
+ * that as "Qdrant not configured" the same way they did before.
175
+ */
176
+ export declare function getEffectiveDestinations(config?: BikkyConfig): Destination[];
110
177
  /** Save config to disk (used by setup command). */
111
178
  export declare function saveConfig(config: BikkyConfig): void;
112
179
  /** Reset cached config (for testing). */
package/dist/config.js CHANGED
@@ -28,7 +28,9 @@ const DEFAULTS = {
28
28
  qdrant_url: null,
29
29
  qdrant_api_key: null,
30
30
  collection: "bikky",
31
- default_workspace: null,
31
+ destinations: [],
32
+ default_search_scope: "routed",
33
+ search_scopes: [],
32
34
  aws_profile: null,
33
35
  embedding: {
34
36
  provider: "ollama",
@@ -176,11 +178,38 @@ const identityConfigFileSchema = z.object({
176
178
  actor_id: z.string().nullable().optional(),
177
179
  actor_label: z.string().nullable().optional(),
178
180
  }).passthrough();
181
+ const regexArrayField = z.array(z.string()).optional();
182
+ const destinationMatchSchema = z.object({
183
+ cwd: regexArrayField,
184
+ entity: regexArrayField,
185
+ content: regexArrayField,
186
+ metadata: z.record(z.array(z.string())).optional(),
187
+ }).passthrough();
188
+ const destinationFileSchema = z.object({
189
+ name: z.string().min(1),
190
+ description: z.string().optional(),
191
+ qdrant_url: z.string().min(1),
192
+ qdrant_api_key: z.string().nullable().optional(),
193
+ collection: z.string().min(1),
194
+ default: z.boolean().optional(),
195
+ match: destinationMatchSchema.optional(),
196
+ }).passthrough();
197
+ const searchScopeTargetSchema = z.union([
198
+ z.string().min(1),
199
+ z.array(z.string().min(1)).min(1),
200
+ ]);
201
+ const searchScopeDefinitionFileSchema = z.object({
202
+ name: z.string().min(1),
203
+ description: z.string().min(1),
204
+ destinations: searchScopeTargetSchema,
205
+ }).passthrough();
179
206
  const configFileSchema = z.object({
180
207
  qdrant_url: z.string().nullable().optional(),
181
208
  qdrant_api_key: z.string().nullable().optional(),
182
209
  collection: z.string().optional(),
183
- default_workspace: z.string().nullable().optional(),
210
+ destinations: z.array(destinationFileSchema).optional(),
211
+ default_search_scope: searchScopeTargetSchema.optional(),
212
+ search_scopes: z.array(searchScopeDefinitionFileSchema).optional(),
184
213
  aws_profile: z.string().nullable().optional(),
185
214
  embedding: embeddingConfigFileSchema.optional(),
186
215
  llm: llmConfigFileSchema.optional(),
@@ -267,6 +296,144 @@ export function validateConfigObject(raw) {
267
296
  });
268
297
  }
269
298
  validateUrlLike(raw.qdrant_url, "qdrant_url", issues);
299
+ // Destinations validation
300
+ if (Array.isArray(raw.destinations)) {
301
+ const seenNames = new Set();
302
+ let defaultCount = 0;
303
+ raw.destinations.forEach((entry, idx) => {
304
+ const base = `destinations[${idx}]`;
305
+ if (!isObject(entry)) {
306
+ issues.push({ severity: "error", path: base, message: "must be an object" });
307
+ return;
308
+ }
309
+ const name = entry.name;
310
+ if (typeof name === "string" && name.trim() !== "") {
311
+ if (seenNames.has(name)) {
312
+ issues.push({ severity: "error", path: `${base}.name`, message: `duplicate destination name '${name}'` });
313
+ }
314
+ seenNames.add(name);
315
+ }
316
+ validateUrlLike(entry.qdrant_url, `${base}.qdrant_url`, issues);
317
+ if (typeof entry.collection === "string" && entry.collection.trim() === "") {
318
+ issues.push({ severity: "error", path: `${base}.collection`, message: "must not be empty" });
319
+ }
320
+ if (entry.default === true)
321
+ defaultCount++;
322
+ const match = childObject(entry, "match");
323
+ if (match) {
324
+ for (const field of ["cwd", "entity", "content"]) {
325
+ const value = match[field];
326
+ if (value === undefined)
327
+ continue;
328
+ if (!Array.isArray(value)) {
329
+ issues.push({ severity: "error", path: `${base}.match.${field}`, message: "must be an array of regex strings" });
330
+ continue;
331
+ }
332
+ value.forEach((pattern, pIdx) => {
333
+ if (typeof pattern !== "string") {
334
+ issues.push({ severity: "error", path: `${base}.match.${field}[${pIdx}]`, message: "must be a string" });
335
+ return;
336
+ }
337
+ try {
338
+ new RegExp(pattern);
339
+ }
340
+ catch (e) {
341
+ issues.push({
342
+ severity: "error",
343
+ path: `${base}.match.${field}[${pIdx}]`,
344
+ message: `invalid regex: ${e instanceof Error ? e.message : String(e)}`,
345
+ });
346
+ }
347
+ });
348
+ }
349
+ const metadata = childObject(match, "metadata");
350
+ if (metadata) {
351
+ for (const [key, value] of Object.entries(metadata)) {
352
+ if (!Array.isArray(value)) {
353
+ issues.push({ severity: "error", path: `${base}.match.metadata.${key}`, message: "must be an array of regex strings" });
354
+ continue;
355
+ }
356
+ value.forEach((pattern, pIdx) => {
357
+ if (typeof pattern !== "string") {
358
+ issues.push({ severity: "error", path: `${base}.match.metadata.${key}[${pIdx}]`, message: "must be a string" });
359
+ return;
360
+ }
361
+ try {
362
+ new RegExp(pattern);
363
+ }
364
+ catch (e) {
365
+ issues.push({
366
+ severity: "error",
367
+ path: `${base}.match.metadata.${key}[${pIdx}]`,
368
+ message: `invalid regex: ${e instanceof Error ? e.message : String(e)}`,
369
+ });
370
+ }
371
+ });
372
+ }
373
+ }
374
+ }
375
+ });
376
+ if (defaultCount > 1) {
377
+ issues.push({ severity: "error", path: "destinations", message: `at most one destination may set 'default: true' (found ${defaultCount})` });
378
+ }
379
+ }
380
+ const destinationNames = new Set();
381
+ if (Array.isArray(raw.destinations)) {
382
+ for (const entry of raw.destinations) {
383
+ if (isObject(entry) && typeof entry.name === "string" && entry.name.trim() !== "") {
384
+ destinationNames.add(entry.name);
385
+ }
386
+ }
387
+ }
388
+ const searchScopeNames = new Set();
389
+ if (Array.isArray(raw.search_scopes)) {
390
+ for (const entry of raw.search_scopes) {
391
+ if (isObject(entry) && typeof entry.name === "string" && entry.name.trim() !== "") {
392
+ searchScopeNames.add(entry.name);
393
+ }
394
+ }
395
+ }
396
+ const validateSearchScopeTarget = (target, pathName) => {
397
+ const values = Array.isArray(target) ? target : [target];
398
+ for (const [idx, value] of values.entries()) {
399
+ const valuePath = Array.isArray(target) ? `${pathName}[${idx}]` : pathName;
400
+ if (typeof value !== "string" || value.trim() === "")
401
+ continue;
402
+ const normalized = value.trim();
403
+ if (normalized === "all" || normalized === "routed" || destinationNames.size === 0)
404
+ continue;
405
+ if (searchScopeNames.has(normalized))
406
+ continue;
407
+ if (!destinationNames.has(normalized)) {
408
+ issues.push({
409
+ severity: "warning",
410
+ path: valuePath,
411
+ message: `references unknown destination '${normalized}'`,
412
+ });
413
+ }
414
+ }
415
+ };
416
+ if (Object.prototype.hasOwnProperty.call(raw, "default_search_scope")) {
417
+ validateSearchScopeTarget(raw.default_search_scope, "default_search_scope");
418
+ }
419
+ if (Array.isArray(raw.search_scopes)) {
420
+ const seenScopeNames = new Set();
421
+ raw.search_scopes.forEach((entry, idx) => {
422
+ const base = `search_scopes[${idx}]`;
423
+ if (!isObject(entry)) {
424
+ issues.push({ severity: "error", path: base, message: "must be an object" });
425
+ return;
426
+ }
427
+ const name = entry.name;
428
+ if (typeof name === "string" && name.trim() !== "") {
429
+ if (seenScopeNames.has(name)) {
430
+ issues.push({ severity: "error", path: `${base}.name`, message: `duplicate search scope name '${name}'` });
431
+ }
432
+ seenScopeNames.add(name);
433
+ }
434
+ validateSearchScopeTarget(entry.destinations, `${base}.destinations`);
435
+ });
436
+ }
270
437
  const embedding = childObject(raw, "embedding");
271
438
  if (embedding)
272
439
  validateUrlLike(embedding.base_url, "embedding.base_url", issues);
@@ -345,8 +512,6 @@ export function loadConfig() {
345
512
  config.qdrant_api_key = process.env.QDRANT_API_KEY;
346
513
  if (process.env.BIKKY_COLLECTION)
347
514
  config.collection = process.env.BIKKY_COLLECTION;
348
- if (process.env.BIKKY_DEFAULT_WORKSPACE)
349
- config.default_workspace = process.env.BIKKY_DEFAULT_WORKSPACE;
350
515
  // Embedding env overrides
351
516
  if (process.env.EMBEDDING_PROVIDER)
352
517
  config.embedding.provider = process.env.EMBEDDING_PROVIDER;
@@ -481,9 +646,37 @@ export function loadConfig() {
481
646
  config.qdrant_url = config.qdrant_url.replace(/\/+$/, "");
482
647
  config.embedding.base_url = config.embedding.base_url.replace(/\/+$/, "");
483
648
  config.llm.base_url = config.llm.base_url.replace(/\/+$/, "");
649
+ for (const dest of config.destinations) {
650
+ if (dest.qdrant_url)
651
+ dest.qdrant_url = dest.qdrant_url.replace(/\/+$/, "");
652
+ }
484
653
  _config = config;
485
654
  return config;
486
655
  }
656
+ /**
657
+ * Resolve the effective list of destinations from the loaded config.
658
+ *
659
+ * - If `destinations` is non-empty, return as-is.
660
+ * - Otherwise synthesize a single fallback destination from the top-level
661
+ * `qdrant_url` / `qdrant_api_key` / `collection` so existing single-Qdrant
662
+ * configs keep working without changes.
663
+ * - If neither is configured, returns an empty array — callers should treat
664
+ * that as "Qdrant not configured" the same way they did before.
665
+ */
666
+ export function getEffectiveDestinations(config = loadConfig()) {
667
+ if (config.destinations.length > 0)
668
+ return config.destinations;
669
+ if (!config.qdrant_url)
670
+ return [];
671
+ return [{
672
+ name: "default",
673
+ description: "Default Qdrant destination synthesized from the top-level qdrant_url, qdrant_api_key, and collection settings.",
674
+ qdrant_url: config.qdrant_url,
675
+ qdrant_api_key: config.qdrant_api_key,
676
+ collection: config.collection,
677
+ default: true,
678
+ }];
679
+ }
487
680
  /** Save config to disk (used by setup command). */
488
681
  export function saveConfig(config) {
489
682
  fs.mkdirSync(BIKKY_DIR, { recursive: true });
@@ -1,12 +1,14 @@
1
1
  /**
2
- * Events-based memory extraction — reads Copilot CLI events.jsonl transcripts,
2
+ * Events-based memory extraction — reads supported coding-agent transcripts,
3
3
  * extracts facts via LLM, and stores them in Qdrant with source: "system".
4
4
  *
5
5
  * Uses a JSON file for extraction state (high-water byte offsets) instead of SQLite.
6
- * Active session detection scans ~/.copilot/session-state/ for lock files.
6
+ * Copilot session detection uses lock files. Claude Code detection uses
7
+ * top-level JSONL transcripts under ~/.claude/projects.
7
8
  */
8
9
  import type { BikkyConfig } from "../config.js";
9
10
  import type { LogFn } from "./qdrant.js";
11
+ import { type TranscriptSource } from "./transcript-sources.js";
10
12
  export declare const setLogger: (fn: LogFn) => void;
11
13
  export declare const DEFAULT_EXTRACTION_PROMPT = "You are Bikky's memory extraction agent for open-source coding agents. Extract durable, reusable facts that help a future agent continue work without rereading the whole transcript.\n\n## Core rule\nExtract fewer, sharper memories. A candidate fact must be independently useful after the session is gone.\n\n## Quality gate\nEvery fact must pass at least one gate:\n1. GREPPABLE: names a file path, package, symbol, config key, CLI flag, issue/PR, service, or API a future agent can search for.\n2. RUNNABLE: contains a command, URL, setting, port, or procedure that can be executed or checked.\n3. NAVIGABLE: tells a future agent where to look and what that location means.\n4. DECISIVE: records a durable decision, rationale, constraint, convention, or preference.\n5. DIAGNOSTIC: captures a repeatable failure mode, root cause, or troubleshooting gotcha.\n\n## Ontology\n- domain is the activity profile. For coding-agent captures use \"software_engineering\".\n- category is subject matter: engineering | product | human | system.\n- kind is object shape. For this prompt, emit only kind=\"fact\".\n- memory_subtype must be one of:\n codebase_map | architecture_decision | infra_topology | access_pattern | operational_procedure | domain_rule | product_decision | product_requirement | user_workflow | roadmap_item | success_metric | market_insight | troubleshooting_gotcha | preference | person_profile | ownership_note | working_agreement | activity_event.\n\n## Examples\nGOOD:\n- \"The UI smoke tests live in packages/ui/tests/smoke.spec.ts and run through npm run test:e2e with mocked /api/memory/* responses.\"\n- \"Use workspace_id as the tenancy/access boundary; domain is reserved for activity profile such as software_engineering.\"\n- \"If Qdrant order_by fails with a missing index error, create a datetime payload index for the sorted field before retrying.\"\n- \"The memory page should show categories and concrete subtype chips directly; a sub-tab layer makes the ontology harder to understand.\"\n- \"Saber prefers Node's built-in test runner for root tests; do not add Jest just for daemon unit tests.\"\n- \"Saber merged PR #85 after approving the subtype UX copy changes.\"\n\nBAD:\n- \"The tests were fixed.\" (status only)\n- \"We reviewed the code.\" (session narration)\n- \"The deployment succeeded.\" (transient and not reusable)\n- \"The agent used npm.\" (tool narration)\n- \"There was an error.\" (no root cause or reusable detail)\n\n## Output format\nReturn strict JSON:\n{\"facts\":[\n {\n \"content\":\"One self-contained durable fact.\",\n \"category\":\"engineering\",\n \"memory_subtype\":\"codebase_map\",\n \"action_actor\":\"optional actor for activity_event only\",\n \"action_type\":\"optional action verb for activity_event only\",\n \"action_object\":\"optional durable object for activity_event only\",\n \"action_outcome\":\"optional durable outcome for activity_event only\",\n \"entities\":[\"repo-or-tool\",\"specific-module\"],\n \"confidence\":0.9,\n \"importance\":0.7,\n \"quality_score\":0.8,\n \"confidence_reason\":\"Explicitly stated in the transcript.\",\n \"repo\":\"optional/repo-or-package\",\n \"branch\":\"optional-branch\",\n \"task_key\":\"optional issue/PR/task key\",\n \"workstream_key\":\"optional stable workstream key\"\n }\n]}\n\nScoring:\n- confidence: 0.9 explicit, 0.7 strong inference, 0.55 weak but useful inference.\n- importance: 0.8+ for decisions, infra, procedures, access, recurring failures, product requirements, ownership, and state-changing activity events; 0.6+ for useful codebase maps/preferences.\n- quality_score: 0.8+ passes multiple gates, 0.6+ passes one strong gate, below 0.6 should usually be omitted.\n\nIf nothing passes the quality gate, return {\"facts\":[]}.";
12
14
  export type Volatility = "stable" | "evolving" | "transient" | "ephemeral";
@@ -60,5 +62,13 @@ export interface ExtractionHealth {
60
62
  active_session_count: number;
61
63
  /** Configured copilot watcher path at the time of the tick. */
62
64
  watcher_path: string;
65
+ /** Per-source health, including non-Copilot watchers. */
66
+ sources?: Record<TranscriptSource, ExtractionSourceHealth>;
67
+ }
68
+ export interface ExtractionSourceHealth {
69
+ enabled: boolean;
70
+ watcher_path: string;
71
+ active_session_count: number;
72
+ last_active_session_at: string | null;
63
73
  }
64
74
  //# sourceMappingURL=extraction.d.ts.map