@dikolab/kbdb 0.5.0 → 0.6.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 (224) hide show
  1. package/CLA.md +68 -0
  2. package/LICENSE +676 -12
  3. package/LICENSING.md +58 -0
  4. package/README.md +50 -25
  5. package/README.md.bak +322 -0
  6. package/dist/README.md +322 -0
  7. package/dist/{chunk-BJXEVALU.mjs → chunk-QLJ33C74.mjs} +44 -44
  8. package/dist/chunk-QLJ33C74.mjs.map +7 -0
  9. package/dist/cli.cjs +550 -232
  10. package/dist/cli.cjs.map +4 -4
  11. package/dist/cli.d.ts +0 -8
  12. package/dist/cli.mjs +483 -154
  13. package/dist/cli.mjs.map +4 -4
  14. package/dist/kbdb-worker.cjs +36 -5
  15. package/dist/kbdb-worker.cjs.map +3 -3
  16. package/dist/mod.cjs +89 -30
  17. package/dist/mod.cjs.map +4 -4
  18. package/dist/mod.mjs +88 -30
  19. package/dist/mod.mjs.map +4 -4
  20. package/dist/src/cli.d.ts +0 -8
  21. package/dist/src/shared/cli/constants/defaults.constant.d.ts +1 -1
  22. package/dist/src/shared/cli/constants/recfile-command-field-map.constant.d.ts +8 -0
  23. package/dist/src/shared/cli/constants/recfile-field-maps.constant.d.ts +21 -0
  24. package/dist/src/shared/cli/functions/compute-directory-level.function.d.ts +14 -0
  25. package/dist/src/shared/cli/functions/dispatch-command.function.d.ts +2 -28
  26. package/dist/src/shared/cli/functions/format-command-output.function.d.ts +14 -0
  27. package/dist/src/shared/cli/functions/format-db-not-found.function.d.ts +20 -0
  28. package/dist/src/shared/cli/functions/format-output.function.d.ts +1 -0
  29. package/dist/src/shared/cli/functions/format-recfile-output.function.d.ts +11 -0
  30. package/dist/src/shared/cli/functions/render-recfile-value.function.d.ts +11 -0
  31. package/dist/src/shared/cli/functions/resolve-db-dir.function.d.ts +24 -0
  32. package/dist/src/shared/cli/functions/resolve-recfile-key.function.d.ts +9 -0
  33. package/dist/src/shared/cli/functions/run-db-path.function.d.ts +10 -0
  34. package/dist/src/shared/cli/functions/run-export.function.d.ts +8 -4
  35. package/dist/src/shared/cli/functions/run-import.function.d.ts +4 -0
  36. package/dist/src/shared/cli/functions/run-learn.function.d.ts +12 -0
  37. package/dist/src/shared/cli/index.d.ts +4 -1
  38. package/dist/src/shared/cli/typings/cli-options.interface.d.ts +9 -2
  39. package/dist/src/shared/cli/typings/db-resolution.interface.d.ts +9 -0
  40. package/dist/src/shared/cli/typings/recfile-field-map.type.d.ts +10 -0
  41. package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
  42. package/dist/src/shared/wasm-codec/functions/decode-option-u8.function.d.ts +9 -0
  43. package/dist/src/shared/wasm-codec/functions/decode-section-records.function.d.ts +4 -0
  44. package/dist/src/shared/wasm-codec/functions/encode-add-section-params.function.d.ts +2 -45
  45. package/dist/src/shared/wasm-codec/functions/encode-update-section-params.function.d.ts +10 -1
  46. package/dist/src/shared/wasm-codec/index.d.ts +1 -1
  47. package/dist/src/shared/wasm-codec/typings/add-section-input.model.d.ts +6 -0
  48. package/dist/src/shared/wasm-codec/typings/section-record-trailing.model.d.ts +5 -0
  49. package/dist/src/shared/wasm-codec/typings/section-record.model.d.ts +5 -0
  50. package/dist/src/shared/worker-client/functions/build-deno-permissions.function.d.ts +11 -0
  51. package/dist/src/shared/worker-client/functions/read-crash-reason.function.d.ts +9 -0
  52. package/dist/src/shared/worker-client/functions/resolve-spawn-script.function.d.ts +6 -0
  53. package/dist/src/shared/worker-client/functions/spawn-daemon.function.d.ts +1 -1
  54. package/dist/src/shared/worker-client/typings/section.model.d.ts +5 -0
  55. package/dist/src/shared/worker-client/typings/worker-client-options.interface.d.ts +0 -6
  56. package/dist/src/shared/worker-daemon/functions/count-files.function.d.ts +12 -0
  57. package/dist/src/shared/worker-daemon/functions/handle-import.function.d.ts +2 -0
  58. package/dist/src/shared/worker-daemon/functions/handle-read-ops.function.d.ts +8 -0
  59. package/dist/src/shared/worker-daemon/functions/validate-daemon-path.function.d.ts +15 -0
  60. package/dist/src/worker.d.ts +0 -7
  61. package/dist/wasm/default-embedding/kbdb_default_embedding_bg.wasm +0 -0
  62. package/dist/wasm/default-embedding/package.json +1 -1
  63. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  64. package/dist/wasm/fs-database/package.json +1 -1
  65. package/dist/wasm/fs-migration/package.json +1 -1
  66. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  67. package/dist/wasm/kb-worker/package.json +1 -1
  68. package/dist/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
  69. package/dist/wasm/query-parser/package.json +1 -1
  70. package/dist/worker.d.ts +0 -7
  71. package/dist/worker.mjs +37 -6
  72. package/dist/worker.mjs.map +3 -3
  73. package/package.json +11 -10
  74. package/dist/chunk-BJXEVALU.mjs.map +0 -7
  75. package/dist/src/shared/cli/functions/resolve-raw-db-path.function.d.ts +0 -10
  76. package/docs/details/README.md +0 -30
  77. package/docs/details/agent-tooling.md +0 -132
  78. package/docs/details/cli.md +0 -777
  79. package/docs/details/knowledge-base.md +0 -180
  80. package/docs/details/library-api.md +0 -495
  81. package/docs/details/mcp-server.md +0 -482
  82. package/docs/details/search-and-ranking.md +0 -575
  83. package/docs/details/storage.md +0 -531
  84. package/docs/goals/agents.md +0 -751
  85. package/docs/goals/architecture.svg +0 -198
  86. package/docs/goals/auto-capture.md +0 -378
  87. package/docs/goals/benchmarking.md +0 -296
  88. package/docs/goals/cli.md +0 -2654
  89. package/docs/goals/concurrency.md +0 -259
  90. package/docs/goals/content-composer.md +0 -609
  91. package/docs/goals/content-parser.md +0 -279
  92. package/docs/goals/database.md +0 -1679
  93. package/docs/goals/document.md +0 -368
  94. package/docs/goals/hybrid-search.md +0 -465
  95. package/docs/goals/mcp.md +0 -1541
  96. package/docs/goals/overview.md +0 -124
  97. package/docs/goals/query-parser.md +0 -373
  98. package/docs/goals/query-result.md +0 -860
  99. package/docs/goals/semantic-dedup.md +0 -233
  100. package/docs/goals/skills.md +0 -810
  101. package/docs/goals/sync.md +0 -217
  102. package/docs/goals/worker-client.md +0 -1005
  103. package/docs/goals/worker-daemon.md +0 -1547
  104. package/docs/modules/overview.md +0 -319
  105. package/docs/modules/rust/embedding/module.md +0 -91
  106. package/docs/modules/rust/fs-database/functions/document.md +0 -48
  107. package/docs/modules/rust/fs-database/functions/integrity.md +0 -79
  108. package/docs/modules/rust/fs-database/functions/io.md +0 -87
  109. package/docs/modules/rust/fs-database/functions/module.md +0 -22
  110. package/docs/modules/rust/fs-database/functions/query-exec.md +0 -44
  111. package/docs/modules/rust/fs-database/functions/section.md +0 -76
  112. package/docs/modules/rust/fs-database/indexes/btree.md +0 -35
  113. package/docs/modules/rust/fs-database/indexes/corpus.md +0 -61
  114. package/docs/modules/rust/fs-database/indexes/inverted.md +0 -60
  115. package/docs/modules/rust/fs-database/indexes/module.md +0 -64
  116. package/docs/modules/rust/fs-database/indexes/positional.md +0 -39
  117. package/docs/modules/rust/fs-database/indexes/vectors.md +0 -110
  118. package/docs/modules/rust/fs-database/module.md +0 -150
  119. package/docs/modules/rust/fs-database/types/catalog.md +0 -53
  120. package/docs/modules/rust/fs-database/types/module.md +0 -12
  121. package/docs/modules/rust/fs-database/types/section.md +0 -127
  122. package/docs/modules/rust/kb-worker/functions/compose.md +0 -57
  123. package/docs/modules/rust/kb-worker/functions/module.md +0 -20
  124. package/docs/modules/rust/kb-worker/functions/retrieve.md +0 -194
  125. package/docs/modules/rust/kb-worker/functions/search.md +0 -173
  126. package/docs/modules/rust/kb-worker/functions/write.md +0 -172
  127. package/docs/modules/rust/kb-worker/module.md +0 -171
  128. package/docs/modules/rust/kb-worker/types/cache.md +0 -90
  129. package/docs/modules/rust/kb-worker/types/context.md +0 -26
  130. package/docs/modules/rust/kb-worker/types/module.md +0 -16
  131. package/docs/modules/rust/kb-worker/types/status.md +0 -29
  132. package/docs/modules/rust/kb-worker/types/token.md +0 -50
  133. package/docs/modules/rust/overview.md +0 -531
  134. package/docs/modules/rust/query-parser/functions/extract.md +0 -56
  135. package/docs/modules/rust/query-parser/functions/module.md +0 -18
  136. package/docs/modules/rust/query-parser/functions/parse.md +0 -33
  137. package/docs/modules/rust/query-parser/functions/pipeline.md +0 -9
  138. package/docs/modules/rust/query-parser/functions/rank.md +0 -85
  139. package/docs/modules/rust/query-parser/module.md +0 -131
  140. package/docs/modules/rust/query-parser/types/cache.md +0 -39
  141. package/docs/modules/rust/query-parser/types/keyphrase.md +0 -71
  142. package/docs/modules/rust/query-parser/types/module.md +0 -18
  143. package/docs/modules/rust/query-parser/types/token.md +0 -46
  144. package/docs/modules/rust/shared/content-composer/functions.md +0 -114
  145. package/docs/modules/rust/shared/content-composer/module.md +0 -147
  146. package/docs/modules/rust/shared/content-composer/types.md +0 -93
  147. package/docs/modules/rust/shared/content-parser/functions.md +0 -72
  148. package/docs/modules/rust/shared/content-parser/module.md +0 -99
  149. package/docs/modules/rust/shared/content-parser/types.md +0 -71
  150. package/docs/modules/rust/shared/corpus/module.md +0 -24
  151. package/docs/modules/rust/shared/corpus/types.md +0 -141
  152. package/docs/modules/rust/shared/document/module.md +0 -25
  153. package/docs/modules/rust/shared/document/types.md +0 -154
  154. package/docs/modules/rust/shared/encode/module.md +0 -22
  155. package/docs/modules/rust/shared/encode/traits.md +0 -304
  156. package/docs/modules/rust/shared/error/module.md +0 -28
  157. package/docs/modules/rust/shared/error/types.md +0 -302
  158. package/docs/modules/rust/shared/kbid/module.md +0 -24
  159. package/docs/modules/rust/shared/kbid/types.md +0 -147
  160. package/docs/modules/rust/shared/memory/functions.md +0 -209
  161. package/docs/modules/rust/shared/memory/module.md +0 -24
  162. package/docs/modules/rust/shared/module.md +0 -196
  163. package/docs/modules/rust/shared/pipeline/functions.md +0 -141
  164. package/docs/modules/rust/shared/pipeline/module.md +0 -62
  165. package/docs/modules/rust/shared/pipeline/types.md +0 -43
  166. package/docs/modules/rust/shared/query/module.md +0 -27
  167. package/docs/modules/rust/shared/query/types.md +0 -236
  168. package/docs/modules/rust/shared/section/module.md +0 -25
  169. package/docs/modules/rust/shared/section/types.md +0 -294
  170. package/docs/modules/rust/shared/term/module.md +0 -25
  171. package/docs/modules/rust/shared/term/types.md +0 -139
  172. package/docs/modules/typescript/cli.md +0 -131
  173. package/docs/modules/typescript/kbdb-worker.md +0 -150
  174. package/docs/modules/typescript/overview.md +0 -400
  175. package/docs/modules/typescript/shared/auto-capture/module.md +0 -73
  176. package/docs/modules/typescript/shared/cli/constants.md +0 -23
  177. package/docs/modules/typescript/shared/cli/functions.md +0 -809
  178. package/docs/modules/typescript/shared/cli/module.md +0 -138
  179. package/docs/modules/typescript/shared/cli/typings.md +0 -197
  180. package/docs/modules/typescript/shared/embedding/functions.md +0 -200
  181. package/docs/modules/typescript/shared/embedding/module.md +0 -77
  182. package/docs/modules/typescript/shared/embedding/typings.md +0 -124
  183. package/docs/modules/typescript/shared/hash/functions.md +0 -20
  184. package/docs/modules/typescript/shared/hash/module.md +0 -21
  185. package/docs/modules/typescript/shared/log/constants.md +0 -82
  186. package/docs/modules/typescript/shared/log/functions.md +0 -131
  187. package/docs/modules/typescript/shared/log/module.md +0 -153
  188. package/docs/modules/typescript/shared/log/typings.md +0 -82
  189. package/docs/modules/typescript/shared/mcp/classes.md +0 -179
  190. package/docs/modules/typescript/shared/mcp/functions.md +0 -386
  191. package/docs/modules/typescript/shared/mcp/module.md +0 -160
  192. package/docs/modules/typescript/shared/mcp/typings.md +0 -529
  193. package/docs/modules/typescript/shared/module.md +0 -110
  194. package/docs/modules/typescript/shared/platform/functions.md +0 -42
  195. package/docs/modules/typescript/shared/platform/module.md +0 -25
  196. package/docs/modules/typescript/shared/runtime/functions.md +0 -26
  197. package/docs/modules/typescript/shared/runtime/module.md +0 -27
  198. package/docs/modules/typescript/shared/runtime/typings.md +0 -13
  199. package/docs/modules/typescript/shared/version/module.md +0 -27
  200. package/docs/modules/typescript/shared/wasm-codec/functions.md +0 -391
  201. package/docs/modules/typescript/shared/wasm-codec/module.md +0 -98
  202. package/docs/modules/typescript/shared/worker-client/classes.md +0 -264
  203. package/docs/modules/typescript/shared/worker-client/functions.md +0 -175
  204. package/docs/modules/typescript/shared/worker-client/module.md +0 -92
  205. package/docs/modules/typescript/shared/worker-client/typings.md +0 -511
  206. package/docs/modules/typescript/shared/worker-daemon/classes.md +0 -239
  207. package/docs/modules/typescript/shared/worker-daemon/constants.md +0 -37
  208. package/docs/modules/typescript/shared/worker-daemon/functions.md +0 -234
  209. package/docs/modules/typescript/shared/worker-daemon/module.md +0 -118
  210. package/docs/modules/typescript/shared/worker-daemon/typings.md +0 -132
  211. package/docs/overview.md +0 -191
  212. package/docs/release-notes/0.1.0.md +0 -189
  213. package/docs/release-notes/0.1.1.md +0 -46
  214. package/docs/release-notes/0.1.2.md +0 -38
  215. package/docs/release-notes/0.1.3.md +0 -42
  216. package/docs/release-notes/0.2.0.md +0 -147
  217. package/docs/release-notes/0.3.0.md +0 -89
  218. package/docs/release-notes/0.3.1.md +0 -121
  219. package/docs/release-notes/0.3.2.md +0 -64
  220. package/docs/release-notes/0.4.0.md +0 -80
  221. package/docs/release-notes/0.4.1.md +0 -149
  222. package/docs/release-notes/0.4.3.md +0 -60
  223. package/docs/release-notes/0.5.0.md +0 -41
  224. package/docs/release-notes/README.md +0 -16
package/dist/cli.cjs CHANGED
@@ -2,8 +2,8 @@
2
2
  "use strict";
3
3
 
4
4
  // src/cli.ts
5
- var import_node_fs9 = require("node:fs");
6
- var import_node_path12 = require("node:path");
5
+ var import_node_fs10 = require("node:fs");
6
+ var import_node_path14 = require("node:path");
7
7
 
8
8
  // src/shared/runtime/functions/detect-runtime.ts
9
9
  function detectRuntime() {
@@ -23,44 +23,9 @@ function getArgs() {
23
23
  return process.argv.slice(2);
24
24
  }
25
25
 
26
- // src/shared/dir-resolver/functions/resolve-base-dir.function.ts
27
- var import_node_path = require("node:path");
28
- var import_node_url = require("node:url");
29
- function resolveScriptDir(entryUrl, entryDirname) {
30
- if (entryDirname) return entryDirname;
31
- if (entryUrl.startsWith("file:"))
32
- return (0, import_node_path.dirname)((0, import_node_url.fileURLToPath)(entryUrl));
33
- return (0, import_node_path.dirname)(entryUrl);
34
- }
35
- function resolveBaseDir(entryUrl, entryDirname) {
36
- const scriptDir = typeof __dirname !== "undefined" ? __dirname : resolveScriptDir(entryUrl, entryDirname);
37
- return { scriptDir, cwd: process.cwd() };
38
- }
39
-
40
- // src/shared/dir-resolver/functions/join-path.function.ts
41
- var import_node_path2 = require("node:path");
42
- function isRemoteUrl(path) {
43
- return path.startsWith("http://") || path.startsWith("https://");
44
- }
45
- function joinPath(base, ...segments) {
46
- if (isRemoteUrl(base)) {
47
- const trailing = base.endsWith("/") ? "" : "/";
48
- return base + trailing + segments.join("/");
49
- }
50
- return (0, import_node_path2.join)(base, ...segments);
51
- }
52
-
53
- // src/shared/dir-resolver/functions/resolve-worker-script.function.ts
54
- function resolveWorkerScript(scriptDir, runtime2) {
55
- if (runtime2 === "deno") {
56
- return joinPath(scriptDir, "worker.ts");
57
- }
58
- return joinPath(scriptDir, "kbdb-worker.cjs");
59
- }
60
-
61
26
  // src/shared/cli/constants/defaults.constant.ts
62
27
  var DEFAULT_LIMIT = 20;
63
- var DEFAULT_FORMAT = "json";
28
+ var DEFAULT_FORMAT = "rec";
64
29
  var DEFAULT_MODE = "sections";
65
30
  var SUPPORTED_EXTENSIONS = [
66
31
  ".md",
@@ -192,6 +157,18 @@ function parseArgs(argv) {
192
157
  case "--replace":
193
158
  options.replace = true;
194
159
  break;
160
+ case "--level":
161
+ case "--weight": {
162
+ const raw = argv[++i];
163
+ const n = Number(raw);
164
+ if (!Number.isInteger(n) || n < 1 || n > 6) {
165
+ throw new Error(
166
+ `Invalid level "${raw}": must be integer 1-6`
167
+ );
168
+ }
169
+ options.level = n;
170
+ break;
171
+ }
195
172
  case "--depth":
196
173
  case "-d":
197
174
  options.depth = Math.min(
@@ -238,18 +215,8 @@ function parseArgs(argv) {
238
215
  return options;
239
216
  }
240
217
 
241
- // src/shared/cli/functions/format-output.function.ts
242
- function formatOutput(paged, format) {
243
- switch (format) {
244
- case "json":
245
- return JSON.stringify(paged, null, 2);
246
- case "text":
247
- return formatText(paged);
248
- case "mcp":
249
- return formatMcp(paged);
250
- }
251
- }
252
- function formatText(paged) {
218
+ // src/shared/cli/functions/format-text-output.function.ts
219
+ function formatTextOutput(paged) {
253
220
  if (paged.items.length === 0) return "No results found.";
254
221
  const start = paged.offset + 1;
255
222
  const end = paged.offset + paged.items.length;
@@ -269,7 +236,9 @@ Showing ${String(start)}-${String(end)} of ${String(paged.total)} results`;
269
236
  Use --offset ${String(end)} to see more` : "";
270
237
  return lines + footer + hint;
271
238
  }
272
- function formatMcp(paged) {
239
+
240
+ // src/shared/cli/functions/format-mcp-output.function.ts
241
+ function formatMcpOutput(paged) {
273
242
  const mcpItems = paged.items.map((r) => ({
274
243
  kbid: r.kbid,
275
244
  heading: r.heading,
@@ -298,6 +267,168 @@ function formatMcp(paged) {
298
267
  );
299
268
  }
300
269
 
270
+ // src/shared/cli/functions/resolve-recfile-key.function.ts
271
+ function resolveRecfileKey(obj, key) {
272
+ const parts = key.split(".");
273
+ let current = obj;
274
+ for (const part of parts) {
275
+ if (current == null || typeof current !== "object") {
276
+ return void 0;
277
+ }
278
+ current = current[part];
279
+ }
280
+ return current;
281
+ }
282
+
283
+ // src/shared/cli/functions/render-recfile-value.function.ts
284
+ function renderRecfileValue(value) {
285
+ if (value === null || value === void 0) return null;
286
+ if (Array.isArray(value)) {
287
+ if (value.length === 0) return null;
288
+ return value.map(String).join(", ");
289
+ }
290
+ if (typeof value === "boolean") return value ? "true" : "false";
291
+ if (typeof value === "number") return String(value);
292
+ if (typeof value === "string") return value === "" ? null : value;
293
+ return JSON.stringify(value);
294
+ }
295
+
296
+ // src/shared/cli/functions/format-recfile-output.function.ts
297
+ function formatRecfileOutput(data, fields) {
298
+ const records = Array.isArray(data) ? data : [data];
299
+ return records.map((record) => formatRecord(record, fields)).filter(Boolean).join("\n\n");
300
+ }
301
+ function formatRecord(record, fields) {
302
+ if (!record || typeof record !== "object") return "";
303
+ const lines = [];
304
+ for (const [field, key] of fields) {
305
+ const value = resolveRecfileKey(record, key);
306
+ const rendered = renderRecfileValue(value);
307
+ if (rendered === null) continue;
308
+ lines.push(formatField(field, rendered));
309
+ }
310
+ return lines.join("\n");
311
+ }
312
+ function formatField(field, value) {
313
+ const lines = value.split("\n");
314
+ if (lines.length === 1) return `${field}: ${lines[0]}`;
315
+ return [
316
+ `${field}: ${lines[0]}`,
317
+ ...lines.slice(1).map((line) => `+ ${line}`)
318
+ ].join("\n");
319
+ }
320
+
321
+ // src/shared/cli/constants/recfile-field-maps.constant.ts
322
+ var SEARCH_FIELDS = [
323
+ ["kbid", "kbid"],
324
+ ["heading", "heading"],
325
+ ["score", "score"],
326
+ ["confidence", "confidence"],
327
+ ["type", "type"],
328
+ ["terms", "matched_terms"],
329
+ ["fields", "matched_fields"],
330
+ ["snippet", "snippet"],
331
+ ["level", "level"]
332
+ ];
333
+ var LEARN_FIELDS = [
334
+ ["kbid", "kbid"],
335
+ ["path", "path"],
336
+ ["size", "size"],
337
+ ["skipped", "skipped"],
338
+ ["superseded", "superseded"],
339
+ ["warnings", "warnings"],
340
+ ["level", "level"]
341
+ ];
342
+ var UNLEARN_FIELDS = [
343
+ ["removed", "removed"],
344
+ ["elapsed_ms", "elapsed_ms"]
345
+ ];
346
+ var RECALL_FIELDS = [
347
+ ["kbid", "kbid"],
348
+ ["heading", "heading"],
349
+ ["type", "type"],
350
+ ["docids", "docids"],
351
+ ["content", "content"],
352
+ ["level", "level"]
353
+ ];
354
+ var EXPORT_FIELDS = [
355
+ ["path", "path"],
356
+ ["sections", "sections_exported"],
357
+ ["documents", "documents_exported"],
358
+ ["elapsed_ms", "elapsed_ms"]
359
+ ];
360
+ var IMPORT_FIELDS = [
361
+ ["sections", "sections_imported"],
362
+ ["documents", "documents_imported"],
363
+ ["rebuilt", "rebuilt"],
364
+ ["dry_run", "dry_run"],
365
+ ["elapsed_ms", "elapsed_ms"]
366
+ ];
367
+ var STATUS_FIELDS = [
368
+ ["initialized", "initialized"],
369
+ ["path", "contextPath"],
370
+ ["content_cached", "cacheStats.contentCount"],
371
+ ["index_cached", "cacheStats.indexCount"]
372
+ ];
373
+ var CHECK_FIELDS = [
374
+ ["ok", "ok"],
375
+ ["sections_checked", "sections_checked"],
376
+ ["documents_checked", "documents_checked"],
377
+ ["references_checked", "references_checked"],
378
+ ["elapsed_ms", "elapsed_ms"]
379
+ ];
380
+ var GC_FIELDS = [
381
+ ["removed_sections", "removed_sections"],
382
+ ["removed_bytes", "removed_bytes"],
383
+ ["elapsed_ms", "elapsed_ms"]
384
+ ];
385
+ var REBUILD_FIELDS = [
386
+ ["sections_reindexed", "sections_reindexed"],
387
+ ["terms_indexed", "terms_indexed"],
388
+ ["elapsed_ms", "elapsed_ms"]
389
+ ];
390
+
391
+ // src/shared/cli/functions/format-output.function.ts
392
+ function formatOutput(paged, format) {
393
+ switch (format) {
394
+ case "json":
395
+ return JSON.stringify(paged, null, 2);
396
+ case "text":
397
+ return formatTextOutput(paged);
398
+ case "rec":
399
+ return formatRecfileOutput(paged.items, SEARCH_FIELDS);
400
+ case "mcp":
401
+ return formatMcpOutput(paged);
402
+ }
403
+ }
404
+
405
+ // src/shared/cli/constants/recfile-command-field-map.constant.ts
406
+ var RECFILE_COMMAND_FIELD_MAP = {
407
+ learn: LEARN_FIELDS,
408
+ unlearn: UNLEARN_FIELDS,
409
+ recall: RECALL_FIELDS,
410
+ export: EXPORT_FIELDS,
411
+ import: IMPORT_FIELDS,
412
+ status: STATUS_FIELDS,
413
+ check: CHECK_FIELDS,
414
+ gc: GC_FIELDS,
415
+ rebuild: REBUILD_FIELDS
416
+ };
417
+
418
+ // src/shared/cli/functions/format-command-output.function.ts
419
+ function formatCommandOutput(data, format, command) {
420
+ switch (format) {
421
+ case "rec": {
422
+ const fields = RECFILE_COMMAND_FIELD_MAP[command];
423
+ return fields ? formatRecfileOutput(data, fields) : JSON.stringify(data, null, 2);
424
+ }
425
+ case "json":
426
+ case "text":
427
+ case "mcp":
428
+ return JSON.stringify(data, null, 2);
429
+ }
430
+ }
431
+
301
432
  // src/shared/log/constants/log-colors.constant.ts
302
433
  var ANSI_RESET = "\x1B[0m";
303
434
  var LOG_COLORS = {
@@ -452,15 +583,64 @@ async function runRecall(client, options) {
452
583
  }
453
584
 
454
585
  // src/shared/cli/functions/run-export.function.ts
586
+ var import_node_path = require("node:path");
455
587
  async function runExport(client, options) {
456
588
  log("running export", 0 /* DEBUG */);
457
- const path = options.args[0];
589
+ const path = options.args.length > 0 ? (0, import_node_path.resolve)(process.cwd(), options.args[0]) : void 0;
458
590
  return client.export({ path });
459
591
  }
460
592
 
461
593
  // src/shared/cli/functions/run-learn.function.ts
594
+ var import_node_fs2 = require("node:fs");
595
+
596
+ // src/shared/cli/functions/collect-files.function.ts
462
597
  var import_node_fs = require("node:fs");
463
- var import_node_path3 = require("node:path");
598
+ var import_node_path2 = require("node:path");
599
+ function collectFiles(target) {
600
+ try {
601
+ const stat = (0, import_node_fs.statSync)(target);
602
+ if (stat.isFile()) {
603
+ return isSupportedFile(target) ? [target] : [];
604
+ }
605
+ if (stat.isDirectory()) {
606
+ return scanDirectory(target);
607
+ }
608
+ } catch {
609
+ }
610
+ return [];
611
+ }
612
+ function scanDirectory(dir) {
613
+ const files = [];
614
+ for (const entry of (0, import_node_fs.readdirSync)(dir)) {
615
+ if (entry.startsWith(".")) continue;
616
+ const full = (0, import_node_path2.join)(dir, entry);
617
+ try {
618
+ const stat = (0, import_node_fs.statSync)(full);
619
+ if (stat.isDirectory()) {
620
+ files.push(...scanDirectory(full));
621
+ } else if (isSupportedFile(full)) {
622
+ files.push(full);
623
+ }
624
+ } catch {
625
+ }
626
+ }
627
+ return files;
628
+ }
629
+ function isSupportedFile(path) {
630
+ if ((0, import_node_path2.basename)(path).startsWith(".")) return false;
631
+ const ext = (0, import_node_path2.extname)(path).toLowerCase();
632
+ return SUPPORTED_EXTENSIONS.includes(ext);
633
+ }
634
+
635
+ // src/shared/cli/functions/compute-directory-level.function.ts
636
+ var MAX_LEVEL = 6;
637
+ function computeDirectoryLevel(filePath, basePath) {
638
+ const relative = filePath.slice(basePath.length).replace(/^\//, "");
639
+ const depth = relative.split("/").length - 1;
640
+ return Math.min(depth + 1, MAX_LEVEL);
641
+ }
642
+
643
+ // src/shared/cli/functions/run-learn.function.ts
464
644
  async function runLearn(client, options, io) {
465
645
  log(
466
646
  "learning " + options.args.length.toString() + " targets",
@@ -481,14 +661,15 @@ async function runLearn(client, options, io) {
481
661
  description: options.description,
482
662
  docid: options.docid,
483
663
  tags: options.tags,
484
- replace: options.replace
664
+ replace: options.replace,
665
+ level: options.level
485
666
  });
486
667
  results.push(mapAddSectionResult(result, "-", content.length));
487
668
  continue;
488
669
  }
489
670
  const files = collectFiles(target);
490
671
  for (const file of files) {
491
- const content = (0, import_node_fs.readFileSync)(file, "utf-8");
672
+ const content = (0, import_node_fs2.readFileSync)(file, "utf-8");
492
673
  const result = await client.addSection({
493
674
  sectionType: "text",
494
675
  content,
@@ -497,7 +678,8 @@ async function runLearn(client, options, io) {
497
678
  docid: options.docid,
498
679
  tags: options.tags,
499
680
  replace: options.replace,
500
- sourcePath: file
681
+ sourcePath: file,
682
+ level: options.level ?? computeDirectoryLevel(file, target)
501
683
  });
502
684
  results.push(
503
685
  mapAddSectionResult(result, file, content.length)
@@ -522,52 +704,17 @@ function mapAddSectionResult(result, path, size) {
522
704
  };
523
705
  }
524
706
  function readProcessStdin() {
525
- return new Promise((resolve4) => {
707
+ return new Promise((resolve7) => {
526
708
  const chunks = [];
527
709
  process.stdin.on("data", (chunk) => {
528
710
  chunks.push(chunk);
529
711
  });
530
712
  process.stdin.on("end", () => {
531
- resolve4(Buffer.concat(chunks).toString("utf-8"));
713
+ resolve7(Buffer.concat(chunks).toString("utf-8"));
532
714
  });
533
715
  process.stdin.resume();
534
716
  });
535
717
  }
536
- function collectFiles(target) {
537
- try {
538
- const stat = (0, import_node_fs.statSync)(target);
539
- if (stat.isFile()) {
540
- return isSupportedFile(target) ? [target] : [];
541
- }
542
- if (stat.isDirectory()) {
543
- return scanDirectory(target);
544
- }
545
- } catch {
546
- }
547
- return [];
548
- }
549
- function scanDirectory(dir) {
550
- const files = [];
551
- for (const entry of (0, import_node_fs.readdirSync)(dir)) {
552
- if (entry.startsWith(".")) continue;
553
- const full = (0, import_node_path3.join)(dir, entry);
554
- try {
555
- const stat = (0, import_node_fs.statSync)(full);
556
- if (stat.isDirectory()) {
557
- files.push(...scanDirectory(full));
558
- } else if (isSupportedFile(full)) {
559
- files.push(full);
560
- }
561
- } catch {
562
- }
563
- }
564
- return files;
565
- }
566
- function isSupportedFile(path) {
567
- if ((0, import_node_path3.basename)(path).startsWith(".")) return false;
568
- const ext = (0, import_node_path3.extname)(path).toLowerCase();
569
- return SUPPORTED_EXTENSIONS.includes(ext);
570
- }
571
718
 
572
719
  // src/shared/cli/functions/run-unlearn.function.ts
573
720
  async function runUnlearn(client, options) {
@@ -627,33 +774,33 @@ async function runRebuild(client, _options) {
627
774
  }
628
775
 
629
776
  // src/shared/cli/functions/find-db.function.ts
630
- var import_node_fs2 = require("node:fs");
631
- var import_node_path4 = require("node:path");
777
+ var import_node_fs3 = require("node:fs");
778
+ var import_node_path3 = require("node:path");
632
779
  function findDb(dbPath) {
633
780
  if (dbPath) {
634
- const target = (0, import_node_path4.join)((0, import_node_path4.resolve)(dbPath), ".kbdb");
635
- return (0, import_node_fs2.existsSync)(target) ? target : null;
781
+ const target = (0, import_node_path3.join)((0, import_node_path3.resolve)(dbPath), ".kbdb");
782
+ return (0, import_node_fs3.existsSync)(target) ? target : null;
636
783
  }
637
784
  let current = process.cwd();
638
- let parent = (0, import_node_path4.dirname)(current);
785
+ let parent = (0, import_node_path3.dirname)(current);
639
786
  while (parent !== current) {
640
- const candidate2 = (0, import_node_path4.join)(current, ".kbdb");
641
- if ((0, import_node_fs2.existsSync)(candidate2)) return candidate2;
787
+ const candidate2 = (0, import_node_path3.join)(current, ".kbdb");
788
+ if ((0, import_node_fs3.existsSync)(candidate2)) return candidate2;
642
789
  current = parent;
643
- parent = (0, import_node_path4.dirname)(current);
790
+ parent = (0, import_node_path3.dirname)(current);
644
791
  }
645
- const candidate = (0, import_node_path4.join)(current, ".kbdb");
646
- return (0, import_node_fs2.existsSync)(candidate) ? candidate : null;
792
+ const candidate = (0, import_node_path3.join)(current, ".kbdb");
793
+ return (0, import_node_fs3.existsSync)(candidate) ? candidate : null;
647
794
  }
648
795
 
649
796
  // src/shared/cli/functions/run-init.function.ts
650
- var import_node_fs4 = require("node:fs");
651
- var import_node_path6 = require("node:path");
797
+ var import_node_fs5 = require("node:fs");
798
+ var import_node_path5 = require("node:path");
652
799
 
653
800
  // src/shared/cli/functions/install-default-skills.function.ts
654
801
  var import_node_crypto = require("node:crypto");
655
- var import_node_fs3 = require("node:fs");
656
- var import_node_path5 = require("node:path");
802
+ var import_node_fs4 = require("node:fs");
803
+ var import_node_path4 = require("node:path");
657
804
  var BASE32_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
658
805
  function base32Encode(bytes) {
659
806
  let result = "";
@@ -714,19 +861,19 @@ function installSkill(sectionsDir, skill) {
714
861
  });
715
862
  const kbid = computeSectionKbid("text/markdown", content);
716
863
  const prefix = kbid.slice(0, 2);
717
- const shardDir = (0, import_node_path5.join)(sectionsDir, prefix);
718
- const filePath = (0, import_node_path5.join)(shardDir, `${kbid}.section`);
719
- if ((0, import_node_fs3.existsSync)(filePath)) {
864
+ const shardDir = (0, import_node_path4.join)(sectionsDir, prefix);
865
+ const filePath = (0, import_node_path4.join)(shardDir, `${kbid}.section`);
866
+ if ((0, import_node_fs4.existsSync)(filePath)) {
720
867
  return;
721
868
  }
722
- (0, import_node_fs3.mkdirSync)(shardDir, { recursive: true });
869
+ (0, import_node_fs4.mkdirSync)(shardDir, { recursive: true });
723
870
  const fileContent = serializeSkillSection(
724
871
  kbid,
725
872
  skill.name,
726
873
  skill.description,
727
874
  content
728
875
  );
729
- (0, import_node_fs3.writeFileSync)(filePath, fileContent, "utf-8");
876
+ (0, import_node_fs4.writeFileSync)(filePath, fileContent, "utf-8");
730
877
  }
731
878
  var QUERY_GUIDANCE_BODY = 'This knowledge base uses lexical search (stemmed BM25F), not semantic/vector search. Follow these guidelines for effective retrieval:\n\n1. Issue MULTIPLE short keyword queries rather than one long natural-language question. Each query should target 2-3 specific terms.\n\n2. EXPAND SYNONYMS yourself. "login" will not match "sign-in" unless both terms appear in the content. Try alternative phrasings: search for "login", then "sign-in", then "authentication".\n\n3. USE BOOLEAN AND PHRASE SYNTAX:\n - Exact phrases: "error handling"\n - Boolean AND: auth AND token\n - Boolean OR: cache OR redis\n - Exclusion: auth -oauth\n\n4. LEAN ON HEADINGS. Headings carry 2x weight in ranking. Search for terms that are likely in section titles.\n\n5. STEMMING IS AUTOMATIC. "connections" matches "connect", "running" matches "run". You do not need to try inflected forms.\n\n6. USE RECALL AFTER SEARCH. After finding relevant sections with search, use recall with increasing depth (0-3) to progressively expand context: depth 0 = full content, depth 1 = parent documents + back-references, depth 2 = siblings + forward references, depth 3 = referenced sections.\n\n7. CODE IDENTIFIERS ARE SPLIT. camelCase and snake_case names are decomposed: getUserById becomes searchable as "get", "user", "by", "id".\n\n8. PAGINATION. Default limit is 20 results. Use offset for additional pages if total > limit.';
732
879
  var MEMORY_PROTOCOL_BODY = "Follow these guidelines to keep the knowledge base accurate and useful:\n\n1. STORE DURABLE FACTS: decisions, architecture choices, configuration values, corrections to prior knowledge, API contracts, and resolved incidents. These are the facts that matter weeks later.\n\n2. DO NOT STORE: transient conversation context, debugging output, ephemeral task state, raw log dumps, or information that changes every session. The brain should contain knowledge, not activity logs.\n\n3. SEARCH BEFORE STORING. Always search the knowledge base before adding new content. If a section already covers the topic, use learn with --replace to update it rather than creating a duplicate.\n\n4. USE --replace FOR CORRECTIONS. When a fact changes (e.g., rate limit updated from 100 to 200 req/min), re-learn the corrected content with --replace so the old version is superseded. Without --replace, both the old and new versions coexist with equal ranking.\n\n5. ATTACH TAGS for scoping. Use tags like project name, domain, or topic (e.g., --tags auth,api,v2) so queries can be filtered by scope later.\n\n6. PREFER RECENT RESULTS. When search returns multiple sections covering the same topic, prefer the one with the most recent created_at timestamp -- it is more likely to reflect the current state.\n\n7. USE RECALL AFTER SEARCH. After finding relevant sections, use recall with increasing depth (0-3) to expand context progressively before making decisions.\n\n8. INCLUDE HEADINGS. Always provide a descriptive title when storing content. Headings carry 2x ranking weight -- omitting them significantly reduces searchability.";
@@ -743,7 +890,7 @@ var DEFAULT_SKILLS = [
743
890
  }
744
891
  ];
745
892
  function installDefaultSkills(dbDir) {
746
- const sectionsDir = (0, import_node_path5.join)(dbDir, "sections");
893
+ const sectionsDir = (0, import_node_path4.join)(dbDir, "sections");
747
894
  for (const skill of DEFAULT_SKILLS) {
748
895
  installSkill(sectionsDir, skill);
749
896
  }
@@ -767,22 +914,22 @@ var GITIGNORE = [
767
914
  ""
768
915
  ].join("\n");
769
916
  function createScaffold(dbDir) {
770
- (0, import_node_fs4.mkdirSync)(dbDir, { recursive: true });
771
- (0, import_node_fs4.mkdirSync)((0, import_node_path6.join)(dbDir, "sections"));
772
- (0, import_node_fs4.mkdirSync)((0, import_node_path6.join)(dbDir, "documents"));
773
- (0, import_node_fs4.writeFileSync)((0, import_node_path6.join)(dbDir, "catalog.toml"), CATALOG_TOML);
774
- (0, import_node_fs4.writeFileSync)((0, import_node_path6.join)(dbDir, "corpus.bin"), "");
775
- (0, import_node_fs4.writeFileSync)((0, import_node_path6.join)(dbDir, "inverted.idx"), "");
776
- (0, import_node_fs4.writeFileSync)((0, import_node_path6.join)(dbDir, "positional.idx"), "");
777
- (0, import_node_fs4.writeFileSync)((0, import_node_path6.join)(dbDir, "worker.toml"), WORKER_TOML);
778
- (0, import_node_fs4.writeFileSync)((0, import_node_path6.join)(dbDir, ".gitignore"), GITIGNORE);
917
+ (0, import_node_fs5.mkdirSync)(dbDir, { recursive: true });
918
+ (0, import_node_fs5.mkdirSync)((0, import_node_path5.join)(dbDir, "sections"));
919
+ (0, import_node_fs5.mkdirSync)((0, import_node_path5.join)(dbDir, "documents"));
920
+ (0, import_node_fs5.writeFileSync)((0, import_node_path5.join)(dbDir, "catalog.toml"), CATALOG_TOML);
921
+ (0, import_node_fs5.writeFileSync)((0, import_node_path5.join)(dbDir, "corpus.bin"), "");
922
+ (0, import_node_fs5.writeFileSync)((0, import_node_path5.join)(dbDir, "inverted.idx"), "");
923
+ (0, import_node_fs5.writeFileSync)((0, import_node_path5.join)(dbDir, "positional.idx"), "");
924
+ (0, import_node_fs5.writeFileSync)((0, import_node_path5.join)(dbDir, "worker.toml"), WORKER_TOML);
925
+ (0, import_node_fs5.writeFileSync)((0, import_node_path5.join)(dbDir, ".gitignore"), GITIGNORE);
779
926
  }
780
927
  function runInit(options) {
781
928
  log("running init", 0 /* DEBUG */);
782
- const basePath = options.dbPath ? (0, import_node_path6.resolve)(options.dbPath) : process.cwd();
783
- const dbDir = (0, import_node_path6.join)(basePath, ".kbdb");
929
+ const basePath = options.dbPath ? (0, import_node_path5.resolve)(options.dbPath) : process.cwd();
930
+ const dbDir = (0, import_node_path5.join)(basePath, ".kbdb");
784
931
  try {
785
- if ((0, import_node_fs4.existsSync)(dbDir)) {
932
+ if ((0, import_node_fs5.existsSync)(dbDir)) {
786
933
  return {
787
934
  ok: false,
788
935
  targetPath: dbDir,
@@ -816,14 +963,14 @@ async function promptUser(question, io) {
816
963
  return answer.trim();
817
964
  }
818
965
  function askReadline(question) {
819
- return new Promise((resolve4) => {
966
+ return new Promise((resolve7) => {
820
967
  const rl = (0, import_node_readline.createInterface)({
821
968
  input: process.stdin,
822
969
  output: process.stdout
823
970
  });
824
971
  rl.question(question, (answer) => {
825
972
  rl.close();
826
- resolve4(answer);
973
+ resolve7(answer);
827
974
  });
828
975
  });
829
976
  }
@@ -1153,6 +1300,7 @@ async function runAgentDelete(client, options) {
1153
1300
  }
1154
1301
 
1155
1302
  // src/shared/cli/functions/run-import.function.ts
1303
+ var import_node_path6 = require("node:path");
1156
1304
  async function runImport(client, options) {
1157
1305
  const from = options.from;
1158
1306
  if (!from) {
@@ -1161,11 +1309,24 @@ async function runImport(client, options) {
1161
1309
  throw new Error(msg);
1162
1310
  }
1163
1311
  return client.import({
1164
- from,
1312
+ from: (0, import_node_path6.resolve)(process.cwd(), from),
1165
1313
  dryRun: options.dryRun === true
1166
1314
  });
1167
1315
  }
1168
1316
 
1317
+ // src/shared/cli/functions/hydrate-search-previews.function.ts
1318
+ async function hydrateSearchPreviews(client, paged) {
1319
+ await Promise.all(
1320
+ paged.items.map(async (result) => {
1321
+ try {
1322
+ const contentResult = await client.content([result.kbid]);
1323
+ result.preview = contentResult.data;
1324
+ } catch {
1325
+ }
1326
+ })
1327
+ );
1328
+ }
1329
+
1169
1330
  // src/shared/cli/functions/dispatch-command.function.ts
1170
1331
  async function dispatchCommand(client, options, io) {
1171
1332
  log("dispatching command: " + options.command, 0 /* DEBUG */);
@@ -1240,7 +1401,7 @@ async function handleLearn(client, options, io) {
1240
1401
  try {
1241
1402
  const results = await runLearn(client, options, io);
1242
1403
  return {
1243
- output: JSON.stringify(results, null, 2),
1404
+ output: formatCommandOutput(results, options.format, "learn"),
1244
1405
  exitCode: 0
1245
1406
  };
1246
1407
  } catch (err) {
@@ -1254,7 +1415,11 @@ async function handleUnlearn(client, options) {
1254
1415
  try {
1255
1416
  const results = await runUnlearn(client, options);
1256
1417
  return {
1257
- output: JSON.stringify(results, null, 2),
1418
+ output: formatCommandOutput(
1419
+ results,
1420
+ options.format,
1421
+ "unlearn"
1422
+ ),
1258
1423
  exitCode: 0
1259
1424
  };
1260
1425
  } catch (err) {
@@ -1291,7 +1456,7 @@ async function handleRecall(client, options) {
1291
1456
  };
1292
1457
  }
1293
1458
  return {
1294
- output: JSON.stringify(result, null, 2),
1459
+ output: formatCommandOutput(result, options.format, "recall"),
1295
1460
  exitCode: 0
1296
1461
  };
1297
1462
  } catch (err) {
@@ -1305,7 +1470,7 @@ async function handleExport(client, options) {
1305
1470
  try {
1306
1471
  const result = await runExport(client, options);
1307
1472
  return {
1308
- output: JSON.stringify(result, null, 2),
1473
+ output: formatCommandOutput(result, options.format, "export"),
1309
1474
  exitCode: 0
1310
1475
  };
1311
1476
  } catch (err) {
@@ -1319,7 +1484,7 @@ async function handleImport(client, options) {
1319
1484
  try {
1320
1485
  const result = await runImport(client, options);
1321
1486
  return {
1322
- output: JSON.stringify(result, null, 2),
1487
+ output: formatCommandOutput(result, options.format, "import"),
1323
1488
  exitCode: 0
1324
1489
  };
1325
1490
  } catch (err) {
@@ -1332,6 +1497,9 @@ async function handleImport(client, options) {
1332
1497
  async function handleContent(client, options) {
1333
1498
  try {
1334
1499
  const result = await runContent(client, options);
1500
+ if (options.format === "rec") {
1501
+ return { output: result.data, exitCode: 0 };
1502
+ }
1335
1503
  return {
1336
1504
  output: JSON.stringify(result, null, 2),
1337
1505
  exitCode: 0
@@ -1347,7 +1515,7 @@ async function handleCheck(client, options) {
1347
1515
  try {
1348
1516
  const result = await runCheck(client, options);
1349
1517
  return {
1350
- output: JSON.stringify(result, null, 2),
1518
+ output: formatCommandOutput(result, options.format, "check"),
1351
1519
  exitCode: result.ok ? 0 : 1
1352
1520
  };
1353
1521
  } catch (err) {
@@ -1361,7 +1529,7 @@ async function handleGc(client, options) {
1361
1529
  try {
1362
1530
  const result = await runGc(client, options);
1363
1531
  return {
1364
- output: JSON.stringify(result, null, 2),
1532
+ output: formatCommandOutput(result, options.format, "gc"),
1365
1533
  exitCode: 0
1366
1534
  };
1367
1535
  } catch (err) {
@@ -1375,7 +1543,7 @@ async function handleRebuild(client, options) {
1375
1543
  try {
1376
1544
  const result = await runRebuild(client, options);
1377
1545
  return {
1378
- output: JSON.stringify(result, null, 2),
1546
+ output: formatCommandOutput(result, options.format, "rebuild"),
1379
1547
  exitCode: 0
1380
1548
  };
1381
1549
  } catch (err) {
@@ -1389,7 +1557,7 @@ async function handleStatus(client, options) {
1389
1557
  try {
1390
1558
  const result = await runStatus(client, options);
1391
1559
  return {
1392
- output: JSON.stringify(result, null, 2),
1560
+ output: formatCommandOutput(result, options.format, "status"),
1393
1561
  exitCode: 0
1394
1562
  };
1395
1563
  } catch (err) {
@@ -1406,7 +1574,11 @@ async function handleDbMigrate(client, options) {
1406
1574
  try {
1407
1575
  const result = await runDbMigrate(client, options);
1408
1576
  return {
1409
- output: JSON.stringify(result, null, 2),
1577
+ output: formatCommandOutput(
1578
+ result,
1579
+ options.format,
1580
+ "db-migrate"
1581
+ ),
1410
1582
  exitCode: 0
1411
1583
  };
1412
1584
  } catch (err) {
@@ -1416,20 +1588,9 @@ async function handleDbMigrate(client, options) {
1416
1588
  };
1417
1589
  }
1418
1590
  }
1419
- async function hydrateSearchPreviews(client, paged) {
1420
- await Promise.all(
1421
- paged.items.map(async (result) => {
1422
- try {
1423
- const contentResult = await client.content([result.kbid]);
1424
- result.preview = contentResult.data;
1425
- } catch {
1426
- }
1427
- })
1428
- );
1429
- }
1430
1591
 
1431
1592
  // src/shared/version/constants/version.constant.ts
1432
- var VERSION = "0.5.0";
1593
+ var VERSION = "0.6.1";
1433
1594
 
1434
1595
  // src/shared/cli/functions/generate-help.function.ts
1435
1596
  var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
@@ -1452,7 +1613,8 @@ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
1452
1613
  var GROUP_SUBCOMMANDS = {
1453
1614
  db: [
1454
1615
  ["init", "Initialise a new .kbdb directory"],
1455
- ["migrate", "Migrate database to current format"]
1616
+ ["migrate", "Migrate database to current format"],
1617
+ ["path", "Show resolved database path"]
1456
1618
  ],
1457
1619
  skill: [
1458
1620
  ["learn", "Create a new skill definition"],
@@ -1516,6 +1678,7 @@ Knowledge Base:
1516
1678
  Database:
1517
1679
  db init Initialise a new .kbdb directory
1518
1680
  db migrate Migrate database to current format
1681
+ db path Show resolved database path
1519
1682
 
1520
1683
  Maintenance:
1521
1684
  check Verify knowledge base integrity
@@ -1812,6 +1975,30 @@ Output:
1812
1975
  Examples:
1813
1976
  kbdb db migrate
1814
1977
  kbdb db migrate --db /path/to/project
1978
+ `,
1979
+ "db-path": `kbdb db path - Show resolved database path
1980
+
1981
+ Usage: kbdb db path [options]
1982
+
1983
+ Prints the absolute path of the .kbdb database
1984
+ that would be used by the current command
1985
+ context. Useful for debugging database
1986
+ resolution.
1987
+
1988
+ Resolution order:
1989
+ 1. --db <path> Explicit flag
1990
+ 2. cwd traversal Walk up from cwd
1991
+ 3. KBDB_DB_DIR Environment variable
1992
+
1993
+ Options:
1994
+ --db <path> Path to .kbdb directory
1995
+ --format json Show full diagnostic
1996
+ -h, --help Show this help message
1997
+
1998
+ Examples:
1999
+ kbdb db path
2000
+ kbdb db path --format json
2001
+ kbdb db path --db /path/to/project
1815
2002
  `,
1816
2003
  "skill-learn": `kbdb skill learn - Create a new skill definition
1817
2004
 
@@ -1973,11 +2160,78 @@ function generateSubcommandHelp(command, subcommand) {
1973
2160
  return generateCommandHelp(command);
1974
2161
  }
1975
2162
 
2163
+ // src/shared/cli/functions/resolve-db-dir.function.ts
2164
+ function resolveDbDir(options, findDb2) {
2165
+ if (options.dbPath) {
2166
+ const flagResult = findDb2(options.dbPath);
2167
+ return flagResult ? { path: flagResult, source: "flag" } : null;
2168
+ }
2169
+ if (!options.skipTraversal) {
2170
+ const traversalResult = findDb2();
2171
+ if (traversalResult) {
2172
+ return { path: traversalResult, source: "traversal" };
2173
+ }
2174
+ }
2175
+ const envDir = process.env["KBDB_DB_DIR"];
2176
+ if (envDir) {
2177
+ const envResult = findDb2(envDir);
2178
+ if (envResult) {
2179
+ return { path: envResult, source: "env" };
2180
+ }
2181
+ }
2182
+ return null;
2183
+ }
2184
+
2185
+ // src/shared/cli/functions/format-db-not-found.function.ts
2186
+ function formatDbNotFound(options) {
2187
+ if (options.dbPath) {
2188
+ return `error: no .kbdb database found at ${options.dbPath}`;
2189
+ }
2190
+ const envValue = process.env["KBDB_DB_DIR"] ?? "(not set)";
2191
+ const lines = [
2192
+ "error: no .kbdb database found",
2193
+ " --db: (not set)"
2194
+ ];
2195
+ if (!options.skipTraversal) {
2196
+ lines.push(` cwd: ${process.cwd()} (searched upward)`);
2197
+ }
2198
+ lines.push(` KBDB_DB_DIR: ${envValue}`);
2199
+ if (!options.skipTraversal) {
2200
+ lines.push('Run "kbdb db init" to create a database.');
2201
+ }
2202
+ return lines.join("\n");
2203
+ }
2204
+
2205
+ // src/shared/cli/functions/run-db-path.function.ts
2206
+ function runDbPath(options, findDb2) {
2207
+ const resolution = resolveDbDir({ dbPath: options.dbPath }, findDb2);
2208
+ if (!resolution) {
2209
+ return {
2210
+ error: formatDbNotFound({ dbPath: options.dbPath }),
2211
+ exitCode: 1
2212
+ };
2213
+ }
2214
+ if (options.format === "json") {
2215
+ const diagnostic = {
2216
+ path: resolution.path,
2217
+ source: resolution.source,
2218
+ flag: options.dbPath ?? null,
2219
+ cwd: process.cwd(),
2220
+ env: process.env["KBDB_DB_DIR"] ?? null
2221
+ };
2222
+ return {
2223
+ output: JSON.stringify(diagnostic, null, 2),
2224
+ exitCode: 0
2225
+ };
2226
+ }
2227
+ return { output: resolution.path, exitCode: 0 };
2228
+ }
2229
+
1976
2230
  // src/shared/worker-client/classes/worker-client.class.ts
1977
2231
  var import_node_net = require("node:net");
1978
2232
 
1979
2233
  // src/shared/worker-client/functions/discover-daemon.function.ts
1980
- var import_node_fs5 = require("node:fs");
2234
+ var import_node_fs6 = require("node:fs");
1981
2235
  var import_node_path7 = require("node:path");
1982
2236
  var import_node_os = require("node:os");
1983
2237
 
@@ -1995,14 +2249,14 @@ function isProcessAlive(pid) {
1995
2249
  function discoverDaemon(contextId) {
1996
2250
  log("discovering daemon for context: " + contextId, 0 /* DEBUG */);
1997
2251
  const pidPath = (0, import_node_path7.join)((0, import_node_os.tmpdir)(), `kbdb-${contextId}.pid`);
1998
- if (!(0, import_node_fs5.existsSync)(pidPath)) {
2252
+ if (!(0, import_node_fs6.existsSync)(pidPath)) {
1999
2253
  log(
2000
2254
  "no daemon PID file found for context: " + contextId,
2001
2255
  0 /* DEBUG */
2002
2256
  );
2003
2257
  return null;
2004
2258
  }
2005
- const pidStr = (0, import_node_fs5.readFileSync)(pidPath, "utf-8").trim();
2259
+ const pidStr = (0, import_node_fs6.readFileSync)(pidPath, "utf-8").trim();
2006
2260
  const pid = parseInt(pidStr, 10);
2007
2261
  if (isNaN(pid) || !isProcessAlive(pid)) {
2008
2262
  log(
@@ -2010,7 +2264,7 @@ function discoverDaemon(contextId) {
2010
2264
  0 /* DEBUG */
2011
2265
  );
2012
2266
  try {
2013
- (0, import_node_fs5.unlinkSync)(pidPath);
2267
+ (0, import_node_fs6.unlinkSync)(pidPath);
2014
2268
  } catch {
2015
2269
  }
2016
2270
  return null;
@@ -2019,7 +2273,7 @@ function discoverDaemon(contextId) {
2019
2273
  const socketPath = (0, import_node_path7.join)((0, import_node_os.tmpdir)(), `kbdb-${contextId}.sock`);
2020
2274
  const crashPath = (0, import_node_path7.join)((0, import_node_os.tmpdir)(), `kbdb-${contextId}.crash`);
2021
2275
  try {
2022
- (0, import_node_fs5.unlinkSync)(crashPath);
2276
+ (0, import_node_fs6.unlinkSync)(crashPath);
2023
2277
  } catch {
2024
2278
  }
2025
2279
  return { pid, socketPath };
@@ -2117,7 +2371,7 @@ var WorkerClient = class {
2117
2371
  * post-connect failure handlers.
2118
2372
  */
2119
2373
  async tryConnect() {
2120
- return new Promise((resolve4, reject) => {
2374
+ return new Promise((resolve7, reject) => {
2121
2375
  const sock = (0, import_node_net.connect)(this.socketPath, () => {
2122
2376
  sock.removeListener("error", reject);
2123
2377
  sock.setKeepAlive(true, 3e4);
@@ -2138,7 +2392,7 @@ var WorkerClient = class {
2138
2392
  this.socket = null;
2139
2393
  });
2140
2394
  this.socket = sock;
2141
- resolve4();
2395
+ resolve7();
2142
2396
  });
2143
2397
  sock.on("error", reject);
2144
2398
  sock.on("data", (chunk) => {
@@ -2466,8 +2720,8 @@ var WorkerClient = class {
2466
2720
  params: { ctx: this.contextId, ...params }
2467
2721
  };
2468
2722
  const timeoutMs = this.requestTimeoutMs;
2469
- return new Promise((resolve4, reject) => {
2470
- const call = { resolve: resolve4, reject };
2723
+ return new Promise((resolve7, reject) => {
2724
+ const call = { resolve: resolve7, reject };
2471
2725
  if (timeoutMs) {
2472
2726
  call.timer = setTimeout(() => {
2473
2727
  if (!this.pending.has(id)) return;
@@ -2536,18 +2790,13 @@ var WorkerClient = class {
2536
2790
  }
2537
2791
  };
2538
2792
 
2539
- // src/shared/worker-client/functions/create-worker-client.function.ts
2540
- var import_node_fs8 = require("node:fs");
2541
- var import_node_path11 = require("node:path");
2542
- var import_node_os4 = require("node:os");
2543
-
2544
2793
  // src/shared/worker-client/functions/resolve-db-path.function.ts
2545
- var import_node_fs6 = require("node:fs");
2794
+ var import_node_fs7 = require("node:fs");
2546
2795
  var import_node_path8 = require("node:path");
2547
2796
  function resolveDbPath(targetDir) {
2548
2797
  const base = targetDir ? (0, import_node_path8.resolve)(targetDir) : process.cwd();
2549
2798
  const dbPath = (0, import_node_path8.join)(base, ".kbdb");
2550
- if (!(0, import_node_fs6.existsSync)(dbPath)) {
2799
+ if (!(0, import_node_fs7.existsSync)(dbPath)) {
2551
2800
  const msg = `database not found: ${dbPath}`;
2552
2801
  log(msg, 3 /* ERROR */);
2553
2802
  throw new Error(msg);
@@ -2571,16 +2820,35 @@ async function computeContextId(absolutePath) {
2571
2820
 
2572
2821
  // src/shared/worker-client/functions/spawn-daemon.function.ts
2573
2822
  var import_node_child_process = require("node:child_process");
2574
- function spawnDaemon(contextPath, runtime2, workerScript2) {
2575
- if (!workerScript2) {
2823
+
2824
+ // src/shared/worker-client/functions/build-deno-permissions.function.ts
2825
+ function buildDenoPermissions() {
2826
+ return [
2827
+ "--allow-read",
2828
+ "--allow-write",
2829
+ "--allow-env",
2830
+ "--allow-run",
2831
+ "--allow-sys"
2832
+ ];
2833
+ }
2834
+
2835
+ // src/shared/worker-client/functions/spawn-daemon.function.ts
2836
+ function spawnDaemon(contextPath, runtime, workerScript) {
2837
+ if (!workerScript) {
2576
2838
  const msg = "workerScript must be provided (resolve at entry point)";
2577
2839
  log(msg, 3 /* ERROR */);
2578
2840
  throw new Error(msg);
2579
2841
  }
2580
- const execPath = runtime2 === "deno" ? "deno" : process.execPath;
2842
+ const execPath = runtime === "deno" ? "deno" : process.execPath;
2581
2843
  const logLevelEnv = process.env["KBDB_LOG_LEVEL"];
2582
2844
  const logArgs = logLevelEnv ? ["--log-level", logLevelEnv] : [];
2583
- const args = runtime2 === "deno" ? ["run", "--allow-all", workerScript2, contextPath, ...logArgs] : [workerScript2, contextPath, ...logArgs];
2845
+ const args = runtime === "deno" ? [
2846
+ "run",
2847
+ ...buildDenoPermissions(),
2848
+ workerScript,
2849
+ contextPath,
2850
+ ...logArgs
2851
+ ] : [workerScript, contextPath, ...logArgs];
2584
2852
  log(
2585
2853
  "spawning daemon: " + execPath + " " + args.join(" "),
2586
2854
  0 /* DEBUG */
@@ -2593,7 +2861,7 @@ function spawnDaemon(contextPath, runtime2, workerScript2) {
2593
2861
  }
2594
2862
 
2595
2863
  // src/shared/worker-client/functions/wait-for-daemon.function.ts
2596
- var import_node_fs7 = require("node:fs");
2864
+ var import_node_fs8 = require("node:fs");
2597
2865
  var import_node_path9 = require("node:path");
2598
2866
  var import_node_os2 = require("node:os");
2599
2867
  var DEFAULT_TIMEOUT_MS = 1e4;
@@ -2604,7 +2872,7 @@ async function waitForDaemon(contextId, timeoutMs = DEFAULT_TIMEOUT_MS) {
2604
2872
  const start = Date.now();
2605
2873
  let iteration = 0;
2606
2874
  while (Date.now() - start < timeoutMs) {
2607
- if ((0, import_node_fs7.existsSync)(pidPath)) {
2875
+ if ((0, import_node_fs8.existsSync)(pidPath)) {
2608
2876
  log("daemon PID file appeared", 0 /* DEBUG */);
2609
2877
  return true;
2610
2878
  }
@@ -2626,13 +2894,71 @@ async function waitForDaemon(contextId, timeoutMs = DEFAULT_TIMEOUT_MS) {
2626
2894
  return false;
2627
2895
  }
2628
2896
 
2629
- // src/shared/platform/functions/get-ipc-path.function.ts
2897
+ // src/shared/worker-client/functions/read-crash-reason.function.ts
2898
+ var import_node_fs9 = require("node:fs");
2630
2899
  var import_node_path10 = require("node:path");
2900
+ var import_node_os3 = require("node:os");
2901
+ function readCrashReason(contextId) {
2902
+ const crashPath = (0, import_node_path10.join)((0, import_node_os3.tmpdir)(), `kbdb-${contextId}.crash`);
2903
+ if (!(0, import_node_fs9.existsSync)(crashPath)) {
2904
+ return "daemon failed to start (no details available)";
2905
+ }
2906
+ try {
2907
+ const raw = (0, import_node_fs9.readFileSync)(crashPath, "utf-8");
2908
+ const crash = JSON.parse(raw);
2909
+ (0, import_node_fs9.unlinkSync)(crashPath);
2910
+ return crash.error ?? "unknown error (crash log empty)";
2911
+ } catch {
2912
+ return "daemon failed to start (crash log unreadable)";
2913
+ }
2914
+ }
2915
+
2916
+ // src/shared/worker-client/functions/resolve-spawn-script.function.ts
2917
+ var import_node_path12 = require("node:path");
2918
+ var import_node_url = require("node:url");
2919
+
2920
+ // src/shared/dir-resolver/functions/join-path.function.ts
2921
+ var import_node_path11 = require("node:path");
2922
+ function isRemoteUrl(path) {
2923
+ return path.startsWith("http://") || path.startsWith("https://");
2924
+ }
2925
+ function joinPath(base, ...segments) {
2926
+ if (isRemoteUrl(base)) {
2927
+ const trailing = base.endsWith("/") ? "" : "/";
2928
+ return base + trailing + segments.join("/");
2929
+ }
2930
+ return (0, import_node_path11.join)(base, ...segments);
2931
+ }
2932
+
2933
+ // src/shared/dir-resolver/functions/resolve-worker-script.function.ts
2934
+ function resolveWorkerScript(scriptDir, runtime) {
2935
+ if (runtime === "deno") {
2936
+ return joinPath(scriptDir, "worker.ts");
2937
+ }
2938
+ return joinPath(scriptDir, "kbdb-worker.cjs");
2939
+ }
2940
+
2941
+ // src/shared/worker-client/functions/resolve-spawn-script.function.ts
2942
+ var import_meta = {};
2943
+ function resolveSpawnScript(runtime) {
2944
+ return resolveWorkerScript(resolveScriptDir2(runtime), runtime);
2945
+ }
2946
+ function resolveScriptDir2(runtime) {
2947
+ if (typeof __dirname !== "undefined") return __dirname;
2948
+ const thisDir = (0, import_node_path12.dirname)((0, import_node_url.fileURLToPath)(import_meta.url));
2949
+ if (runtime === "deno") {
2950
+ return (0, import_node_path12.resolve)(thisDir, "..", "..", "..");
2951
+ }
2952
+ return thisDir;
2953
+ }
2954
+
2955
+ // src/shared/platform/functions/get-ipc-path.function.ts
2956
+ var import_node_path13 = require("node:path");
2631
2957
 
2632
2958
  // src/shared/platform/functions/get-tmpdir.function.ts
2633
- var import_node_os3 = require("node:os");
2959
+ var import_node_os4 = require("node:os");
2634
2960
  function getTmpdir() {
2635
- return (0, import_node_os3.tmpdir)();
2961
+ return (0, import_node_os4.tmpdir)();
2636
2962
  }
2637
2963
 
2638
2964
  // src/shared/platform/functions/get-ipc-path.function.ts
@@ -2640,7 +2966,7 @@ function getIpcPath(ctx) {
2640
2966
  if (process.platform === "win32") {
2641
2967
  return `\\\\.\\pipe\\kbdb-${ctx}`;
2642
2968
  }
2643
- return (0, import_node_path10.join)(getTmpdir(), `kbdb-${ctx}.sock`);
2969
+ return (0, import_node_path13.join)(getTmpdir(), `kbdb-${ctx}.sock`);
2644
2970
  }
2645
2971
 
2646
2972
  // src/shared/worker-client/functions/create-worker-client.function.ts
@@ -2656,9 +2982,10 @@ async function createWorkerClient(options) {
2656
2982
  log("no daemon found", 0 /* DEBUG */);
2657
2983
  }
2658
2984
  if (!daemon && options?.autoSpawn !== false) {
2659
- const runtime2 = detectRuntime();
2985
+ const runtime = detectRuntime();
2660
2986
  log("auto-spawning daemon", 0 /* DEBUG */);
2661
- spawnDaemon(dbPath, runtime2, options?.workerScript);
2987
+ const workerScript = resolveSpawnScript(runtime);
2988
+ spawnDaemon(dbPath, runtime, workerScript);
2662
2989
  log("waiting for daemon after spawn", 0 /* DEBUG */);
2663
2990
  await waitForDaemon(contextId, options?.connectTimeoutMs);
2664
2991
  daemon = discoverDaemon(contextId);
@@ -2677,20 +3004,6 @@ async function createWorkerClient(options) {
2677
3004
  await client.connect();
2678
3005
  return client;
2679
3006
  }
2680
- function readCrashReason(contextId) {
2681
- const crashPath = (0, import_node_path11.join)((0, import_node_os4.tmpdir)(), `kbdb-${contextId}.crash`);
2682
- if (!(0, import_node_fs8.existsSync)(crashPath)) {
2683
- return "daemon failed to start (no details available)";
2684
- }
2685
- try {
2686
- const raw = (0, import_node_fs8.readFileSync)(crashPath, "utf-8");
2687
- const crash = JSON.parse(raw);
2688
- (0, import_node_fs8.unlinkSync)(crashPath);
2689
- return crash.error ?? "unknown error (crash log empty)";
2690
- } catch {
2691
- return "daemon failed to start (crash log unreadable)";
2692
- }
2693
- }
2694
3007
 
2695
3008
  // src/shared/cli/functions/run-worker-stop.function.ts
2696
3009
  async function runWorkerStop(dbDir) {
@@ -2754,11 +3067,6 @@ async function runWorkerRestart(dbDir) {
2754
3067
  };
2755
3068
  }
2756
3069
 
2757
- // src/shared/cli/functions/resolve-raw-db-path.function.ts
2758
- function resolveRawDbPath(options) {
2759
- return options.dbPath ?? process.env["KBDB_DB_DIR"];
2760
- }
2761
-
2762
3070
  // src/shared/worker-client/functions/retry-on-timeout.function.ts
2763
3071
  async function retryOnTimeout(createClient, operation, maxRetries) {
2764
3072
  let lastError = new Error("retryOnTimeout exhausted");
@@ -2859,9 +3167,6 @@ async function runCli(argv, deps2) {
2859
3167
  }
2860
3168
  const nonInteractive = options.nonInteractive || process.env["KBDB_NON_INTERACTIVE"] === "1" || process.env["KBDB_NON_INTERACTIVE"] === "true";
2861
3169
  const effectiveDeps = nonInteractive ? { ...deps2, isStdinTty: () => false } : deps2;
2862
- if (!options.formatExplicit) {
2863
- options.format = effectiveDeps.isStdoutTty() ? "text" : "json";
2864
- }
2865
3170
  if (options.command === "help" || !options.command) {
2866
3171
  const helpCommand = options.args[0];
2867
3172
  const helpSubcommand = options.args[1];
@@ -2877,6 +3182,9 @@ async function runCli(argv, deps2) {
2877
3182
  if (options.command === "init" || options.command === "db-init") {
2878
3183
  return handleInit(options, effectiveDeps);
2879
3184
  }
3185
+ if (options.command === "db-path") {
3186
+ return runDbPath(options, effectiveDeps.findDb);
3187
+ }
2880
3188
  if (options.command === "mcp") {
2881
3189
  return handleMcp(options, effectiveDeps);
2882
3190
  }
@@ -2919,14 +3227,20 @@ function resolveRetryCount(options) {
2919
3227
  return options.retry ?? (parseInt(process.env["KBDB_RETRY"] ?? "", 10) || DEFAULT_RETRY_COUNT);
2920
3228
  }
2921
3229
  async function handleMcp(options, deps2) {
2922
- const explicitPath = resolveRawDbPath(options);
2923
- const dbDir = deps2.findDb(explicitPath);
2924
- if (!dbDir) {
3230
+ const resolution = resolveDbDir(
3231
+ { dbPath: options.dbPath, skipTraversal: true },
3232
+ deps2.findDb
3233
+ );
3234
+ if (!resolution) {
2925
3235
  return {
2926
- error: "error: no .kbdb database found at " + (explicitPath ?? process.cwd()),
3236
+ error: formatDbNotFound({
3237
+ dbPath: options.dbPath,
3238
+ skipTraversal: true
3239
+ }),
2927
3240
  exitCode: 1
2928
3241
  };
2929
3242
  }
3243
+ const dbDir = resolution.path;
2930
3244
  const timeoutMs = resolveTimeoutMs(options);
2931
3245
  const maxRetries = resolveRetryCount(options);
2932
3246
  let client;
@@ -2965,14 +3279,17 @@ async function handleMcp(options, deps2) {
2965
3279
  }
2966
3280
  }
2967
3281
  async function handleMigrate(options, deps2) {
2968
- const dbDir = deps2.findDb(options.dbPath);
2969
- if (!dbDir) {
2970
- const basePath = options.dbPath ?? process.cwd();
3282
+ const resolution = resolveDbDir(
3283
+ { dbPath: options.dbPath },
3284
+ deps2.findDb
3285
+ );
3286
+ if (!resolution) {
2971
3287
  return {
2972
- error: `error: no .kbdb database found at ${basePath}`,
3288
+ error: formatDbNotFound({ dbPath: options.dbPath }),
2973
3289
  exitCode: 1
2974
3290
  };
2975
3291
  }
3292
+ const dbDir = resolution.path;
2976
3293
  let client;
2977
3294
  try {
2978
3295
  client = await deps2.createWorkerClient({
@@ -3010,13 +3327,18 @@ async function handleMigrate(options, deps2) {
3010
3327
  }
3011
3328
  }
3012
3329
  async function handleDataCommand(options, deps2) {
3013
- const explicitPath = resolveRawDbPath(options);
3014
- let dbDir = deps2.findDb(explicitPath);
3330
+ const resolution = resolveDbDir(
3331
+ { dbPath: options.dbPath },
3332
+ deps2.findDb
3333
+ );
3334
+ let dbDir = resolution?.path ?? null;
3015
3335
  if (!dbDir) {
3016
- const basePath = explicitPath ?? process.cwd();
3336
+ const basePath = options.dbPath ?? process.cwd();
3017
3337
  if (!deps2.isStdinTty()) {
3018
3338
  return {
3019
- error: `error: no .kbdb database found at ${basePath} -- run \`kbdb --init\` to create one`,
3339
+ error: formatDbNotFound({
3340
+ dbPath: options.dbPath
3341
+ }),
3020
3342
  exitCode: 1
3021
3343
  };
3022
3344
  }
@@ -3064,14 +3386,17 @@ async function handleDataCommand(options, deps2) {
3064
3386
  }
3065
3387
  }
3066
3388
  async function handleWorkerLifecycle(options, deps2, action) {
3067
- const explicitPath = resolveRawDbPath(options);
3068
- const dbDir = deps2.findDb(explicitPath);
3069
- if (!dbDir) {
3389
+ const resolution = resolveDbDir(
3390
+ { dbPath: options.dbPath },
3391
+ deps2.findDb
3392
+ );
3393
+ if (!resolution) {
3070
3394
  return {
3071
- error: "error: no .kbdb database found at " + (explicitPath ?? process.cwd()),
3395
+ error: formatDbNotFound({ dbPath: options.dbPath }),
3072
3396
  exitCode: 1
3073
3397
  };
3074
3398
  }
3399
+ const dbDir = resolution.path;
3075
3400
  return action(dbDir);
3076
3401
  }
3077
3402
  async function versionGate(client, dbDir) {
@@ -4651,7 +4976,7 @@ var McpServer = class {
4651
4976
  });
4652
4977
  log("MCP server listening on stdin", 0 /* DEBUG */);
4653
4978
  let pending = Promise.resolve();
4654
- await new Promise((resolve4) => {
4979
+ await new Promise((resolve7) => {
4655
4980
  rl.on("line", (line) => {
4656
4981
  pending = pending.then(() => this.dispatchLine(line));
4657
4982
  });
@@ -4661,7 +4986,7 @@ var McpServer = class {
4661
4986
  this.autoCaptureController = null;
4662
4987
  this.client.disconnect();
4663
4988
  log("MCP stdin closed", 0 /* DEBUG */);
4664
- resolve4();
4989
+ resolve7();
4665
4990
  });
4666
4991
  });
4667
4992
  });
@@ -4705,13 +5030,13 @@ var McpServer = class {
4705
5030
  const id = this.nextRequestId++;
4706
5031
  const request = { jsonrpc: "2.0", id, method, params };
4707
5032
  process.stdout.write(JSON.stringify(request) + "\n");
4708
- return new Promise((resolve4, reject) => {
5033
+ return new Promise((resolve7, reject) => {
4709
5034
  const timer = setTimeout(() => {
4710
5035
  this.pendingRequests.delete(id);
4711
5036
  reject(new Error(`Request ${method} timed out`));
4712
5037
  }, 3e4);
4713
5038
  this.pendingRequests.set(id, {
4714
- resolve: resolve4,
5039
+ resolve: resolve7,
4715
5040
  reject,
4716
5041
  timer
4717
5042
  });
@@ -5143,28 +5468,21 @@ function parseWorkerToml(text, contextPath) {
5143
5468
  }
5144
5469
 
5145
5470
  // src/cli.ts
5146
- var import_meta = {};
5147
- var runtime = detectRuntime();
5148
- var baseDir = resolveBaseDir(import_meta.url, import_meta.dirname);
5149
- var workerScript = resolveWorkerScript(baseDir.scriptDir, runtime);
5150
5471
  var deps = {
5151
5472
  isStdinTty,
5152
5473
  isStdoutTty: () => process.stdout.isTTY,
5153
5474
  promptUser,
5154
- createWorkerClient: (opts) => createWorkerClient({ ...opts, workerScript }),
5475
+ createWorkerClient: (opts) => createWorkerClient(opts),
5155
5476
  findDb,
5156
5477
  runInit,
5157
5478
  startMcpServer: async (contextPath, clientFactory, maxRetries) => {
5158
5479
  log("starting MCP server", 1 /* INFO */);
5159
- const client = await createWorkerClient({
5160
- contextPath,
5161
- workerScript
5162
- });
5480
+ const client = await createWorkerClient({ contextPath });
5163
5481
  try {
5164
- const tomlPath = (0, import_node_path12.join)(contextPath, "worker.toml");
5482
+ const tomlPath = (0, import_node_path14.join)(contextPath, "worker.toml");
5165
5483
  let autoCaptureConfig;
5166
5484
  try {
5167
- const tomlText = (0, import_node_fs9.readFileSync)(tomlPath, "utf-8");
5485
+ const tomlText = (0, import_node_fs10.readFileSync)(tomlPath, "utf-8");
5168
5486
  const daemonConfig = parseWorkerToml(tomlText, contextPath);
5169
5487
  autoCaptureConfig = daemonConfig.autoCapture;
5170
5488
  } catch {