@dikolab/kbdb 0.3.2 → 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.
- package/README.md +92 -90
- package/dist/chunk-BJXEVALU.mjs +337 -0
- package/dist/chunk-BJXEVALU.mjs.map +7 -0
- package/dist/cli.cjs +1398 -378
- package/dist/cli.cjs.map +4 -4
- package/dist/cli.d.ts +9 -0
- package/dist/cli.mjs +1138 -342
- package/dist/cli.mjs.map +4 -4
- package/dist/kbdb-worker.cjs +1115 -135
- package/dist/kbdb-worker.cjs.map +4 -4
- package/dist/mod.cjs +351 -69
- package/dist/mod.cjs.map +4 -4
- package/dist/mod.d.ts +23 -2
- package/dist/mod.mjs +349 -68
- package/dist/mod.mjs.map +4 -4
- package/dist/src/shared/cli/functions/dispatch-command.function.d.ts +2 -1
- package/dist/src/shared/cli/functions/find-db.function.d.ts +7 -8
- package/dist/src/shared/cli/functions/handle-mcp.function.d.ts +1 -1
- package/dist/src/shared/cli/functions/parse-args.function.d.ts +4 -3
- package/dist/src/shared/cli/functions/resolve-kbid-prefix.function.d.ts +27 -0
- package/dist/src/shared/cli/functions/resolve-raw-db-path.function.d.ts +10 -0
- package/dist/src/shared/cli/functions/run-cli.function.d.ts +3 -1
- package/dist/src/shared/cli/functions/run-content.function.d.ts +8 -3
- package/dist/src/shared/cli/functions/run-import.function.d.ts +27 -0
- package/dist/src/shared/cli/functions/run-recall.function.d.ts +10 -4
- package/dist/src/shared/cli/functions/run-search.function.d.ts +7 -0
- package/dist/src/shared/cli/functions/run-unlearn.function.d.ts +9 -4
- package/dist/src/shared/cli/functions/run-worker-restart.function.d.ts +11 -0
- package/dist/src/shared/cli/functions/run-worker-stop.function.d.ts +11 -0
- package/dist/src/shared/cli/index.d.ts +2 -0
- package/dist/src/shared/cli/typings/cli-deps.interface.d.ts +4 -1
- package/dist/src/shared/cli/typings/cli-options.interface.d.ts +22 -0
- package/dist/src/shared/cli/typings/dispatch-client.type.d.ts +2 -1
- package/dist/src/shared/cli/typings/search-display.model.d.ts +6 -0
- package/dist/src/shared/embedding/classes/api-embedding-provider.class.d.ts +33 -0
- package/dist/src/shared/embedding/classes/onnx-embedding-provider.class.d.ts +33 -0
- package/dist/src/shared/embedding/classes/tfidf-embedding-provider.class.d.ts +28 -0
- package/dist/src/shared/embedding/constants/tfidf-defaults.constant.d.ts +4 -0
- package/dist/src/shared/embedding/functions/append-vector-entry.function.d.ts +14 -0
- package/dist/src/shared/embedding/functions/create-embedding-provider.function.d.ts +15 -0
- package/dist/src/shared/embedding/functions/detect-stale-vectors.function.d.ts +16 -0
- package/dist/src/shared/embedding/functions/parse-api-embedding-response.function.d.ts +11 -0
- package/dist/src/shared/embedding/functions/rebuild-vectors.function.d.ts +15 -0
- package/dist/src/shared/embedding/functions/scan-semantic-contradictions.function.d.ts +13 -0
- package/dist/src/shared/embedding/index.d.ts +9 -0
- package/dist/src/shared/embedding/typings/semantic-contradiction.model.d.ts +21 -0
- package/dist/src/shared/embedding/typings/stale-vectors-report.model.d.ts +16 -0
- package/dist/src/shared/log/constants/log-colors.constant.d.ts +5 -0
- package/dist/src/shared/log/constants/log-defaults.constant.d.ts +3 -0
- package/dist/src/shared/log/constants/log-icons.constant.d.ts +3 -0
- package/dist/src/shared/log/functions/configure-log.function.d.ts +12 -0
- package/dist/src/shared/log/functions/log.function.d.ts +28 -0
- package/dist/src/shared/log/functions/parse-log-level.function.d.ts +10 -0
- package/dist/src/shared/log/functions/resolve-log-level.function.d.ts +12 -0
- package/dist/src/shared/log/functions/write-stderr.function.d.ts +10 -0
- package/dist/src/shared/log/index.d.ts +10 -0
- package/dist/src/shared/log/typings/log-config.interface.d.ts +7 -0
- package/dist/src/shared/log/typings/log-level.type.d.ts +7 -0
- package/dist/src/shared/log/typings/log-output.interface.d.ts +4 -0
- package/dist/src/shared/mcp/classes/mcp-server.class.d.ts +22 -2
- package/dist/src/shared/mcp/functions/create-mcp-server.function.d.ts +6 -1
- package/dist/src/shared/mcp/functions/has-sampling-capability.function.d.ts +8 -0
- package/dist/src/shared/mcp/functions/run-auto-capture.function.d.ts +26 -0
- package/dist/src/shared/mcp/typings/mcp-client.interface.d.ts +2 -0
- package/dist/src/shared/mcp/typings/mcp-integrity-check-result.model.d.ts +24 -0
- package/dist/src/shared/mcp/typings/mcp-worker-client.interface.d.ts +3 -1
- package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
- package/dist/src/shared/wasm-codec/typings/paged-search-result.model.d.ts +2 -0
- package/dist/src/shared/worker-client/classes/worker-client.class.d.ts +38 -1
- package/dist/src/shared/worker-client/constants/request-timeout.constant.d.ts +2 -0
- package/dist/src/shared/worker-client/constants/retry-defaults.constant.d.ts +2 -0
- package/dist/src/shared/worker-client/functions/get-or-create-client.function.d.ts +20 -0
- package/dist/src/shared/worker-client/functions/retry-on-timeout.function.d.ts +18 -0
- package/dist/src/shared/worker-client/index.d.ts +4 -1
- package/dist/src/shared/worker-client/typings/import-result.model.d.ts +16 -0
- package/dist/src/shared/worker-client/typings/integrity-check-result.model.d.ts +24 -0
- package/dist/src/shared/worker-client/typings/search-params.model.d.ts +4 -0
- package/dist/src/shared/worker-client/typings/search-result.model.d.ts +6 -0
- package/dist/src/shared/worker-client/typings/worker-client-options.interface.d.ts +7 -0
- package/dist/src/shared/worker-daemon/classes/worker-daemon.class.d.ts +6 -0
- package/dist/src/shared/worker-daemon/functions/create-ipc-server.function.d.ts +11 -11
- package/dist/src/shared/worker-daemon/functions/embed-after-learn.function.d.ts +13 -0
- package/dist/src/shared/worker-daemon/functions/handle-hybrid-search.function.d.ts +44 -0
- package/dist/src/shared/worker-daemon/functions/handle-import.function.d.ts +14 -0
- package/dist/src/shared/worker-daemon/functions/handle-read-ops.function.d.ts +7 -1
- package/dist/src/shared/worker-daemon/functions/handle-write-ops.function.d.ts +9 -4
- package/dist/src/shared/worker-daemon/functions/run-worker.function.d.ts +6 -1
- package/dist/src/shared/worker-daemon/typings/handler-context.interface.d.ts +3 -0
- package/dist/src/shared/worker-daemon/typings/wasm-modules.interface.d.ts +5 -0
- package/dist/wasm/default-embedding/kbdb_default_embedding.d.ts +55 -0
- package/dist/wasm/default-embedding/kbdb_default_embedding.js +156 -0
- package/{src/wasm/query-parser/kbdb_query_parser_bg.wasm → dist/wasm/default-embedding/kbdb_default_embedding_bg.wasm} +0 -0
- package/dist/wasm/default-embedding/kbdb_default_embedding_bg.wasm.d.ts +12 -0
- package/dist/wasm/default-embedding/package.json +13 -0
- package/dist/wasm/fs-database/kbdb_fs_database.d.ts +16 -85
- package/dist/wasm/fs-database/kbdb_fs_database.js +16 -85
- package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
- package/dist/wasm/fs-migration/kbdb_fs_migration.d.ts +38 -0
- package/dist/wasm/fs-migration/kbdb_fs_migration.js +130 -0
- package/dist/wasm/fs-migration/kbdb_fs_migration_bg.wasm +0 -0
- package/dist/wasm/fs-migration/kbdb_fs_migration_bg.wasm.d.ts +9 -0
- package/dist/wasm/fs-migration/package.json +13 -0
- package/dist/wasm/kb-worker/kbdb_worker.d.ts +20 -115
- package/dist/wasm/kb-worker/kbdb_worker.js +20 -115
- package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
- package/dist/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
- package/dist/worker.d.ts +8 -0
- package/dist/worker.mjs +899 -143
- package/dist/worker.mjs.map +4 -4
- package/docs/details/README.md +4 -0
- package/docs/details/agent-tooling.md +132 -0
- package/docs/details/cli.md +91 -18
- package/docs/details/knowledge-base.md +180 -0
- package/docs/details/library-api.md +42 -2
- package/docs/details/mcp-server.md +53 -7
- package/docs/details/search-and-ranking.md +16 -11
- package/docs/goals/cli.md +142 -37
- package/docs/goals/content-parser.md +1 -1
- package/docs/goals/hybrid-search.md +71 -42
- package/docs/goals/mcp.md +24 -19
- package/docs/goals/overview.md +1 -1
- package/docs/goals/query-parser.md +8 -0
- package/docs/goals/semantic-dedup.md +7 -3
- package/docs/goals/worker-client.md +62 -1
- package/docs/goals/worker-daemon.md +83 -30
- package/docs/modules/overview.md +43 -22
- package/docs/modules/rust/embedding/module.md +91 -0
- package/docs/modules/rust/overview.md +56 -21
- package/docs/modules/rust/query-parser/functions/module.md +7 -5
- package/docs/modules/rust/query-parser/functions/pipeline.md +6 -138
- package/docs/modules/rust/query-parser/module.md +16 -22
- package/docs/modules/rust/query-parser/types/module.md +5 -4
- package/docs/modules/rust/query-parser/types/token.md +5 -1
- package/docs/modules/rust/shared/content-parser/functions.md +1 -1
- package/docs/modules/rust/shared/memory/module.md +1 -1
- package/docs/modules/rust/shared/module.md +33 -5
- package/docs/modules/rust/shared/pipeline/functions.md +141 -0
- package/docs/modules/rust/shared/pipeline/module.md +62 -0
- package/docs/modules/rust/shared/pipeline/types.md +43 -0
- package/docs/modules/rust/shared/section/module.md +1 -1
- package/docs/modules/rust/shared/section/types.md +1 -1
- package/docs/modules/typescript/cli.md +5 -3
- package/docs/modules/typescript/kbdb-worker.md +20 -5
- package/docs/modules/typescript/overview.md +28 -6
- package/docs/modules/typescript/shared/cli/functions.md +131 -17
- package/docs/modules/typescript/shared/cli/module.md +33 -20
- package/docs/modules/typescript/shared/cli/typings.md +25 -0
- package/docs/modules/typescript/shared/embedding/functions.md +125 -19
- package/docs/modules/typescript/shared/embedding/module.md +10 -4
- package/docs/modules/typescript/shared/embedding/typings.md +7 -5
- package/docs/modules/typescript/shared/log/constants.md +82 -0
- package/docs/modules/typescript/shared/log/functions.md +131 -0
- package/docs/modules/typescript/shared/log/module.md +153 -0
- package/docs/modules/typescript/shared/log/typings.md +82 -0
- package/docs/modules/typescript/shared/mcp/module.md +1 -1
- package/docs/modules/typescript/shared/mcp/typings.md +8 -1
- package/docs/modules/typescript/shared/module.md +22 -6
- package/docs/modules/typescript/shared/worker-client/module.md +9 -1
- package/docs/modules/typescript/shared/worker-client/typings.md +3 -0
- package/docs/modules/typescript/shared/worker-daemon/functions.md +19 -6
- package/docs/modules/typescript/shared/worker-daemon/module.md +11 -5
- package/docs/modules/typescript/shared/worker-daemon/typings.md +13 -7
- package/docs/overview.md +1 -2
- package/docs/release-notes/0.4.0.md +80 -0
- package/docs/release-notes/0.4.1.md +149 -0
- package/docs/release-notes/README.md +1 -0
- package/mod.ts +33 -15
- package/package.json +12 -11
- package/dist/chunk-JG2UCKLI.mjs +0 -95
- package/dist/chunk-JG2UCKLI.mjs.map +0 -7
- package/src/cli.ts +0 -71
- package/src/shared/auto-capture/classes/auto-capture-controller.class.ts +0 -62
- package/src/shared/auto-capture/constants/auto-capture-defaults.constant.ts +0 -15
- package/src/shared/auto-capture/functions/build-capture-prompt.function.ts +0 -27
- package/src/shared/auto-capture/functions/evaluate-trigger.function.ts +0 -50
- package/src/shared/auto-capture/index.ts +0 -7
- package/src/shared/auto-capture/typings/auto-capture-config.interface.ts +0 -13
- package/src/shared/auto-capture/typings/auto-capture-state.interface.ts +0 -13
- package/src/shared/auto-capture/typings/auto-capture-trigger.interface.ts +0 -7
- package/src/shared/cli/constants/defaults.constant.ts +0 -19
- package/src/shared/cli/constants/global-help.constant.ts +0 -73
- package/src/shared/cli/constants/help-text.constant.ts +0 -4
- package/src/shared/cli/constants/leaf-help.constant.ts +0 -219
- package/src/shared/cli/constants/memory-protocol-body.constant.ts +0 -39
- package/src/shared/cli/constants/query-guidance-body.constant.ts +0 -37
- package/src/shared/cli/constants/subcommand-help.constant.ts +0 -195
- package/src/shared/cli/functions/collect-files.function.ts +0 -55
- package/src/shared/cli/functions/compute-section-kbid.function.ts +0 -49
- package/src/shared/cli/functions/dispatch-command.function.ts +0 -390
- package/src/shared/cli/functions/ensure-db.function.ts +0 -21
- package/src/shared/cli/functions/error-to-message.function.ts +0 -9
- package/src/shared/cli/functions/find-db.function.ts +0 -20
- package/src/shared/cli/functions/format-mcp-output.function.ts +0 -41
- package/src/shared/cli/functions/format-output.function.ts +0 -95
- package/src/shared/cli/functions/format-text-output.function.ts +0 -42
- package/src/shared/cli/functions/generate-group-help.function.ts +0 -41
- package/src/shared/cli/functions/generate-help.function.ts +0 -654
- package/src/shared/cli/functions/handle-data-command.function.ts +0 -67
- package/src/shared/cli/functions/handle-mcp.function.ts +0 -56
- package/src/shared/cli/functions/handle-migrate.function.ts +0 -64
- package/src/shared/cli/functions/hydrate-search-previews.function.ts +0 -29
- package/src/shared/cli/functions/install-default-skills.function.ts +0 -296
- package/src/shared/cli/functions/is-stdin-tty.function.ts +0 -12
- package/src/shared/cli/functions/parse-args.function.ts +0 -156
- package/src/shared/cli/functions/prompt-user.function.ts +0 -36
- package/src/shared/cli/functions/resolve-skill-names.function.ts +0 -43
- package/src/shared/cli/functions/run-agent-create.function.ts +0 -114
- package/src/shared/cli/functions/run-agent-delete.function.ts +0 -47
- package/src/shared/cli/functions/run-agent-get.function.ts +0 -166
- package/src/shared/cli/functions/run-agent-list.function.ts +0 -58
- package/src/shared/cli/functions/run-check.function.ts +0 -159
- package/src/shared/cli/functions/run-cli.function.ts +0 -299
- package/src/shared/cli/functions/run-content.function.ts +0 -47
- package/src/shared/cli/functions/run-db-init.function.ts +0 -44
- package/src/shared/cli/functions/run-db-migrate.function.ts +0 -40
- package/src/shared/cli/functions/run-export.function.ts +0 -40
- package/src/shared/cli/functions/run-gc.function.ts +0 -51
- package/src/shared/cli/functions/run-init.function.ts +0 -93
- package/src/shared/cli/functions/run-learn.function.ts +0 -223
- package/src/shared/cli/functions/run-migrate.function.ts +0 -85
- package/src/shared/cli/functions/run-rebuild.function.ts +0 -47
- package/src/shared/cli/functions/run-recall.function.ts +0 -66
- package/src/shared/cli/functions/run-search.function.ts +0 -133
- package/src/shared/cli/functions/run-skill-delete.function.ts +0 -47
- package/src/shared/cli/functions/run-skill-get.function.ts +0 -90
- package/src/shared/cli/functions/run-skill-learn.function.ts +0 -70
- package/src/shared/cli/functions/run-skill-list.function.ts +0 -74
- package/src/shared/cli/functions/run-status.function.ts +0 -29
- package/src/shared/cli/functions/run-unlearn.function.ts +0 -58
- package/src/shared/cli/functions/version-gate.function.ts +0 -44
- package/src/shared/cli/functions/wrap-command.function.ts +0 -34
- package/src/shared/cli/index.ts +0 -55
- package/src/shared/cli/typings/agent-create-client.interface.ts +0 -47
- package/src/shared/cli/typings/agent-get-client.interface.ts +0 -39
- package/src/shared/cli/typings/check-client.interface.ts +0 -66
- package/src/shared/cli/typings/cli-deps.interface.ts +0 -54
- package/src/shared/cli/typings/cli-options.interface.ts +0 -72
- package/src/shared/cli/typings/command-result.model.ts +0 -15
- package/src/shared/cli/typings/disconnectable-client.interface.ts +0 -29
- package/src/shared/cli/typings/dispatch-client.type.ts +0 -46
- package/src/shared/cli/typings/learn-client.interface.ts +0 -53
- package/src/shared/cli/typings/learn-io.interface.ts +0 -5
- package/src/shared/cli/typings/learn-result.model.ts +0 -27
- package/src/shared/cli/typings/search-client.interface.ts +0 -73
- package/src/shared/cli/typings/search-display.model.ts +0 -54
- package/src/shared/dir-resolver/functions/join-path.function.ts +0 -13
- package/src/shared/dir-resolver/functions/resolve-base-dir.function.ts +0 -25
- package/src/shared/dir-resolver/functions/resolve-wasm-dir.function.ts +0 -5
- package/src/shared/dir-resolver/functions/resolve-worker-script.function.ts +0 -13
- package/src/shared/dir-resolver/index.ts +0 -11
- package/src/shared/dir-resolver/typings/base-dir.interface.ts +0 -4
- package/src/shared/embedding/classes/null-embedding-provider.class.ts +0 -29
- package/src/shared/embedding/constants/near-duplicate-thresholds.constant.ts +0 -17
- package/src/shared/embedding/functions/build-vector-index.function.ts +0 -79
- package/src/shared/embedding/functions/cosine-similarity.function.ts +0 -31
- package/src/shared/embedding/functions/detect-near-duplicates.function.ts +0 -69
- package/src/shared/embedding/functions/jaccard-coefficient.function.ts +0 -26
- package/src/shared/embedding/functions/read-vector-index-meta.function.ts +0 -44
- package/src/shared/embedding/functions/rrf-fuse.function.ts +0 -33
- package/src/shared/embedding/functions/search-vectors.function.ts +0 -59
- package/src/shared/embedding/index.ts +0 -20
- package/src/shared/embedding/typings/embedding-config.interface.ts +0 -23
- package/src/shared/embedding/typings/embedding-provider.interface.ts +0 -25
- package/src/shared/embedding/typings/near-duplicate-candidate.model.ts +0 -25
- package/src/shared/embedding/typings/near-duplicate-result.model.ts +0 -26
- package/src/shared/embedding/typings/vector-index-entry.model.ts +0 -13
- package/src/shared/embedding/typings/vector-index-meta.model.ts +0 -14
- package/src/shared/embedding/typings/vector-search-result.model.ts +0 -8
- package/src/shared/hash/functions/compute-sha256.ts +0 -17
- package/src/shared/hash/index.ts +0 -1
- package/src/shared/mcp/classes/mcp-server.class.ts +0 -480
- package/src/shared/mcp/constants/mcp-error-codes.constant.ts +0 -30
- package/src/shared/mcp/constants/tool-agent-create.constant.ts +0 -39
- package/src/shared/mcp/constants/tool-agent-delete.constant.ts +0 -26
- package/src/shared/mcp/constants/tool-agent-get.constant.ts +0 -24
- package/src/shared/mcp/constants/tool-agent-list.constant.ts +0 -18
- package/src/shared/mcp/constants/tool-auto-capture-review.constant.ts +0 -32
- package/src/shared/mcp/constants/tool-check.constant.ts +0 -21
- package/src/shared/mcp/constants/tool-content.constant.ts +0 -29
- package/src/shared/mcp/constants/tool-export.constant.ts +0 -27
- package/src/shared/mcp/constants/tool-gc.constant.ts +0 -21
- package/src/shared/mcp/constants/tool-learn.constant.ts +0 -58
- package/src/shared/mcp/constants/tool-rebuild.constant.ts +0 -21
- package/src/shared/mcp/constants/tool-recall.constant.ts +0 -36
- package/src/shared/mcp/constants/tool-retrieve.constant.ts +0 -31
- package/src/shared/mcp/constants/tool-search.constant.ts +0 -51
- package/src/shared/mcp/constants/tool-skill-delete.constant.ts +0 -24
- package/src/shared/mcp/constants/tool-skill-get.constant.ts +0 -27
- package/src/shared/mcp/constants/tool-skill-learn.constant.ts +0 -37
- package/src/shared/mcp/constants/tool-skill-list.constant.ts +0 -18
- package/src/shared/mcp/constants/tool-status.constant.ts +0 -20
- package/src/shared/mcp/constants/tool-unlearn.constant.ts +0 -25
- package/src/shared/mcp/functions/as-boolean-or-undefined.function.ts +0 -11
- package/src/shared/mcp/functions/as-string-array-or-undefined.function.ts +0 -17
- package/src/shared/mcp/functions/as-string-array.function.ts +0 -15
- package/src/shared/mcp/functions/as-string.function.ts +0 -10
- package/src/shared/mcp/functions/build-skills-text.function.ts +0 -43
- package/src/shared/mcp/functions/create-mcp-server.function.ts +0 -14
- package/src/shared/mcp/functions/create-prompt-definitions.function.ts +0 -102
- package/src/shared/mcp/functions/create-resource-templates.function.ts +0 -23
- package/src/shared/mcp/functions/create-tool-definitions.function.ts +0 -530
- package/src/shared/mcp/functions/extract-skill-arguments.function.ts +0 -27
- package/src/shared/mcp/functions/handle-agent-create.function.ts +0 -116
- package/src/shared/mcp/functions/handle-agent-delete.function.ts +0 -50
- package/src/shared/mcp/functions/handle-agent-get.function.ts +0 -160
- package/src/shared/mcp/functions/handle-agent-list.function.ts +0 -50
- package/src/shared/mcp/functions/handle-agent-prompt.function.ts +0 -68
- package/src/shared/mcp/functions/handle-completion.function.ts +0 -114
- package/src/shared/mcp/functions/handle-mcp-request.function.ts +0 -202
- package/src/shared/mcp/functions/handle-prompt-get.function.ts +0 -220
- package/src/shared/mcp/functions/handle-recall.function.ts +0 -66
- package/src/shared/mcp/functions/handle-resource-read.function.ts +0 -56
- package/src/shared/mcp/functions/handle-roots-list.function.ts +0 -29
- package/src/shared/mcp/functions/handle-skill-prompt.function.ts +0 -44
- package/src/shared/mcp/functions/handle-tool-auto-capture-review.function.ts +0 -24
- package/src/shared/mcp/functions/handle-tool-call.function.ts +0 -560
- package/src/shared/mcp/functions/handle-tool-check.function.ts +0 -21
- package/src/shared/mcp/functions/handle-tool-content.function.ts +0 -23
- package/src/shared/mcp/functions/handle-tool-export.function.ts +0 -25
- package/src/shared/mcp/functions/handle-tool-gc.function.ts +0 -21
- package/src/shared/mcp/functions/handle-tool-learn.function.ts +0 -69
- package/src/shared/mcp/functions/handle-tool-rebuild.function.ts +0 -21
- package/src/shared/mcp/functions/handle-tool-retrieve.function.ts +0 -40
- package/src/shared/mcp/functions/handle-tool-search.function.ts +0 -47
- package/src/shared/mcp/functions/handle-tool-skill-delete.function.ts +0 -34
- package/src/shared/mcp/functions/handle-tool-skill-get.function.ts +0 -59
- package/src/shared/mcp/functions/handle-tool-skill-learn.function.ts +0 -61
- package/src/shared/mcp/functions/handle-tool-skill-list.function.ts +0 -39
- package/src/shared/mcp/functions/handle-tool-status.function.ts +0 -21
- package/src/shared/mcp/functions/handle-tool-unlearn.function.ts +0 -24
- package/src/shared/mcp/functions/parse-agent-meta.function.ts +0 -27
- package/src/shared/mcp/functions/parse-skill-arguments.function.ts +0 -36
- package/src/shared/mcp/functions/parse-skill-content.function.ts +0 -38
- package/src/shared/mcp/functions/read-agent-meta.function.ts +0 -41
- package/src/shared/mcp/functions/resolve-skill-refs.function.ts +0 -50
- package/src/shared/mcp/functions/run-startup-health-check.function.ts +0 -34
- package/src/shared/mcp/functions/serialize-skill-content.function.ts +0 -12
- package/src/shared/mcp/functions/should-emit-log.function.ts +0 -38
- package/src/shared/mcp/index.ts +0 -28
- package/src/shared/mcp/typings/agent-types.interface.ts +0 -39
- package/src/shared/mcp/typings/log-types.interface.ts +0 -26
- package/src/shared/mcp/typings/mcp-capabilities.interface.ts +0 -16
- package/src/shared/mcp/typings/mcp-client.interface.ts +0 -317
- package/src/shared/mcp/typings/mcp-completion.interface.ts +0 -45
- package/src/shared/mcp/typings/mcp-content-result.model.ts +0 -9
- package/src/shared/mcp/typings/mcp-export-result.model.ts +0 -11
- package/src/shared/mcp/typings/mcp-gc-result.model.ts +0 -15
- package/src/shared/mcp/typings/mcp-integrity-check-result.model.ts +0 -17
- package/src/shared/mcp/typings/mcp-integrity-error.model.ts +0 -15
- package/src/shared/mcp/typings/mcp-notification.interface.ts +0 -9
- package/src/shared/mcp/typings/mcp-rebuild-result.model.ts +0 -9
- package/src/shared/mcp/typings/mcp-request.interface.ts +0 -11
- package/src/shared/mcp/typings/mcp-resource-result.interface.ts +0 -12
- package/src/shared/mcp/typings/mcp-resource-template.interface.ts +0 -11
- package/src/shared/mcp/typings/mcp-response.interface.ts +0 -18
- package/src/shared/mcp/typings/mcp-server-info.interface.ts +0 -7
- package/src/shared/mcp/typings/mcp-server-state.interface.ts +0 -17
- package/src/shared/mcp/typings/mcp-tool-annotations.interface.ts +0 -32
- package/src/shared/mcp/typings/mcp-tool-definition.interface.ts +0 -16
- package/src/shared/mcp/typings/mcp-tool-result.interface.ts +0 -19
- package/src/shared/mcp/typings/mcp-types.interface.ts +0 -158
- package/src/shared/mcp/typings/mcp-worker-client.interface.ts +0 -243
- package/src/shared/mcp/typings/prompt-types.interface.ts +0 -39
- package/src/shared/mcp/typings/remove-section-result.model.ts +0 -10
- package/src/shared/mcp/typings/sampling-types.interface.ts +0 -48
- package/src/shared/mcp/typings/skill-types.interface.ts +0 -29
- package/src/shared/mcp/typings/tool-call-result.model.ts +0 -18
- package/src/shared/mod.ts +0 -1
- package/src/shared/platform/functions/get-ipc-path.function.ts +0 -19
- package/src/shared/platform/functions/get-tmpdir.function.ts +0 -8
- package/src/shared/platform/functions/is-process-alive.function.ts +0 -17
- package/src/shared/platform/index.ts +0 -3
- package/src/shared/runtime/functions/detect-runtime.ts +0 -14
- package/src/shared/runtime/functions/get-args.ts +0 -16
- package/src/shared/runtime/index.ts +0 -3
- package/src/shared/runtime/typings/runtime.ts +0 -2
- package/src/shared/sync/functions/build-import-report.function.ts +0 -40
- package/src/shared/sync/functions/parse-export-entry.function.ts +0 -45
- package/src/shared/sync/functions/resolve-conflict.function.ts +0 -31
- package/src/shared/sync/functions/serialize-export-entry.function.ts +0 -18
- package/src/shared/sync/index.ts +0 -9
- package/src/shared/sync/typings/conflict-resolution.type.ts +0 -8
- package/src/shared/sync/typings/export-entry.interface.ts +0 -13
- package/src/shared/sync/typings/export-options.interface.ts +0 -9
- package/src/shared/sync/typings/import-options.interface.ts +0 -7
- package/src/shared/sync/typings/import-report.interface.ts +0 -15
- package/src/shared/version/constants/version.constant.ts +0 -2
- package/src/shared/version/index.ts +0 -1
- package/src/shared/wasm-codec/functions/decode-add-section-result.function.ts +0 -112
- package/src/shared/wasm-codec/functions/decode-compose-output.function.ts +0 -16
- package/src/shared/wasm-codec/functions/decode-document-manifest-list.function.ts +0 -70
- package/src/shared/wasm-codec/functions/decode-document-manifest.function.ts +0 -87
- package/src/shared/wasm-codec/functions/decode-f32.function.ts +0 -16
- package/src/shared/wasm-codec/functions/decode-key-value-text.function.ts +0 -15
- package/src/shared/wasm-codec/functions/decode-one-recall-result.function.ts +0 -86
- package/src/shared/wasm-codec/functions/decode-option-string.function.ts +0 -24
- package/src/shared/wasm-codec/functions/decode-recall-document.function.ts +0 -59
- package/src/shared/wasm-codec/functions/decode-recall-reference.function.ts +0 -52
- package/src/shared/wasm-codec/functions/decode-recall-result.function.ts +0 -267
- package/src/shared/wasm-codec/functions/decode-recall-sibling.function.ts +0 -43
- package/src/shared/wasm-codec/functions/decode-remove-flag.function.ts +0 -3
- package/src/shared/wasm-codec/functions/decode-scored-results.function.ts +0 -194
- package/src/shared/wasm-codec/functions/decode-section-match.function.ts +0 -80
- package/src/shared/wasm-codec/functions/decode-section-record-list.function.ts +0 -20
- package/src/shared/wasm-codec/functions/decode-section-record-trailing.function.ts +0 -75
- package/src/shared/wasm-codec/functions/decode-section-record.function.ts +0 -85
- package/src/shared/wasm-codec/functions/decode-section-records.function.ts +0 -249
- package/src/shared/wasm-codec/functions/decode-section-type.function.ts +0 -30
- package/src/shared/wasm-codec/functions/decode-string.function.ts +0 -22
- package/src/shared/wasm-codec/functions/decode-u32.function.ts +0 -16
- package/src/shared/wasm-codec/functions/decode-u64.function.ts +0 -16
- package/src/shared/wasm-codec/functions/decode-wasm-list.function.ts +0 -31
- package/src/shared/wasm-codec/functions/encode-add-section-params.function.ts +0 -102
- package/src/shared/wasm-codec/functions/encode-group-params.function.ts +0 -28
- package/src/shared/wasm-codec/functions/encode-identifier-list.function.ts +0 -17
- package/src/shared/wasm-codec/functions/encode-kbid-list.function.ts +0 -17
- package/src/shared/wasm-codec/functions/encode-option-string.function.ts +0 -14
- package/src/shared/wasm-codec/functions/encode-recall-params.function.ts +0 -68
- package/src/shared/wasm-codec/functions/encode-search-params.function.ts +0 -12
- package/src/shared/wasm-codec/functions/encode-section-type.function.ts +0 -18
- package/src/shared/wasm-codec/functions/encode-string.function.ts +0 -9
- package/src/shared/wasm-codec/functions/encode-type-filter-param.function.ts +0 -13
- package/src/shared/wasm-codec/functions/encode-u32.function.ts +0 -5
- package/src/shared/wasm-codec/functions/encode-update-section-params.function.ts +0 -16
- package/src/shared/wasm-codec/index.ts +0 -49
- package/src/shared/wasm-codec/typings/add-section-input.model.ts +0 -45
- package/src/shared/wasm-codec/typings/add-section-result.model.ts +0 -28
- package/src/shared/wasm-codec/typings/document-manifest.model.ts +0 -20
- package/src/shared/wasm-codec/typings/document-section.model.ts +0 -12
- package/src/shared/wasm-codec/typings/item-decoder.type.ts +0 -10
- package/src/shared/wasm-codec/typings/near-duplicate.model.ts +0 -16
- package/src/shared/wasm-codec/typings/paged-search-result.model.ts +0 -22
- package/src/shared/wasm-codec/typings/section-match.model.ts +0 -31
- package/src/shared/wasm-codec/typings/section-record-trailing.model.ts +0 -38
- package/src/shared/wasm-codec/typings/section-record.model.ts +0 -66
- package/src/shared/wasm-codec/typings/section-type-result.model.ts +0 -12
- package/src/shared/worker-client/classes/worker-client.class.ts +0 -466
- package/src/shared/worker-client/functions/compute-context-id.function.ts +0 -18
- package/src/shared/worker-client/functions/create-worker-client.function.ts +0 -70
- package/src/shared/worker-client/functions/discover-daemon.function.ts +0 -47
- package/src/shared/worker-client/functions/handle-ipc-data.function.ts +0 -49
- package/src/shared/worker-client/functions/resolve-db-path.function.ts +0 -21
- package/src/shared/worker-client/functions/send-ipc-request.function.ts +0 -39
- package/src/shared/worker-client/functions/spawn-daemon.function.ts +0 -35
- package/src/shared/worker-client/functions/wait-for-daemon.function.ts +0 -34
- package/src/shared/worker-client/index.ts +0 -44
- package/src/shared/worker-client/typings/add-section-result.model.ts +0 -39
- package/src/shared/worker-client/typings/content-result.model.ts +0 -12
- package/src/shared/worker-client/typings/daemon-info.model.ts +0 -7
- package/src/shared/worker-client/typings/export-result.model.ts +0 -14
- package/src/shared/worker-client/typings/gc-result.model.ts +0 -18
- package/src/shared/worker-client/typings/integrity-check-result.model.ts +0 -43
- package/src/shared/worker-client/typings/json-rpc-response.interface.ts +0 -17
- package/src/shared/worker-client/typings/migrate-result.model.ts +0 -11
- package/src/shared/worker-client/typings/pending-call.interface.ts +0 -7
- package/src/shared/worker-client/typings/rebuild-result.model.ts +0 -12
- package/src/shared/worker-client/typings/recall-document.model.ts +0 -16
- package/src/shared/worker-client/typings/recall-params.model.ts +0 -15
- package/src/shared/worker-client/typings/recall-reference.model.ts +0 -32
- package/src/shared/worker-client/typings/recall-result.model.ts +0 -98
- package/src/shared/worker-client/typings/recall-sibling.model.ts +0 -11
- package/src/shared/worker-client/typings/recall-single-result.model.ts +0 -41
- package/src/shared/worker-client/typings/remove-section-result.model.ts +0 -7
- package/src/shared/worker-client/typings/search-params.model.ts +0 -14
- package/src/shared/worker-client/typings/search-result.model.ts +0 -43
- package/src/shared/worker-client/typings/section.model.ts +0 -43
- package/src/shared/worker-client/typings/status-result.model.ts +0 -14
- package/src/shared/worker-client/typings/version-status.model.ts +0 -28
- package/src/shared/worker-client/typings/worker-client-error.interface.ts +0 -8
- package/src/shared/worker-client/typings/worker-client-options.interface.ts +0 -30
- package/src/shared/worker-daemon/classes/ipc-error.class.ts +0 -22
- package/src/shared/worker-daemon/classes/worker-daemon.class.ts +0 -1291
- package/src/shared/worker-daemon/constants/daemon-defaults.constant.ts +0 -29
- package/src/shared/worker-daemon/constants/wasm-method-map.constant.ts +0 -69
- package/src/shared/worker-daemon/functions/build-ipc-error-response.function.ts +0 -16
- package/src/shared/worker-daemon/functions/check-catalog-version.function.ts +0 -54
- package/src/shared/worker-daemon/functions/check-preconditions.function.ts +0 -28
- package/src/shared/worker-daemon/functions/create-host-imports.function.ts +0 -328
- package/src/shared/worker-daemon/functions/create-ipc-server.function.ts +0 -87
- package/src/shared/worker-daemon/functions/detect-stale-pid.function.ts +0 -33
- package/src/shared/worker-daemon/functions/dispatch-request.function.ts +0 -190
- package/src/shared/worker-daemon/functions/handle-check-version.function.ts +0 -74
- package/src/shared/worker-daemon/functions/handle-config-method.function.ts +0 -27
- package/src/shared/worker-daemon/functions/handle-read-ops.function.ts +0 -236
- package/src/shared/worker-daemon/functions/handle-write-ops.function.ts +0 -257
- package/src/shared/worker-daemon/functions/load-wasm-modules.function.ts +0 -95
- package/src/shared/worker-daemon/functions/parse-auto-capture-section.function.ts +0 -51
- package/src/shared/worker-daemon/functions/parse-catalog-version.function.ts +0 -20
- package/src/shared/worker-daemon/functions/parse-embedding-section.function.ts +0 -38
- package/src/shared/worker-daemon/functions/parse-worker-toml.function.ts +0 -104
- package/src/shared/worker-daemon/functions/read-config.function.ts +0 -83
- package/src/shared/worker-daemon/functions/run-startup-integrity-check.function.ts +0 -55
- package/src/shared/worker-daemon/functions/run-worker.function.ts +0 -57
- package/src/shared/worker-daemon/functions/scan-near-duplicates.function.ts +0 -92
- package/src/shared/worker-daemon/functions/start-daemon.function.ts +0 -74
- package/src/shared/worker-daemon/functions/wasm-bridge.function.ts +0 -144
- package/src/shared/worker-daemon/functions/wasm-memory-helpers.function.ts +0 -41
- package/src/shared/worker-daemon/functions/write-lock.function.ts +0 -49
- package/src/shared/worker-daemon/index.ts +0 -16
- package/src/shared/worker-daemon/typings/allocator-ref.interface.ts +0 -16
- package/src/shared/worker-daemon/typings/daemon-config.interface.ts +0 -20
- package/src/shared/worker-daemon/typings/fs-adapter.interface.ts +0 -22
- package/src/shared/worker-daemon/typings/handler-context.interface.ts +0 -19
- package/src/shared/worker-daemon/typings/ipc-handler.interface.ts +0 -39
- package/src/shared/worker-daemon/typings/memory-ref.interface.ts +0 -13
- package/src/shared/worker-daemon/typings/wasm-fn.type.ts +0 -2
- package/src/shared/worker-daemon/typings/wasm-modules.interface.ts +0 -7
- package/src/shared/worker-daemon/typings/write-lock.interface.ts +0 -13
- package/src/wasm/fs-database/kbdb_fs_database.d.ts +0 -259
- package/src/wasm/fs-database/kbdb_fs_database.js +0 -515
- package/src/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
- package/src/wasm/fs-database/kbdb_fs_database_bg.wasm.d.ts +0 -35
- package/src/wasm/fs-database/package.json +0 -13
- package/src/wasm/kb-worker/kbdb_worker.d.ts +0 -650
- package/src/wasm/kb-worker/kbdb_worker.js +0 -1181
- package/src/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
- package/src/wasm/kb-worker/kbdb_worker_bg.wasm.d.ts +0 -77
- package/src/wasm/kb-worker/package.json +0 -13
- package/src/wasm/query-parser/kbdb_query_parser.d.ts +0 -195
- package/src/wasm/query-parser/kbdb_query_parser.js +0 -403
- package/src/wasm/query-parser/kbdb_query_parser_bg.wasm.d.ts +0 -25
- package/src/wasm/query-parser/package.json +0 -13
- package/src/worker.ts +0 -42
package/dist/cli.cjs
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
3
|
|
|
4
|
+
// src/cli.ts
|
|
5
|
+
var import_node_fs9 = require("node:fs");
|
|
6
|
+
var import_node_path12 = require("node:path");
|
|
7
|
+
|
|
4
8
|
// src/shared/runtime/functions/detect-runtime.ts
|
|
5
9
|
function detectRuntime() {
|
|
6
10
|
if (typeof globalThis !== "undefined" && "Deno" in globalThis) {
|
|
@@ -65,6 +69,26 @@ var SUPPORTED_EXTENSIONS = [
|
|
|
65
69
|
".adoc"
|
|
66
70
|
];
|
|
67
71
|
|
|
72
|
+
// src/shared/log/typings/log-level.type.ts
|
|
73
|
+
var LogLevel = /* @__PURE__ */ ((LogLevel2) => {
|
|
74
|
+
LogLevel2[LogLevel2["DEBUG"] = 0] = "DEBUG";
|
|
75
|
+
LogLevel2[LogLevel2["INFO"] = 1] = "INFO";
|
|
76
|
+
LogLevel2[LogLevel2["WARNING"] = 2] = "WARNING";
|
|
77
|
+
LogLevel2[LogLevel2["ERROR"] = 3] = "ERROR";
|
|
78
|
+
return LogLevel2;
|
|
79
|
+
})(LogLevel || {});
|
|
80
|
+
|
|
81
|
+
// src/shared/log/functions/parse-log-level.function.ts
|
|
82
|
+
var LOG_LEVEL_MAP = {
|
|
83
|
+
debug: 0 /* DEBUG */,
|
|
84
|
+
info: 1 /* INFO */,
|
|
85
|
+
warning: 2 /* WARNING */,
|
|
86
|
+
error: 3 /* ERROR */
|
|
87
|
+
};
|
|
88
|
+
function parseLogLevel(value) {
|
|
89
|
+
return LOG_LEVEL_MAP[value.toLowerCase()] ?? 2 /* WARNING */;
|
|
90
|
+
}
|
|
91
|
+
|
|
68
92
|
// src/shared/cli/functions/parse-args.function.ts
|
|
69
93
|
function parseArgs(argv) {
|
|
70
94
|
const options = {
|
|
@@ -88,19 +112,31 @@ function parseArgs(argv) {
|
|
|
88
112
|
}
|
|
89
113
|
return options;
|
|
90
114
|
case "--version":
|
|
91
|
-
case "-v":
|
|
92
115
|
options.command = "version";
|
|
93
116
|
return options;
|
|
117
|
+
case "-v":
|
|
118
|
+
case "--verbose": {
|
|
119
|
+
const next = argv[i + 1];
|
|
120
|
+
if (next && !next.startsWith("-")) {
|
|
121
|
+
options.logLevel = parseLogLevel(next);
|
|
122
|
+
i++;
|
|
123
|
+
} else {
|
|
124
|
+
options.logLevel = 2 /* WARNING */;
|
|
125
|
+
}
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case "-vv":
|
|
129
|
+
case "--verbose-info":
|
|
130
|
+
options.logLevel = 1 /* INFO */;
|
|
131
|
+
break;
|
|
132
|
+
case "-vvv":
|
|
133
|
+
case "--verbose-debug":
|
|
134
|
+
options.logLevel = 0 /* DEBUG */;
|
|
135
|
+
break;
|
|
94
136
|
case "--init":
|
|
95
|
-
console.error(
|
|
96
|
-
'warning: --init is deprecated, use "kbdb db init"'
|
|
97
|
-
);
|
|
98
137
|
options.command = "init";
|
|
99
138
|
break;
|
|
100
139
|
case "--migrate":
|
|
101
|
-
console.error(
|
|
102
|
-
'warning: --migrate is deprecated, use "kbdb db migrate"'
|
|
103
|
-
);
|
|
104
140
|
options.command = "migrate";
|
|
105
141
|
break;
|
|
106
142
|
case "--db":
|
|
@@ -109,6 +145,7 @@ function parseArgs(argv) {
|
|
|
109
145
|
case "--format":
|
|
110
146
|
case "-f":
|
|
111
147
|
options.format = argv[++i] ?? DEFAULT_FORMAT;
|
|
148
|
+
options.formatExplicit = true;
|
|
112
149
|
break;
|
|
113
150
|
case "--mode":
|
|
114
151
|
case "-m":
|
|
@@ -166,10 +203,31 @@ function parseArgs(argv) {
|
|
|
166
203
|
case "-c":
|
|
167
204
|
options.content = true;
|
|
168
205
|
break;
|
|
206
|
+
case "--relaxed":
|
|
207
|
+
options.relaxed = true;
|
|
208
|
+
break;
|
|
209
|
+
case "--from":
|
|
210
|
+
options.from = argv[++i];
|
|
211
|
+
break;
|
|
212
|
+
case "--dry-run":
|
|
213
|
+
options.dryRun = true;
|
|
214
|
+
break;
|
|
215
|
+
case "--export-format":
|
|
216
|
+
options.exportFormat = argv[++i] ?? "git";
|
|
217
|
+
break;
|
|
218
|
+
case "--timeout-ms":
|
|
219
|
+
options.timeoutMs = parseInt(argv[++i] ?? "", 10) || void 0;
|
|
220
|
+
break;
|
|
221
|
+
case "--retry":
|
|
222
|
+
options.retry = parseInt(argv[++i] ?? "", 10) || void 0;
|
|
223
|
+
break;
|
|
224
|
+
case "--non-interactive":
|
|
225
|
+
options.nonInteractive = true;
|
|
226
|
+
break;
|
|
169
227
|
default:
|
|
170
228
|
if (!options.command) {
|
|
171
229
|
options.command = arg;
|
|
172
|
-
} else if (!options.args.length && (options.command === "db" || options.command === "skill" || options.command === "agent")) {
|
|
230
|
+
} else if (!options.args.length && (options.command === "db" || options.command === "skill" || options.command === "agent" || options.command === "worker")) {
|
|
173
231
|
options.command = `${options.command}-${arg}`;
|
|
174
232
|
} else {
|
|
175
233
|
options.args.push(arg);
|
|
@@ -240,8 +298,67 @@ function formatMcp(paged) {
|
|
|
240
298
|
);
|
|
241
299
|
}
|
|
242
300
|
|
|
301
|
+
// src/shared/log/constants/log-colors.constant.ts
|
|
302
|
+
var ANSI_RESET = "\x1B[0m";
|
|
303
|
+
var LOG_COLORS = {
|
|
304
|
+
[0 /* DEBUG */]: "\x1B[37m",
|
|
305
|
+
[1 /* INFO */]: "\x1B[36m",
|
|
306
|
+
[2 /* WARNING */]: "\x1B[33m",
|
|
307
|
+
[3 /* ERROR */]: "\x1B[91m"
|
|
308
|
+
};
|
|
309
|
+
|
|
310
|
+
// src/shared/log/constants/log-icons.constant.ts
|
|
311
|
+
var LOG_ICONS = {
|
|
312
|
+
[0 /* DEBUG */]: "\u25B8",
|
|
313
|
+
[1 /* INFO */]: "\u2139",
|
|
314
|
+
[2 /* WARNING */]: "\u26A0",
|
|
315
|
+
[3 /* ERROR */]: "\u2716"
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
// src/shared/log/constants/log-defaults.constant.ts
|
|
319
|
+
var DEFAULT_LOG_LEVEL = 3 /* ERROR */;
|
|
320
|
+
|
|
321
|
+
// src/shared/log/functions/write-stderr.function.ts
|
|
322
|
+
function writeStderr(message) {
|
|
323
|
+
const g = globalThis;
|
|
324
|
+
const proc = g["process"];
|
|
325
|
+
if (proc?.stderr) {
|
|
326
|
+
proc.stderr.write(message);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
const deno = g["Deno"];
|
|
330
|
+
deno?.stderr.writeSync(new TextEncoder().encode(message));
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// src/shared/log/functions/log.function.ts
|
|
334
|
+
var currentLevel = DEFAULT_LOG_LEVEL;
|
|
335
|
+
var outputs = {
|
|
336
|
+
[0 /* DEBUG */]: writeStderr,
|
|
337
|
+
[1 /* INFO */]: writeStderr,
|
|
338
|
+
[2 /* WARNING */]: writeStderr,
|
|
339
|
+
[3 /* ERROR */]: writeStderr
|
|
340
|
+
};
|
|
341
|
+
function setLogLevel(level) {
|
|
342
|
+
currentLevel = level;
|
|
343
|
+
}
|
|
344
|
+
function setLogOutput(level, output) {
|
|
345
|
+
outputs[level] = output;
|
|
346
|
+
}
|
|
347
|
+
function log(message, level = 3 /* ERROR */) {
|
|
348
|
+
if (level < currentLevel) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
const color = LOG_COLORS[level];
|
|
352
|
+
const icon = LOG_ICONS[level];
|
|
353
|
+
const name = LogLevel[level];
|
|
354
|
+
const line = `${color}${icon} [${name}] ${message}${ANSI_RESET}
|
|
355
|
+
`;
|
|
356
|
+
outputs[level](line);
|
|
357
|
+
}
|
|
358
|
+
|
|
243
359
|
// src/shared/cli/functions/run-search.function.ts
|
|
244
360
|
async function runSearch(client, options) {
|
|
361
|
+
log("searching: " + options.args.join(" "), 0 /* DEBUG */);
|
|
245
362
|
const query = options.args.join(" ").trim();
|
|
246
363
|
if (!query) {
|
|
247
364
|
return {
|
|
@@ -258,8 +375,13 @@ async function runSearch(client, options) {
|
|
|
258
375
|
mode: options.mode,
|
|
259
376
|
limit: options.limit,
|
|
260
377
|
offset: options.offset,
|
|
261
|
-
algo: options.algo
|
|
378
|
+
algo: options.algo,
|
|
379
|
+
relaxed: options.relaxed
|
|
262
380
|
});
|
|
381
|
+
log(
|
|
382
|
+
"search returned " + results.total.toString() + " results",
|
|
383
|
+
0 /* DEBUG */
|
|
384
|
+
);
|
|
263
385
|
return {
|
|
264
386
|
items: results.items.map((r) => ({
|
|
265
387
|
kbid: r.kbid,
|
|
@@ -278,13 +400,41 @@ async function runSearch(client, options) {
|
|
|
278
400
|
offset: results.offset,
|
|
279
401
|
limit: results.limit,
|
|
280
402
|
has_more: results.has_more,
|
|
281
|
-
relaxed: results.relaxed ?? false
|
|
403
|
+
relaxed: results.relaxed ?? false,
|
|
404
|
+
elapsed_ms: results.elapsed_ms,
|
|
405
|
+
search_mode: results.search_mode,
|
|
406
|
+
retrieval_method: results.retrieval_method
|
|
282
407
|
};
|
|
283
408
|
}
|
|
284
409
|
|
|
410
|
+
// src/shared/cli/functions/resolve-kbid-prefix.function.ts
|
|
411
|
+
var SECTION_TYPES = ["text", "code", "image"];
|
|
412
|
+
async function resolveKbidPrefix(prefix, client) {
|
|
413
|
+
if (prefix.length >= 26) return prefix;
|
|
414
|
+
const seen = /* @__PURE__ */ new Set();
|
|
415
|
+
for (const type of SECTION_TYPES) {
|
|
416
|
+
const records = await client.listByType(type);
|
|
417
|
+
for (const r of records) {
|
|
418
|
+
if (r.kbid.startsWith(prefix)) seen.add(r.kbid);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
if (seen.size === 0) {
|
|
422
|
+
const msg = `no section matches prefix "${prefix}"`;
|
|
423
|
+
log(msg, 3 /* ERROR */);
|
|
424
|
+
throw new Error(msg);
|
|
425
|
+
}
|
|
426
|
+
if (seen.size > 1) {
|
|
427
|
+
const msg = `ambiguous prefix "${prefix}": ${seen.size.toString()} matches`;
|
|
428
|
+
log(msg, 3 /* ERROR */);
|
|
429
|
+
throw new Error(msg);
|
|
430
|
+
}
|
|
431
|
+
return [...seen][0];
|
|
432
|
+
}
|
|
433
|
+
|
|
285
434
|
// src/shared/cli/functions/run-recall.function.ts
|
|
286
435
|
var MAX_RECALL_DEPTH = 3;
|
|
287
436
|
async function runRecall(client, options) {
|
|
437
|
+
log("running recall", 0 /* DEBUG */);
|
|
288
438
|
if (options.args.length === 0) {
|
|
289
439
|
return { error: "no kbid provided" };
|
|
290
440
|
}
|
|
@@ -292,14 +442,18 @@ async function runRecall(client, options) {
|
|
|
292
442
|
MAX_RECALL_DEPTH,
|
|
293
443
|
Math.max(0, options.depth ?? 0)
|
|
294
444
|
);
|
|
295
|
-
|
|
296
|
-
|
|
445
|
+
const resolved = await Promise.all(
|
|
446
|
+
options.args.map((a) => resolveKbidPrefix(a, client))
|
|
447
|
+
);
|
|
448
|
+
if (resolved.length === 1) {
|
|
449
|
+
return client.recall({ kbid: resolved[0], depth });
|
|
297
450
|
}
|
|
298
|
-
return client.recall({ kbids:
|
|
451
|
+
return client.recall({ kbids: resolved, depth });
|
|
299
452
|
}
|
|
300
453
|
|
|
301
454
|
// src/shared/cli/functions/run-export.function.ts
|
|
302
455
|
async function runExport(client, options) {
|
|
456
|
+
log("running export", 0 /* DEBUG */);
|
|
303
457
|
const path = options.args[0];
|
|
304
458
|
return client.export({ path });
|
|
305
459
|
}
|
|
@@ -308,6 +462,10 @@ async function runExport(client, options) {
|
|
|
308
462
|
var import_node_fs = require("node:fs");
|
|
309
463
|
var import_node_path3 = require("node:path");
|
|
310
464
|
async function runLearn(client, options, io) {
|
|
465
|
+
log(
|
|
466
|
+
"learning " + options.args.length.toString() + " targets",
|
|
467
|
+
0 /* DEBUG */
|
|
468
|
+
);
|
|
311
469
|
const results = [];
|
|
312
470
|
let stdinConsumed = false;
|
|
313
471
|
const readStdin = io?.readStdin ?? readProcessStdin;
|
|
@@ -346,6 +504,10 @@ async function runLearn(client, options, io) {
|
|
|
346
504
|
);
|
|
347
505
|
}
|
|
348
506
|
}
|
|
507
|
+
log(
|
|
508
|
+
"learned " + results.length.toString() + " sections",
|
|
509
|
+
0 /* DEBUG */
|
|
510
|
+
);
|
|
349
511
|
return results;
|
|
350
512
|
}
|
|
351
513
|
function mapAddSectionResult(result, path, size) {
|
|
@@ -409,8 +571,10 @@ function isSupportedFile(path) {
|
|
|
409
571
|
|
|
410
572
|
// src/shared/cli/functions/run-unlearn.function.ts
|
|
411
573
|
async function runUnlearn(client, options) {
|
|
574
|
+
log("running unlearn", 0 /* DEBUG */);
|
|
412
575
|
const results = [];
|
|
413
|
-
for (const
|
|
576
|
+
for (const arg of options.args) {
|
|
577
|
+
const kbid = await resolveKbidPrefix(arg, client);
|
|
414
578
|
const result = await client.removeSection(kbid);
|
|
415
579
|
results.push({ kbid, removed: result.removed });
|
|
416
580
|
}
|
|
@@ -419,7 +583,11 @@ async function runUnlearn(client, options) {
|
|
|
419
583
|
|
|
420
584
|
// src/shared/cli/functions/run-content.function.ts
|
|
421
585
|
async function runContent(client, options) {
|
|
422
|
-
|
|
586
|
+
log("running content", 0 /* DEBUG */);
|
|
587
|
+
const resolved = await Promise.all(
|
|
588
|
+
options.args.map((a) => resolveKbidPrefix(a, client))
|
|
589
|
+
);
|
|
590
|
+
return client.content(resolved);
|
|
423
591
|
}
|
|
424
592
|
|
|
425
593
|
// src/shared/cli/functions/run-check.function.ts
|
|
@@ -433,6 +601,7 @@ function parseDivergentContent(encoded) {
|
|
|
433
601
|
}).filter((entry) => entry.kbids.length > 0);
|
|
434
602
|
}
|
|
435
603
|
async function runCheck(client, _options) {
|
|
604
|
+
log("running check", 0 /* DEBUG */);
|
|
436
605
|
const raw = await client.integrityCheck();
|
|
437
606
|
return {
|
|
438
607
|
ok: raw.ok,
|
|
@@ -447,11 +616,13 @@ async function runCheck(client, _options) {
|
|
|
447
616
|
|
|
448
617
|
// src/shared/cli/functions/run-gc.function.ts
|
|
449
618
|
async function runGc(client, _options) {
|
|
619
|
+
log("running gc", 0 /* DEBUG */);
|
|
450
620
|
return client.gc();
|
|
451
621
|
}
|
|
452
622
|
|
|
453
623
|
// src/shared/cli/functions/run-rebuild.function.ts
|
|
454
624
|
async function runRebuild(client, _options) {
|
|
625
|
+
log("running rebuild", 0 /* DEBUG */);
|
|
455
626
|
return client.rebuildIndexes();
|
|
456
627
|
}
|
|
457
628
|
|
|
@@ -459,9 +630,20 @@ async function runRebuild(client, _options) {
|
|
|
459
630
|
var import_node_fs2 = require("node:fs");
|
|
460
631
|
var import_node_path4 = require("node:path");
|
|
461
632
|
function findDb(dbPath) {
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
633
|
+
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;
|
|
636
|
+
}
|
|
637
|
+
let current = process.cwd();
|
|
638
|
+
let parent = (0, import_node_path4.dirname)(current);
|
|
639
|
+
while (parent !== current) {
|
|
640
|
+
const candidate2 = (0, import_node_path4.join)(current, ".kbdb");
|
|
641
|
+
if ((0, import_node_fs2.existsSync)(candidate2)) return candidate2;
|
|
642
|
+
current = parent;
|
|
643
|
+
parent = (0, import_node_path4.dirname)(current);
|
|
644
|
+
}
|
|
645
|
+
const candidate = (0, import_node_path4.join)(current, ".kbdb");
|
|
646
|
+
return (0, import_node_fs2.existsSync)(candidate) ? candidate : null;
|
|
465
647
|
}
|
|
466
648
|
|
|
467
649
|
// src/shared/cli/functions/run-init.function.ts
|
|
@@ -596,6 +778,7 @@ function createScaffold(dbDir) {
|
|
|
596
778
|
(0, import_node_fs4.writeFileSync)((0, import_node_path6.join)(dbDir, ".gitignore"), GITIGNORE);
|
|
597
779
|
}
|
|
598
780
|
function runInit(options) {
|
|
781
|
+
log("running init", 0 /* DEBUG */);
|
|
599
782
|
const basePath = options.dbPath ? (0, import_node_path6.resolve)(options.dbPath) : process.cwd();
|
|
600
783
|
const dbDir = (0, import_node_path6.join)(basePath, ".kbdb");
|
|
601
784
|
try {
|
|
@@ -647,11 +830,13 @@ function askReadline(question) {
|
|
|
647
830
|
|
|
648
831
|
// src/shared/cli/functions/run-status.function.ts
|
|
649
832
|
async function runStatus(client, _options) {
|
|
833
|
+
log("running status", 0 /* DEBUG */);
|
|
650
834
|
return client.dbStatus();
|
|
651
835
|
}
|
|
652
836
|
|
|
653
837
|
// src/shared/cli/functions/run-db-init.function.ts
|
|
654
838
|
function runDbInit(options, runInitFn) {
|
|
839
|
+
log("running db-init", 0 /* DEBUG */);
|
|
655
840
|
const result = runInitFn(options);
|
|
656
841
|
if (result.ok) {
|
|
657
842
|
return {
|
|
@@ -671,6 +856,7 @@ function runDbInit(options, runInitFn) {
|
|
|
671
856
|
|
|
672
857
|
// src/shared/cli/functions/run-db-migrate.function.ts
|
|
673
858
|
async function runDbMigrate(client, options) {
|
|
859
|
+
log("running db-migrate", 0 /* DEBUG */);
|
|
674
860
|
const dbPath = options.dbPath ?? process.cwd();
|
|
675
861
|
return client.migrateDatabase(dbPath);
|
|
676
862
|
}
|
|
@@ -698,6 +884,7 @@ function serializeSkillContent(skill) {
|
|
|
698
884
|
|
|
699
885
|
// src/shared/cli/functions/run-skill-learn.function.ts
|
|
700
886
|
async function runSkillLearn(client, options) {
|
|
887
|
+
log("running skill-learn", 0 /* DEBUG */);
|
|
701
888
|
const name = options.name;
|
|
702
889
|
if (!name) {
|
|
703
890
|
return { error: "--name is required", exitCode: 1 };
|
|
@@ -728,6 +915,7 @@ async function runSkillLearn(client, options) {
|
|
|
728
915
|
|
|
729
916
|
// src/shared/cli/functions/run-skill-list.function.ts
|
|
730
917
|
async function runSkillList(client, _options) {
|
|
918
|
+
log("running skill-list", 0 /* DEBUG */);
|
|
731
919
|
const records = await client.listByType("skill");
|
|
732
920
|
const items = records.map((r) => {
|
|
733
921
|
let argumentCount = 0;
|
|
@@ -755,9 +943,11 @@ async function runSkillList(client, _options) {
|
|
|
755
943
|
function parseSkillContent(json) {
|
|
756
944
|
const raw = JSON.parse(json);
|
|
757
945
|
if (typeof raw["name"] !== "string" || !raw["name"]) {
|
|
946
|
+
log("skill name is required", 3 /* ERROR */);
|
|
758
947
|
throw new Error("skill name is required");
|
|
759
948
|
}
|
|
760
949
|
if (typeof raw["body"] !== "string") {
|
|
950
|
+
log("skill body is required", 3 /* ERROR */);
|
|
761
951
|
throw new Error("skill body is required");
|
|
762
952
|
}
|
|
763
953
|
return {
|
|
@@ -770,6 +960,7 @@ function parseSkillContent(json) {
|
|
|
770
960
|
|
|
771
961
|
// src/shared/cli/functions/run-skill-get.function.ts
|
|
772
962
|
async function runSkillGet(client, options) {
|
|
963
|
+
log("running skill-get", 0 /* DEBUG */);
|
|
773
964
|
const identifier = options.args[0] ?? options.name;
|
|
774
965
|
if (!identifier) {
|
|
775
966
|
return {
|
|
@@ -806,6 +997,7 @@ async function runSkillGet(client, options) {
|
|
|
806
997
|
|
|
807
998
|
// src/shared/cli/functions/run-skill-delete.function.ts
|
|
808
999
|
async function runSkillDelete(client, options) {
|
|
1000
|
+
log("running skill-delete", 0 /* DEBUG */);
|
|
809
1001
|
const kbid = options.args[0];
|
|
810
1002
|
if (!kbid) {
|
|
811
1003
|
return { error: "kbid is required", exitCode: 1 };
|
|
@@ -823,6 +1015,7 @@ async function runSkillDelete(client, options) {
|
|
|
823
1015
|
|
|
824
1016
|
// src/shared/cli/functions/run-agent-create.function.ts
|
|
825
1017
|
async function runAgentCreate(client, options) {
|
|
1018
|
+
log("running agent-create", 0 /* DEBUG */);
|
|
826
1019
|
const name = options.name;
|
|
827
1020
|
if (!name) {
|
|
828
1021
|
return { error: "--name is required", exitCode: 1 };
|
|
@@ -868,6 +1061,7 @@ async function runAgentCreate(client, options) {
|
|
|
868
1061
|
|
|
869
1062
|
// src/shared/cli/functions/run-agent-list.function.ts
|
|
870
1063
|
async function runAgentList(client, _options) {
|
|
1064
|
+
log("running agent-list", 0 /* DEBUG */);
|
|
871
1065
|
const docs = await client.listDocumentsByType("agent");
|
|
872
1066
|
const items = docs.map((d) => ({
|
|
873
1067
|
docid: d.docid,
|
|
@@ -924,6 +1118,7 @@ async function resolveSkills(client, skillRefs) {
|
|
|
924
1118
|
});
|
|
925
1119
|
}
|
|
926
1120
|
async function runAgentGet(client, options) {
|
|
1121
|
+
log("running agent-get", 0 /* DEBUG */);
|
|
927
1122
|
const docid = options.args[0];
|
|
928
1123
|
if (!docid) {
|
|
929
1124
|
return { error: "docid is required", exitCode: 1 };
|
|
@@ -945,6 +1140,7 @@ async function runAgentGet(client, options) {
|
|
|
945
1140
|
|
|
946
1141
|
// src/shared/cli/functions/run-agent-delete.function.ts
|
|
947
1142
|
async function runAgentDelete(client, options) {
|
|
1143
|
+
log("running agent-delete", 0 /* DEBUG */);
|
|
948
1144
|
const docid = options.args[0];
|
|
949
1145
|
if (!docid) {
|
|
950
1146
|
return { error: "docid is required", exitCode: 1 };
|
|
@@ -956,8 +1152,23 @@ async function runAgentDelete(client, options) {
|
|
|
956
1152
|
};
|
|
957
1153
|
}
|
|
958
1154
|
|
|
1155
|
+
// src/shared/cli/functions/run-import.function.ts
|
|
1156
|
+
async function runImport(client, options) {
|
|
1157
|
+
const from = options.from;
|
|
1158
|
+
if (!from) {
|
|
1159
|
+
const msg = "import requires --from <path>";
|
|
1160
|
+
log(msg, 3 /* ERROR */);
|
|
1161
|
+
throw new Error(msg);
|
|
1162
|
+
}
|
|
1163
|
+
return client.import({
|
|
1164
|
+
from,
|
|
1165
|
+
dryRun: options.dryRun === true
|
|
1166
|
+
});
|
|
1167
|
+
}
|
|
1168
|
+
|
|
959
1169
|
// src/shared/cli/functions/dispatch-command.function.ts
|
|
960
1170
|
async function dispatchCommand(client, options, io) {
|
|
1171
|
+
log("dispatching command: " + options.command, 0 /* DEBUG */);
|
|
961
1172
|
switch (options.command) {
|
|
962
1173
|
case "learn":
|
|
963
1174
|
return handleLearn(client, options, io);
|
|
@@ -979,6 +1190,8 @@ async function dispatchCommand(client, options, io) {
|
|
|
979
1190
|
return handleStatus(client, options);
|
|
980
1191
|
case "export":
|
|
981
1192
|
return handleExport(client, options);
|
|
1193
|
+
case "import":
|
|
1194
|
+
return handleImport(client, options);
|
|
982
1195
|
case "db-init":
|
|
983
1196
|
return handleDbInit(options);
|
|
984
1197
|
case "db-migrate":
|
|
@@ -1016,6 +1229,7 @@ async function dispatchCommand(client, options, io) {
|
|
|
1016
1229
|
return result;
|
|
1017
1230
|
}
|
|
1018
1231
|
default:
|
|
1232
|
+
log("unknown command: " + options.command, 2 /* WARNING */);
|
|
1019
1233
|
return {
|
|
1020
1234
|
error: `unknown command: ${options.command}`,
|
|
1021
1235
|
exitCode: 1
|
|
@@ -1101,6 +1315,20 @@ async function handleExport(client, options) {
|
|
|
1101
1315
|
};
|
|
1102
1316
|
}
|
|
1103
1317
|
}
|
|
1318
|
+
async function handleImport(client, options) {
|
|
1319
|
+
try {
|
|
1320
|
+
const result = await runImport(client, options);
|
|
1321
|
+
return {
|
|
1322
|
+
output: JSON.stringify(result, null, 2),
|
|
1323
|
+
exitCode: 0
|
|
1324
|
+
};
|
|
1325
|
+
} catch (err) {
|
|
1326
|
+
return {
|
|
1327
|
+
error: `import failed: ${errorToMessage(err)}`,
|
|
1328
|
+
exitCode: 1
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
}
|
|
1104
1332
|
async function handleContent(client, options) {
|
|
1105
1333
|
try {
|
|
1106
1334
|
const result = await runContent(client, options);
|
|
@@ -1201,7 +1429,7 @@ async function hydrateSearchPreviews(client, paged) {
|
|
|
1201
1429
|
}
|
|
1202
1430
|
|
|
1203
1431
|
// src/shared/version/constants/version.constant.ts
|
|
1204
|
-
var VERSION = "0.
|
|
1432
|
+
var VERSION = "0.4.1";
|
|
1205
1433
|
|
|
1206
1434
|
// src/shared/cli/functions/generate-help.function.ts
|
|
1207
1435
|
var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
|
|
@@ -1218,7 +1446,8 @@ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
|
|
|
1218
1446
|
"mcp",
|
|
1219
1447
|
"db",
|
|
1220
1448
|
"skill",
|
|
1221
|
-
"agent"
|
|
1449
|
+
"agent",
|
|
1450
|
+
"worker"
|
|
1222
1451
|
]);
|
|
1223
1452
|
var GROUP_SUBCOMMANDS = {
|
|
1224
1453
|
db: [
|
|
@@ -1236,6 +1465,10 @@ var GROUP_SUBCOMMANDS = {
|
|
|
1236
1465
|
["list", "List all agents"],
|
|
1237
1466
|
["get", "Retrieve an agent by docid"],
|
|
1238
1467
|
["delete", "Remove an agent"]
|
|
1468
|
+
],
|
|
1469
|
+
worker: [
|
|
1470
|
+
["stop", "Stop the worker daemon"],
|
|
1471
|
+
["restart", "Restart the worker daemon"]
|
|
1239
1472
|
]
|
|
1240
1473
|
};
|
|
1241
1474
|
function isKnownCommand(cmd) {
|
|
@@ -1304,6 +1537,10 @@ Agents:
|
|
|
1304
1537
|
agent get Retrieve an agent by docid
|
|
1305
1538
|
agent delete Remove an agent
|
|
1306
1539
|
|
|
1540
|
+
Worker:
|
|
1541
|
+
worker stop Stop the worker daemon
|
|
1542
|
+
worker restart Restart the worker daemon
|
|
1543
|
+
|
|
1307
1544
|
Server:
|
|
1308
1545
|
mcp Start MCP server mode (stdio)
|
|
1309
1546
|
|
|
@@ -1349,7 +1586,8 @@ Run "kbdb ${group} <subcommand> --help" for details.
|
|
|
1349
1586
|
var GROUP_DESCRIPTIONS = {
|
|
1350
1587
|
db: "Database management",
|
|
1351
1588
|
skill: "Skill management",
|
|
1352
|
-
agent: "Agent management"
|
|
1589
|
+
agent: "Agent management",
|
|
1590
|
+
worker: "Worker daemon management"
|
|
1353
1591
|
};
|
|
1354
1592
|
var LEAF_HELP = {
|
|
1355
1593
|
learn: `kbdb learn - Import content from files or stdin
|
|
@@ -1535,11 +1773,11 @@ Options:
|
|
|
1535
1773
|
--db <path> Path to .kbdb directory
|
|
1536
1774
|
|
|
1537
1775
|
Environment:
|
|
1538
|
-
|
|
1776
|
+
KBDB_DB_DIR Fallback database path
|
|
1539
1777
|
|
|
1540
1778
|
Examples:
|
|
1541
1779
|
kbdb mcp --db /path/to/project
|
|
1542
|
-
|
|
1780
|
+
KBDB_DB_DIR=/path/to/project kbdb mcp
|
|
1543
1781
|
`
|
|
1544
1782
|
};
|
|
1545
1783
|
var SUBCOMMAND_HELP = {
|
|
@@ -1702,6 +1940,28 @@ Output:
|
|
|
1702
1940
|
|
|
1703
1941
|
Examples:
|
|
1704
1942
|
kbdb agent delete agent-code-reviewer
|
|
1943
|
+
`,
|
|
1944
|
+
"worker-stop": `kbdb worker stop - Stop the worker daemon
|
|
1945
|
+
|
|
1946
|
+
Usage: kbdb worker stop [options]
|
|
1947
|
+
|
|
1948
|
+
Options:
|
|
1949
|
+
--db <path> Path to .kbdb directory
|
|
1950
|
+
|
|
1951
|
+
Examples:
|
|
1952
|
+
kbdb worker stop
|
|
1953
|
+
kbdb worker stop --db /path/to/project
|
|
1954
|
+
`,
|
|
1955
|
+
"worker-restart": `kbdb worker restart - Restart the worker daemon
|
|
1956
|
+
|
|
1957
|
+
Usage: kbdb worker restart [options]
|
|
1958
|
+
|
|
1959
|
+
Options:
|
|
1960
|
+
--db <path> Path to .kbdb directory
|
|
1961
|
+
|
|
1962
|
+
Examples:
|
|
1963
|
+
kbdb worker restart
|
|
1964
|
+
kbdb worker restart --db /path/to/project
|
|
1705
1965
|
`
|
|
1706
1966
|
};
|
|
1707
1967
|
function generateSubcommandHelp(command, subcommand) {
|
|
@@ -1713,244 +1973,196 @@ function generateSubcommandHelp(command, subcommand) {
|
|
|
1713
1973
|
return generateCommandHelp(command);
|
|
1714
1974
|
}
|
|
1715
1975
|
|
|
1716
|
-
// src/shared/
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
if (options.command === "init" || options.command === "db-init") {
|
|
1732
|
-
return handleInit(options, deps2);
|
|
1976
|
+
// src/shared/worker-client/classes/worker-client.class.ts
|
|
1977
|
+
var import_node_net = require("node:net");
|
|
1978
|
+
|
|
1979
|
+
// src/shared/worker-client/functions/discover-daemon.function.ts
|
|
1980
|
+
var import_node_fs5 = require("node:fs");
|
|
1981
|
+
var import_node_path7 = require("node:path");
|
|
1982
|
+
var import_node_os = require("node:os");
|
|
1983
|
+
|
|
1984
|
+
// src/shared/platform/functions/is-process-alive.function.ts
|
|
1985
|
+
function isProcessAlive(pid) {
|
|
1986
|
+
try {
|
|
1987
|
+
process.kill(pid, 0);
|
|
1988
|
+
return true;
|
|
1989
|
+
} catch {
|
|
1990
|
+
return false;
|
|
1733
1991
|
}
|
|
1734
|
-
|
|
1735
|
-
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
// src/shared/worker-client/functions/discover-daemon.function.ts
|
|
1995
|
+
function discoverDaemon(contextId) {
|
|
1996
|
+
log("discovering daemon for context: " + contextId, 0 /* DEBUG */);
|
|
1997
|
+
const pidPath = (0, import_node_path7.join)((0, import_node_os.tmpdir)(), `kbdb-${contextId}.pid`);
|
|
1998
|
+
if (!(0, import_node_fs5.existsSync)(pidPath)) {
|
|
1999
|
+
log(
|
|
2000
|
+
"no daemon PID file found for context: " + contextId,
|
|
2001
|
+
0 /* DEBUG */
|
|
2002
|
+
);
|
|
2003
|
+
return null;
|
|
1736
2004
|
}
|
|
1737
|
-
|
|
1738
|
-
|
|
2005
|
+
const pidStr = (0, import_node_fs5.readFileSync)(pidPath, "utf-8").trim();
|
|
2006
|
+
const pid = parseInt(pidStr, 10);
|
|
2007
|
+
if (isNaN(pid) || !isProcessAlive(pid)) {
|
|
2008
|
+
log(
|
|
2009
|
+
"daemon process not alive for context: " + contextId,
|
|
2010
|
+
0 /* DEBUG */
|
|
2011
|
+
);
|
|
2012
|
+
try {
|
|
2013
|
+
(0, import_node_fs5.unlinkSync)(pidPath);
|
|
2014
|
+
} catch {
|
|
2015
|
+
}
|
|
2016
|
+
return null;
|
|
1739
2017
|
}
|
|
1740
|
-
|
|
1741
|
-
}
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
output: result.targetPath,
|
|
1747
|
-
exitCode: 0
|
|
1748
|
-
};
|
|
2018
|
+
log("daemon found: pid=" + pid.toString(), 0 /* DEBUG */);
|
|
2019
|
+
const socketPath = (0, import_node_path7.join)((0, import_node_os.tmpdir)(), `kbdb-${contextId}.sock`);
|
|
2020
|
+
const crashPath = (0, import_node_path7.join)((0, import_node_os.tmpdir)(), `kbdb-${contextId}.crash`);
|
|
2021
|
+
try {
|
|
2022
|
+
(0, import_node_fs5.unlinkSync)(crashPath);
|
|
2023
|
+
} catch {
|
|
1749
2024
|
}
|
|
1750
|
-
return {
|
|
1751
|
-
error: `error: ${result.errorMessage ?? "init failed"}`,
|
|
1752
|
-
exitCode: 1
|
|
1753
|
-
};
|
|
2025
|
+
return { pid, socketPath };
|
|
1754
2026
|
}
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
2027
|
+
|
|
2028
|
+
// src/shared/worker-client/classes/worker-client.class.ts
|
|
2029
|
+
var WorkerClient = class {
|
|
2030
|
+
/**
|
|
2031
|
+
* @param socketPath - absolute path to the daemon's IPC socket
|
|
2032
|
+
* (or Windows named pipe path)
|
|
2033
|
+
* @param contextId - 16-character context identifier sent as
|
|
2034
|
+
* `ctx` in every JSON-RPC request
|
|
2035
|
+
* @param requestTimeoutMs - per-request timeout in ms
|
|
2036
|
+
* (0 or undefined disables the timeout)
|
|
2037
|
+
*/
|
|
2038
|
+
constructor(socketPath, contextId, requestTimeoutMs) {
|
|
2039
|
+
this.socketPath = socketPath;
|
|
2040
|
+
this.contextId = contextId;
|
|
2041
|
+
this.requestTimeoutMs = requestTimeoutMs;
|
|
1762
2042
|
}
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
2043
|
+
/** Underlying socket; `null` when not connected. */
|
|
2044
|
+
socket = null;
|
|
2045
|
+
/** Monotonically increasing request ID counter. */
|
|
2046
|
+
nextId = 1;
|
|
2047
|
+
/** Map of outstanding request IDs to their resolve/reject pairs. */
|
|
2048
|
+
pending = /* @__PURE__ */ new Map();
|
|
2049
|
+
/** Partial line buffer for split TCP/IPC frames. */
|
|
2050
|
+
buffer = "";
|
|
2051
|
+
/** Whether the underlying socket is connected. */
|
|
2052
|
+
get isConnected() {
|
|
2053
|
+
return this.socket !== null;
|
|
1769
2054
|
}
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
2055
|
+
/**
|
|
2056
|
+
* Establishes the IPC connection to the worker daemon.
|
|
2057
|
+
*
|
|
2058
|
+
* Retries up to 5 times with exponential backoff on
|
|
2059
|
+
* transient errors (`ENOENT`, `ECONNREFUSED`).
|
|
2060
|
+
*
|
|
2061
|
+
* @throws {Error} if the connection cannot be established
|
|
2062
|
+
*/
|
|
2063
|
+
async connect() {
|
|
2064
|
+
log("connecting to " + this.socketPath, 0 /* DEBUG */);
|
|
2065
|
+
const maxRetries = 5;
|
|
2066
|
+
let delay = 50;
|
|
2067
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
2068
|
+
try {
|
|
2069
|
+
await this.tryConnect();
|
|
2070
|
+
log("connected", 0 /* DEBUG */);
|
|
2071
|
+
return;
|
|
2072
|
+
} catch (err) {
|
|
2073
|
+
const code = err.code;
|
|
2074
|
+
const retriable = code === "ENOENT" || code === "ECONNREFUSED";
|
|
2075
|
+
if (!retriable || attempt === maxRetries) {
|
|
2076
|
+
throw err;
|
|
2077
|
+
}
|
|
2078
|
+
log(
|
|
2079
|
+
"connect retry: attempt=" + attempt.toString() + " code=" + code + " delay=" + delay.toString() + "ms",
|
|
2080
|
+
0 /* DEBUG */
|
|
2081
|
+
);
|
|
2082
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
2083
|
+
delay = Math.min(delay * 2, 1e3);
|
|
2084
|
+
}
|
|
2085
|
+
}
|
|
1780
2086
|
}
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
if (
|
|
1785
|
-
|
|
2087
|
+
/** Destroys the IPC socket and clears the connection state. */
|
|
2088
|
+
disconnect() {
|
|
2089
|
+
log("disconnecting client", 0 /* DEBUG */);
|
|
2090
|
+
if (this.socket) {
|
|
2091
|
+
this.socket.destroy();
|
|
2092
|
+
this.socket = null;
|
|
1786
2093
|
}
|
|
1787
|
-
return { exitCode: 0 };
|
|
1788
|
-
} catch (err) {
|
|
1789
|
-
return {
|
|
1790
|
-
error: `error: mcp failed: ${errorToMessage(err)}`,
|
|
1791
|
-
exitCode: 1
|
|
1792
|
-
};
|
|
1793
|
-
} finally {
|
|
1794
|
-
client.disconnect();
|
|
1795
2094
|
}
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
2095
|
+
/**
|
|
2096
|
+
* Kills the daemon process and disconnects the client.
|
|
2097
|
+
*
|
|
2098
|
+
* Discovers the daemon via PID file and sends `SIGTERM`.
|
|
2099
|
+
* Always disconnects the socket regardless of kill outcome.
|
|
2100
|
+
*/
|
|
2101
|
+
killDaemon() {
|
|
2102
|
+
const info = discoverDaemon(this.contextId);
|
|
2103
|
+
log(
|
|
2104
|
+
"killing daemon: pid=" + (info ? info.pid.toString() : "unknown"),
|
|
2105
|
+
0 /* DEBUG */
|
|
2106
|
+
);
|
|
2107
|
+
if (info) {
|
|
2108
|
+
try {
|
|
2109
|
+
process.kill(info.pid, "SIGTERM");
|
|
2110
|
+
} catch {
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
this.disconnect();
|
|
1805
2114
|
}
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
2115
|
+
/**
|
|
2116
|
+
* Single connection attempt with keepalive and
|
|
2117
|
+
* post-connect failure handlers.
|
|
2118
|
+
*/
|
|
2119
|
+
async tryConnect() {
|
|
2120
|
+
return new Promise((resolve4, reject) => {
|
|
2121
|
+
const sock = (0, import_node_net.connect)(this.socketPath, () => {
|
|
2122
|
+
sock.removeListener("error", reject);
|
|
2123
|
+
sock.setKeepAlive(true, 3e4);
|
|
2124
|
+
sock.on("error", (err) => {
|
|
2125
|
+
log(
|
|
2126
|
+
"socket error: code=" + (err.code ?? err.message),
|
|
2127
|
+
0 /* DEBUG */
|
|
2128
|
+
);
|
|
2129
|
+
this.handleSocketFailure(err);
|
|
2130
|
+
});
|
|
2131
|
+
sock.on("close", () => {
|
|
2132
|
+
log("socket closed", 0 /* DEBUG */);
|
|
2133
|
+
if (this.pending.size > 0) {
|
|
2134
|
+
this.handleSocketFailure(
|
|
2135
|
+
new Error("connection closed")
|
|
2136
|
+
);
|
|
2137
|
+
}
|
|
2138
|
+
this.socket = null;
|
|
2139
|
+
});
|
|
2140
|
+
this.socket = sock;
|
|
2141
|
+
resolve4();
|
|
2142
|
+
});
|
|
2143
|
+
sock.on("error", reject);
|
|
2144
|
+
sock.on("data", (chunk) => {
|
|
2145
|
+
this.handleData(chunk.toString());
|
|
2146
|
+
});
|
|
1810
2147
|
});
|
|
1811
|
-
} catch (err) {
|
|
1812
|
-
return {
|
|
1813
|
-
error: `error: ${errorToMessage(err)}`,
|
|
1814
|
-
exitCode: 1
|
|
1815
|
-
};
|
|
1816
2148
|
}
|
|
1817
|
-
try {
|
|
1818
|
-
const versionStatus = await client.checkVersion(dbDir);
|
|
1819
|
-
if (versionStatus.status === "too_new") {
|
|
1820
|
-
return {
|
|
1821
|
-
error: `error: database version ${versionStatus.currentVersion.toString()} is newer than kbdb version ${versionStatus.requiredVersion.toString()} -- upgrade kbdb`,
|
|
1822
|
-
exitCode: 1
|
|
1823
|
-
};
|
|
1824
|
-
}
|
|
1825
|
-
if (versionStatus.status === "needs_migration") {
|
|
1826
|
-
const migrateResult = await client.migrateDatabase(dbDir);
|
|
1827
|
-
return {
|
|
1828
|
-
output: JSON.stringify(migrateResult, null, 2),
|
|
1829
|
-
exitCode: 0
|
|
1830
|
-
};
|
|
1831
|
-
}
|
|
1832
|
-
return { output: "already up to date", exitCode: 0 };
|
|
1833
|
-
} catch (err) {
|
|
1834
|
-
return {
|
|
1835
|
-
error: `error: migrate failed: ${errorToMessage(err)}`,
|
|
1836
|
-
exitCode: 1
|
|
1837
|
-
};
|
|
1838
|
-
} finally {
|
|
1839
|
-
client.disconnect();
|
|
1840
|
-
}
|
|
1841
|
-
}
|
|
1842
|
-
async function handleDataCommand(options, deps2) {
|
|
1843
|
-
let dbDir = deps2.findDb(options.dbPath);
|
|
1844
|
-
if (!dbDir) {
|
|
1845
|
-
const basePath = options.dbPath ?? process.cwd();
|
|
1846
|
-
if (!deps2.isStdinTty()) {
|
|
1847
|
-
return {
|
|
1848
|
-
error: `error: no .kbdb database found at ${basePath} -- run \`kbdb --init\` to create one`,
|
|
1849
|
-
exitCode: 1
|
|
1850
|
-
};
|
|
1851
|
-
}
|
|
1852
|
-
const answer = await deps2.promptUser(
|
|
1853
|
-
`No .kbdb database found. Create one in ${basePath}? [y/N] `
|
|
1854
|
-
);
|
|
1855
|
-
if (answer.toLowerCase() !== "y") {
|
|
1856
|
-
return {
|
|
1857
|
-
error: "aborted: no database created",
|
|
1858
|
-
exitCode: 1
|
|
1859
|
-
};
|
|
1860
|
-
}
|
|
1861
|
-
const initResult = deps2.runInit(options);
|
|
1862
|
-
if (!initResult.ok) {
|
|
1863
|
-
return {
|
|
1864
|
-
error: `error: ${initResult.errorMessage ?? "init failed"}`,
|
|
1865
|
-
exitCode: 1
|
|
1866
|
-
};
|
|
1867
|
-
}
|
|
1868
|
-
dbDir = initResult.targetPath;
|
|
1869
|
-
}
|
|
1870
|
-
let client;
|
|
1871
|
-
try {
|
|
1872
|
-
client = await deps2.createWorkerClient({
|
|
1873
|
-
contextPath: dbDir
|
|
1874
|
-
});
|
|
1875
|
-
} catch (err) {
|
|
1876
|
-
return {
|
|
1877
|
-
error: `error: ${errorToMessage(err)}`,
|
|
1878
|
-
exitCode: 1
|
|
1879
|
-
};
|
|
1880
|
-
}
|
|
1881
|
-
try {
|
|
1882
|
-
const gateResult = await versionGate(client, dbDir);
|
|
1883
|
-
if (gateResult) return gateResult;
|
|
1884
|
-
return await dispatchCommand(client, options);
|
|
1885
|
-
} finally {
|
|
1886
|
-
client.disconnect();
|
|
1887
|
-
}
|
|
1888
|
-
}
|
|
1889
|
-
async function versionGate(client, dbDir) {
|
|
1890
|
-
const versionStatus = await client.checkVersion(dbDir);
|
|
1891
|
-
if (versionStatus.status === "needs_migration") {
|
|
1892
|
-
return {
|
|
1893
|
-
error: "error: database needs migration -- run `kbdb --migrate`",
|
|
1894
|
-
exitCode: 1
|
|
1895
|
-
};
|
|
1896
|
-
}
|
|
1897
|
-
if (versionStatus.status === "too_new") {
|
|
1898
|
-
return {
|
|
1899
|
-
error: `error: database version ${versionStatus.currentVersion.toString()} is newer than kbdb version ${versionStatus.requiredVersion.toString()} -- upgrade kbdb`,
|
|
1900
|
-
exitCode: 1
|
|
1901
|
-
};
|
|
1902
|
-
}
|
|
1903
|
-
return null;
|
|
1904
|
-
}
|
|
1905
|
-
|
|
1906
|
-
// src/shared/cli/constants/help-text.constant.ts
|
|
1907
|
-
var HELP_TEXT = generateHelp();
|
|
1908
|
-
|
|
1909
|
-
// src/shared/worker-client/classes/worker-client.class.ts
|
|
1910
|
-
var import_node_net = require("node:net");
|
|
1911
|
-
var WorkerClient = class {
|
|
1912
|
-
/**
|
|
1913
|
-
* @param socketPath - absolute path to the daemon's IPC socket
|
|
1914
|
-
* (or Windows named pipe path)
|
|
1915
|
-
* @param contextId - 16-character context identifier sent as
|
|
1916
|
-
* `ctx` in every JSON-RPC request
|
|
1917
|
-
*/
|
|
1918
|
-
constructor(socketPath, contextId) {
|
|
1919
|
-
this.socketPath = socketPath;
|
|
1920
|
-
this.contextId = contextId;
|
|
1921
|
-
}
|
|
1922
|
-
/** Underlying socket; `null` when not connected. */
|
|
1923
|
-
socket = null;
|
|
1924
|
-
/** Monotonically increasing request ID counter. */
|
|
1925
|
-
nextId = 1;
|
|
1926
|
-
/** Map of outstanding request IDs to their resolve/reject pairs. */
|
|
1927
|
-
pending = /* @__PURE__ */ new Map();
|
|
1928
|
-
/** Partial line buffer for split TCP/IPC frames. */
|
|
1929
|
-
buffer = "";
|
|
1930
2149
|
/**
|
|
1931
|
-
*
|
|
1932
|
-
*
|
|
1933
|
-
* @throws {Error} if the connection cannot be established
|
|
2150
|
+
* Rejects all pending calls and marks the client as
|
|
2151
|
+
* disconnected.
|
|
1934
2152
|
*/
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
this.
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
});
|
|
1947
|
-
}
|
|
1948
|
-
/** Destroys the IPC socket and clears the connection state. */
|
|
1949
|
-
disconnect() {
|
|
1950
|
-
if (this.socket) {
|
|
1951
|
-
this.socket.destroy();
|
|
1952
|
-
this.socket = null;
|
|
2153
|
+
handleSocketFailure(err) {
|
|
2154
|
+
log(
|
|
2155
|
+
"socket failure: pending=" + this.pending.size.toString() + " err=" + err.message,
|
|
2156
|
+
0 /* DEBUG */
|
|
2157
|
+
);
|
|
2158
|
+
const sock = this.socket;
|
|
2159
|
+
this.socket = null;
|
|
2160
|
+
for (const [id, call] of this.pending) {
|
|
2161
|
+
this.pending.delete(id);
|
|
2162
|
+
if (call.timer) clearTimeout(call.timer);
|
|
2163
|
+
call.reject(err);
|
|
1953
2164
|
}
|
|
2165
|
+
if (sock) sock.destroy();
|
|
1954
2166
|
}
|
|
1955
2167
|
/**
|
|
1956
2168
|
* Searches the knowledge base.
|
|
@@ -1959,7 +2171,10 @@ var WorkerClient = class {
|
|
|
1959
2171
|
* @returns paginated search results with metadata
|
|
1960
2172
|
*/
|
|
1961
2173
|
async search(params) {
|
|
1962
|
-
return this.call("search",
|
|
2174
|
+
return this.call("search", {
|
|
2175
|
+
...params,
|
|
2176
|
+
algo: params.algo
|
|
2177
|
+
});
|
|
1963
2178
|
}
|
|
1964
2179
|
/**
|
|
1965
2180
|
* Retrieves full content and context for one or more sections by
|
|
@@ -2210,7 +2425,20 @@ var WorkerClient = class {
|
|
|
2210
2425
|
*/
|
|
2211
2426
|
async export(params) {
|
|
2212
2427
|
return this.call("export", {
|
|
2213
|
-
targetPath: params?.path || void 0
|
|
2428
|
+
targetPath: params?.path || void 0,
|
|
2429
|
+
format: params?.format
|
|
2430
|
+
});
|
|
2431
|
+
}
|
|
2432
|
+
/**
|
|
2433
|
+
* Imports an exported database from the given path.
|
|
2434
|
+
*
|
|
2435
|
+
* @param params - source path and dry-run flag
|
|
2436
|
+
* @returns import report with counts and timing
|
|
2437
|
+
*/
|
|
2438
|
+
async import(params) {
|
|
2439
|
+
return this.call("importDb", {
|
|
2440
|
+
sourcePath: params.from,
|
|
2441
|
+
dryRun: params.dryRun
|
|
2214
2442
|
});
|
|
2215
2443
|
}
|
|
2216
2444
|
/**
|
|
@@ -2227,14 +2455,35 @@ var WorkerClient = class {
|
|
|
2227
2455
|
throw new Error("not connected");
|
|
2228
2456
|
}
|
|
2229
2457
|
const id = this.nextId++;
|
|
2458
|
+
log(
|
|
2459
|
+
"call: method=" + method + " id=" + id.toString(),
|
|
2460
|
+
0 /* DEBUG */
|
|
2461
|
+
);
|
|
2230
2462
|
const request = {
|
|
2231
2463
|
jsonrpc: "2.0",
|
|
2232
2464
|
id,
|
|
2233
2465
|
method,
|
|
2234
2466
|
params: { ctx: this.contextId, ...params }
|
|
2235
2467
|
};
|
|
2468
|
+
const timeoutMs = this.requestTimeoutMs;
|
|
2236
2469
|
return new Promise((resolve4, reject) => {
|
|
2237
|
-
|
|
2470
|
+
const call = { resolve: resolve4, reject };
|
|
2471
|
+
if (timeoutMs) {
|
|
2472
|
+
call.timer = setTimeout(() => {
|
|
2473
|
+
if (!this.pending.has(id)) return;
|
|
2474
|
+
this.pending.delete(id);
|
|
2475
|
+
log(
|
|
2476
|
+
"request timeout after " + String(timeoutMs) + "ms",
|
|
2477
|
+
2 /* WARNING */
|
|
2478
|
+
);
|
|
2479
|
+
const err = new Error(
|
|
2480
|
+
`request timeout after ${String(timeoutMs)}ms`
|
|
2481
|
+
);
|
|
2482
|
+
err.code = "REQUEST_TIMEOUT";
|
|
2483
|
+
reject(err);
|
|
2484
|
+
}, timeoutMs);
|
|
2485
|
+
}
|
|
2486
|
+
this.pending.set(id, call);
|
|
2238
2487
|
socket.write(JSON.stringify(request) + "\n");
|
|
2239
2488
|
});
|
|
2240
2489
|
}
|
|
@@ -2255,15 +2504,33 @@ var WorkerClient = class {
|
|
|
2255
2504
|
const pending = this.pending.get(response.id);
|
|
2256
2505
|
if (pending) {
|
|
2257
2506
|
this.pending.delete(response.id);
|
|
2507
|
+
if (pending.timer) clearTimeout(pending.timer);
|
|
2258
2508
|
if (response.error) {
|
|
2509
|
+
log(
|
|
2510
|
+
"response error: id=" + response.id.toString() + " code=" + response.error.code.toString(),
|
|
2511
|
+
0 /* DEBUG */
|
|
2512
|
+
);
|
|
2259
2513
|
const err = new Error(response.error.message);
|
|
2260
2514
|
err.code = response.error.code;
|
|
2261
2515
|
pending.reject(err);
|
|
2262
2516
|
} else {
|
|
2517
|
+
log(
|
|
2518
|
+
"response ok: id=" + response.id.toString(),
|
|
2519
|
+
0 /* DEBUG */
|
|
2520
|
+
);
|
|
2263
2521
|
pending.resolve(response.result);
|
|
2264
2522
|
}
|
|
2523
|
+
} else {
|
|
2524
|
+
log(
|
|
2525
|
+
"unmatched response id=" + response.id.toString(),
|
|
2526
|
+
0 /* DEBUG */
|
|
2527
|
+
);
|
|
2265
2528
|
}
|
|
2266
|
-
} catch {
|
|
2529
|
+
} catch (parseErr) {
|
|
2530
|
+
log(
|
|
2531
|
+
"json parse error: " + parseErr.message,
|
|
2532
|
+
0 /* DEBUG */
|
|
2533
|
+
);
|
|
2267
2534
|
}
|
|
2268
2535
|
}
|
|
2269
2536
|
}
|
|
@@ -2275,13 +2542,15 @@ var import_node_path11 = require("node:path");
|
|
|
2275
2542
|
var import_node_os4 = require("node:os");
|
|
2276
2543
|
|
|
2277
2544
|
// src/shared/worker-client/functions/resolve-db-path.function.ts
|
|
2278
|
-
var
|
|
2279
|
-
var
|
|
2545
|
+
var import_node_fs6 = require("node:fs");
|
|
2546
|
+
var import_node_path8 = require("node:path");
|
|
2280
2547
|
function resolveDbPath(targetDir) {
|
|
2281
|
-
const base = targetDir ? (0,
|
|
2282
|
-
const dbPath = (0,
|
|
2283
|
-
if (!(0,
|
|
2284
|
-
|
|
2548
|
+
const base = targetDir ? (0, import_node_path8.resolve)(targetDir) : process.cwd();
|
|
2549
|
+
const dbPath = (0, import_node_path8.join)(base, ".kbdb");
|
|
2550
|
+
if (!(0, import_node_fs6.existsSync)(dbPath)) {
|
|
2551
|
+
const msg = `database not found: ${dbPath}`;
|
|
2552
|
+
log(msg, 3 /* ERROR */);
|
|
2553
|
+
throw new Error(msg);
|
|
2285
2554
|
}
|
|
2286
2555
|
return dbPath;
|
|
2287
2556
|
}
|
|
@@ -2300,129 +2569,531 @@ async function computeContextId(absolutePath) {
|
|
|
2300
2569
|
return hash.slice(0, 16);
|
|
2301
2570
|
}
|
|
2302
2571
|
|
|
2303
|
-
// src/shared/worker-client/functions/
|
|
2304
|
-
var
|
|
2305
|
-
|
|
2306
|
-
|
|
2572
|
+
// src/shared/worker-client/functions/spawn-daemon.function.ts
|
|
2573
|
+
var import_node_child_process = require("node:child_process");
|
|
2574
|
+
function spawnDaemon(contextPath, runtime2, workerScript2) {
|
|
2575
|
+
if (!workerScript2) {
|
|
2576
|
+
const msg = "workerScript must be provided (resolve at entry point)";
|
|
2577
|
+
log(msg, 3 /* ERROR */);
|
|
2578
|
+
throw new Error(msg);
|
|
2579
|
+
}
|
|
2580
|
+
const execPath = runtime2 === "deno" ? "deno" : process.execPath;
|
|
2581
|
+
const logLevelEnv = process.env["KBDB_LOG_LEVEL"];
|
|
2582
|
+
const logArgs = logLevelEnv ? ["--log-level", logLevelEnv] : [];
|
|
2583
|
+
const args = runtime2 === "deno" ? ["run", "--allow-all", workerScript2, contextPath, ...logArgs] : [workerScript2, contextPath, ...logArgs];
|
|
2584
|
+
log(
|
|
2585
|
+
"spawning daemon: " + execPath + " " + args.join(" "),
|
|
2586
|
+
0 /* DEBUG */
|
|
2587
|
+
);
|
|
2588
|
+
const child = (0, import_node_child_process.spawn)(execPath, args, {
|
|
2589
|
+
detached: true,
|
|
2590
|
+
stdio: "ignore"
|
|
2591
|
+
});
|
|
2592
|
+
child.unref();
|
|
2593
|
+
}
|
|
2307
2594
|
|
|
2308
|
-
// src/shared/
|
|
2309
|
-
|
|
2595
|
+
// src/shared/worker-client/functions/wait-for-daemon.function.ts
|
|
2596
|
+
var import_node_fs7 = require("node:fs");
|
|
2597
|
+
var import_node_path9 = require("node:path");
|
|
2598
|
+
var import_node_os2 = require("node:os");
|
|
2599
|
+
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
2600
|
+
var POLL_INTERVAL_MS = 100;
|
|
2601
|
+
async function waitForDaemon(contextId, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
2602
|
+
log("waiting for daemon: contextId=" + contextId, 0 /* DEBUG */);
|
|
2603
|
+
const pidPath = (0, import_node_path9.join)((0, import_node_os2.tmpdir)(), `kbdb-${contextId}.pid`);
|
|
2604
|
+
const start = Date.now();
|
|
2605
|
+
let iteration = 0;
|
|
2606
|
+
while (Date.now() - start < timeoutMs) {
|
|
2607
|
+
if ((0, import_node_fs7.existsSync)(pidPath)) {
|
|
2608
|
+
log("daemon PID file appeared", 0 /* DEBUG */);
|
|
2609
|
+
return true;
|
|
2610
|
+
}
|
|
2611
|
+
iteration++;
|
|
2612
|
+
if (iteration % 10 === 0) {
|
|
2613
|
+
const elapsed2 = Date.now() - start;
|
|
2614
|
+
log(
|
|
2615
|
+
"still waiting for daemon: elapsed=" + elapsed2.toString() + "ms",
|
|
2616
|
+
0 /* DEBUG */
|
|
2617
|
+
);
|
|
2618
|
+
}
|
|
2619
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
2620
|
+
}
|
|
2621
|
+
const elapsed = Date.now() - start;
|
|
2622
|
+
log(
|
|
2623
|
+
"timed out waiting for daemon: elapsed=" + elapsed.toString() + "ms",
|
|
2624
|
+
0 /* DEBUG */
|
|
2625
|
+
);
|
|
2626
|
+
return false;
|
|
2627
|
+
}
|
|
2628
|
+
|
|
2629
|
+
// src/shared/platform/functions/get-ipc-path.function.ts
|
|
2630
|
+
var import_node_path10 = require("node:path");
|
|
2631
|
+
|
|
2632
|
+
// src/shared/platform/functions/get-tmpdir.function.ts
|
|
2633
|
+
var import_node_os3 = require("node:os");
|
|
2634
|
+
function getTmpdir() {
|
|
2635
|
+
return (0, import_node_os3.tmpdir)();
|
|
2636
|
+
}
|
|
2637
|
+
|
|
2638
|
+
// src/shared/platform/functions/get-ipc-path.function.ts
|
|
2639
|
+
function getIpcPath(ctx) {
|
|
2640
|
+
if (process.platform === "win32") {
|
|
2641
|
+
return `\\\\.\\pipe\\kbdb-${ctx}`;
|
|
2642
|
+
}
|
|
2643
|
+
return (0, import_node_path10.join)(getTmpdir(), `kbdb-${ctx}.sock`);
|
|
2644
|
+
}
|
|
2645
|
+
|
|
2646
|
+
// src/shared/worker-client/functions/create-worker-client.function.ts
|
|
2647
|
+
async function createWorkerClient(options) {
|
|
2648
|
+
const dbPath = options?.contextPath ?? resolveDbPath(options?.dbPath);
|
|
2649
|
+
const contextId = await computeContextId(dbPath);
|
|
2650
|
+
log("create-worker-client: contextId=" + contextId, 0 /* DEBUG */);
|
|
2651
|
+
const socketPath = getIpcPath(contextId);
|
|
2652
|
+
let daemon = discoverDaemon(contextId);
|
|
2653
|
+
if (daemon) {
|
|
2654
|
+
log("daemon found: pid=" + daemon.pid.toString(), 0 /* DEBUG */);
|
|
2655
|
+
} else {
|
|
2656
|
+
log("no daemon found", 0 /* DEBUG */);
|
|
2657
|
+
}
|
|
2658
|
+
if (!daemon && options?.autoSpawn !== false) {
|
|
2659
|
+
const runtime2 = detectRuntime();
|
|
2660
|
+
log("auto-spawning daemon", 0 /* DEBUG */);
|
|
2661
|
+
spawnDaemon(dbPath, runtime2, options?.workerScript);
|
|
2662
|
+
log("waiting for daemon after spawn", 0 /* DEBUG */);
|
|
2663
|
+
await waitForDaemon(contextId, options?.connectTimeoutMs);
|
|
2664
|
+
daemon = discoverDaemon(contextId);
|
|
2665
|
+
}
|
|
2666
|
+
if (!daemon) {
|
|
2667
|
+
const msg = `kbdb worker daemon did not start: ${readCrashReason(contextId)}`;
|
|
2668
|
+
log(msg, 3 /* ERROR */);
|
|
2669
|
+
throw new Error(msg);
|
|
2670
|
+
}
|
|
2671
|
+
log("connecting to daemon", 0 /* DEBUG */);
|
|
2672
|
+
const client = new WorkerClient(
|
|
2673
|
+
socketPath,
|
|
2674
|
+
contextId,
|
|
2675
|
+
options?.requestTimeoutMs
|
|
2676
|
+
);
|
|
2677
|
+
await client.connect();
|
|
2678
|
+
return client;
|
|
2679
|
+
}
|
|
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
|
+
|
|
2695
|
+
// src/shared/cli/functions/run-worker-stop.function.ts
|
|
2696
|
+
async function runWorkerStop(dbDir) {
|
|
2697
|
+
log("running worker-stop", 0 /* DEBUG */);
|
|
2698
|
+
const contextId = await computeContextId(dbDir);
|
|
2699
|
+
const info = discoverDaemon(contextId);
|
|
2700
|
+
if (!info) {
|
|
2701
|
+
return { output: "no daemon running", exitCode: 0 };
|
|
2702
|
+
}
|
|
2703
|
+
log("pid found: " + info.pid.toString(), 0 /* DEBUG */);
|
|
2704
|
+
try {
|
|
2705
|
+
process.kill(info.pid, "SIGTERM");
|
|
2706
|
+
log("sigterm sent to pid=" + info.pid.toString(), 0 /* DEBUG */);
|
|
2707
|
+
} catch {
|
|
2708
|
+
return {
|
|
2709
|
+
error: "error: failed to stop daemon",
|
|
2710
|
+
exitCode: 1
|
|
2711
|
+
};
|
|
2712
|
+
}
|
|
2713
|
+
const deadline = Date.now() + 5e3;
|
|
2714
|
+
let pollIteration = 0;
|
|
2715
|
+
while (Date.now() < deadline) {
|
|
2716
|
+
try {
|
|
2717
|
+
process.kill(info.pid, 0);
|
|
2718
|
+
} catch {
|
|
2719
|
+
log(
|
|
2720
|
+
"process exited: pid=" + info.pid.toString(),
|
|
2721
|
+
0 /* DEBUG */
|
|
2722
|
+
);
|
|
2723
|
+
break;
|
|
2724
|
+
}
|
|
2725
|
+
pollIteration++;
|
|
2726
|
+
if (pollIteration % 5 === 0) {
|
|
2727
|
+
log(
|
|
2728
|
+
"waiting for exit: pid=" + info.pid.toString() + " poll=" + pollIteration.toString(),
|
|
2729
|
+
0 /* DEBUG */
|
|
2730
|
+
);
|
|
2731
|
+
}
|
|
2732
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
2733
|
+
}
|
|
2734
|
+
if (Date.now() >= deadline) {
|
|
2735
|
+
log(
|
|
2736
|
+
"timed out waiting for exit: pid=" + info.pid.toString(),
|
|
2737
|
+
0 /* DEBUG */
|
|
2738
|
+
);
|
|
2739
|
+
}
|
|
2740
|
+
return {
|
|
2741
|
+
output: `stopped daemon (pid ${info.pid.toString()})`,
|
|
2742
|
+
exitCode: 0
|
|
2743
|
+
};
|
|
2744
|
+
}
|
|
2745
|
+
|
|
2746
|
+
// src/shared/cli/functions/run-worker-restart.function.ts
|
|
2747
|
+
async function runWorkerRestart(dbDir) {
|
|
2748
|
+
log("running worker-restart", 0 /* DEBUG */);
|
|
2749
|
+
const stopResult = await runWorkerStop(dbDir);
|
|
2750
|
+
if (stopResult.exitCode !== 0) return stopResult;
|
|
2751
|
+
return {
|
|
2752
|
+
output: "daemon will restart on next command",
|
|
2753
|
+
exitCode: 0
|
|
2754
|
+
};
|
|
2755
|
+
}
|
|
2756
|
+
|
|
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
|
+
// src/shared/worker-client/functions/retry-on-timeout.function.ts
|
|
2763
|
+
async function retryOnTimeout(createClient, operation, maxRetries) {
|
|
2764
|
+
let lastError = new Error("retryOnTimeout exhausted");
|
|
2765
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
2766
|
+
log(
|
|
2767
|
+
"retry-on-timeout: attempt=" + attempt.toString() + " max=" + maxRetries.toString(),
|
|
2768
|
+
0 /* DEBUG */
|
|
2769
|
+
);
|
|
2770
|
+
const client = await createClient();
|
|
2771
|
+
try {
|
|
2772
|
+
const result = await operation(client);
|
|
2773
|
+
log(
|
|
2774
|
+
"retry-on-timeout: success on attempt=" + attempt.toString(),
|
|
2775
|
+
0 /* DEBUG */
|
|
2776
|
+
);
|
|
2777
|
+
return { client, result };
|
|
2778
|
+
} catch (err) {
|
|
2779
|
+
const code = err.code;
|
|
2780
|
+
if (code !== "REQUEST_TIMEOUT" || attempt >= maxRetries) {
|
|
2781
|
+
log(
|
|
2782
|
+
"retry-on-timeout: non-retriable error code=" + String(code),
|
|
2783
|
+
0 /* DEBUG */
|
|
2784
|
+
);
|
|
2785
|
+
client.disconnect();
|
|
2786
|
+
throw err;
|
|
2787
|
+
}
|
|
2788
|
+
lastError = err;
|
|
2789
|
+
if (client.killDaemon) {
|
|
2790
|
+
log(
|
|
2791
|
+
"retry " + String(attempt + 1) + "/" + String(maxRetries) + ": killing daemon",
|
|
2792
|
+
2 /* WARNING */
|
|
2793
|
+
);
|
|
2794
|
+
client.killDaemon();
|
|
2795
|
+
} else {
|
|
2796
|
+
client.disconnect();
|
|
2797
|
+
}
|
|
2798
|
+
}
|
|
2799
|
+
}
|
|
2800
|
+
log(
|
|
2801
|
+
"retry-on-timeout: all retries exhausted max=" + maxRetries.toString(),
|
|
2802
|
+
0 /* DEBUG */
|
|
2803
|
+
);
|
|
2804
|
+
throw lastError;
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2807
|
+
// src/shared/worker-client/constants/request-timeout.constant.ts
|
|
2808
|
+
var DEFAULT_REQUEST_TIMEOUT_MS = 3e4;
|
|
2809
|
+
|
|
2810
|
+
// src/shared/worker-client/constants/retry-defaults.constant.ts
|
|
2811
|
+
var DEFAULT_RETRY_COUNT = 5;
|
|
2812
|
+
|
|
2813
|
+
// src/shared/log/functions/resolve-log-level.function.ts
|
|
2814
|
+
function resolveLogLevel(cliLevel) {
|
|
2815
|
+
if (cliLevel !== void 0) {
|
|
2816
|
+
return cliLevel;
|
|
2817
|
+
}
|
|
2818
|
+
const envValue = process.env["KBDB_LOG_LEVEL"];
|
|
2819
|
+
if (envValue !== void 0) {
|
|
2820
|
+
return parseLogLevel(envValue);
|
|
2821
|
+
}
|
|
2822
|
+
return DEFAULT_LOG_LEVEL;
|
|
2823
|
+
}
|
|
2824
|
+
|
|
2825
|
+
// src/shared/log/functions/configure-log.function.ts
|
|
2826
|
+
function configureLog(config) {
|
|
2827
|
+
setLogLevel(config.level);
|
|
2828
|
+
if (config.outputs === void 0) {
|
|
2829
|
+
return;
|
|
2830
|
+
}
|
|
2831
|
+
const levels = [
|
|
2832
|
+
0 /* DEBUG */,
|
|
2833
|
+
1 /* INFO */,
|
|
2834
|
+
2 /* WARNING */,
|
|
2835
|
+
3 /* ERROR */
|
|
2836
|
+
];
|
|
2837
|
+
for (const level of levels) {
|
|
2838
|
+
const output = config.outputs[level];
|
|
2839
|
+
if (output !== void 0) {
|
|
2840
|
+
setLogOutput(level, output.write);
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
|
|
2845
|
+
// src/shared/cli/functions/run-cli.function.ts
|
|
2846
|
+
async function runCli(argv, deps2) {
|
|
2847
|
+
const options = parseArgs(argv);
|
|
2848
|
+
const logLevel = resolveLogLevel(options.logLevel);
|
|
2849
|
+
configureLog({ level: logLevel });
|
|
2850
|
+
log("command: " + options.command, 0 /* DEBUG */);
|
|
2851
|
+
if (options.command === "init") {
|
|
2852
|
+
log('--init is deprecated, use "kbdb db init"', 2 /* WARNING */);
|
|
2853
|
+
}
|
|
2854
|
+
if (options.command === "migrate") {
|
|
2855
|
+
log(
|
|
2856
|
+
'--migrate is deprecated, use "kbdb db migrate"',
|
|
2857
|
+
2 /* WARNING */
|
|
2858
|
+
);
|
|
2859
|
+
}
|
|
2860
|
+
const nonInteractive = options.nonInteractive || process.env["KBDB_NON_INTERACTIVE"] === "1" || process.env["KBDB_NON_INTERACTIVE"] === "true";
|
|
2861
|
+
const effectiveDeps = nonInteractive ? { ...deps2, isStdinTty: () => false } : deps2;
|
|
2862
|
+
if (!options.formatExplicit) {
|
|
2863
|
+
options.format = effectiveDeps.isStdoutTty() ? "text" : "json";
|
|
2864
|
+
}
|
|
2865
|
+
if (options.command === "help" || !options.command) {
|
|
2866
|
+
const helpCommand = options.args[0];
|
|
2867
|
+
const helpSubcommand = options.args[1];
|
|
2868
|
+
const helpText = generateHelp(helpCommand, helpSubcommand);
|
|
2869
|
+
if (helpCommand && !isKnownCommand(helpCommand)) {
|
|
2870
|
+
return { output: helpText, exitCode: 1 };
|
|
2871
|
+
}
|
|
2872
|
+
return { output: helpText, exitCode: 0 };
|
|
2873
|
+
}
|
|
2874
|
+
if (options.command === "version") {
|
|
2875
|
+
return { output: VERSION, exitCode: 0 };
|
|
2876
|
+
}
|
|
2877
|
+
if (options.command === "init" || options.command === "db-init") {
|
|
2878
|
+
return handleInit(options, effectiveDeps);
|
|
2879
|
+
}
|
|
2880
|
+
if (options.command === "mcp") {
|
|
2881
|
+
return handleMcp(options, effectiveDeps);
|
|
2882
|
+
}
|
|
2883
|
+
if (options.command === "migrate" || options.command === "db-migrate") {
|
|
2884
|
+
return handleMigrate(options, effectiveDeps);
|
|
2885
|
+
}
|
|
2886
|
+
if (options.command === "worker-stop") {
|
|
2887
|
+
return handleWorkerLifecycle(
|
|
2888
|
+
options,
|
|
2889
|
+
effectiveDeps,
|
|
2890
|
+
runWorkerStop
|
|
2891
|
+
);
|
|
2892
|
+
}
|
|
2893
|
+
if (options.command === "worker-restart") {
|
|
2894
|
+
return handleWorkerLifecycle(
|
|
2895
|
+
options,
|
|
2896
|
+
effectiveDeps,
|
|
2897
|
+
runWorkerRestart
|
|
2898
|
+
);
|
|
2899
|
+
}
|
|
2900
|
+
return handleDataCommand(options, effectiveDeps);
|
|
2901
|
+
}
|
|
2902
|
+
function handleInit(options, deps2) {
|
|
2903
|
+
const result = deps2.runInit(options);
|
|
2904
|
+
if (result.ok) {
|
|
2905
|
+
return {
|
|
2906
|
+
output: result.targetPath,
|
|
2907
|
+
exitCode: 0
|
|
2908
|
+
};
|
|
2909
|
+
}
|
|
2910
|
+
return {
|
|
2911
|
+
error: `error: ${result.errorMessage ?? "init failed"}`,
|
|
2912
|
+
exitCode: 1
|
|
2913
|
+
};
|
|
2914
|
+
}
|
|
2915
|
+
function resolveTimeoutMs(options) {
|
|
2916
|
+
return options.timeoutMs ?? (parseInt(process.env["KBDB_DAEMON_TIMEOUT"] ?? "", 10) || DEFAULT_REQUEST_TIMEOUT_MS);
|
|
2917
|
+
}
|
|
2918
|
+
function resolveRetryCount(options) {
|
|
2919
|
+
return options.retry ?? (parseInt(process.env["KBDB_RETRY"] ?? "", 10) || DEFAULT_RETRY_COUNT);
|
|
2920
|
+
}
|
|
2921
|
+
async function handleMcp(options, deps2) {
|
|
2922
|
+
const explicitPath = resolveRawDbPath(options);
|
|
2923
|
+
const dbDir = deps2.findDb(explicitPath);
|
|
2924
|
+
if (!dbDir) {
|
|
2925
|
+
return {
|
|
2926
|
+
error: "error: no .kbdb database found at " + (explicitPath ?? process.cwd()),
|
|
2927
|
+
exitCode: 1
|
|
2928
|
+
};
|
|
2929
|
+
}
|
|
2930
|
+
const timeoutMs = resolveTimeoutMs(options);
|
|
2931
|
+
const maxRetries = resolveRetryCount(options);
|
|
2932
|
+
let client;
|
|
2933
|
+
try {
|
|
2934
|
+
client = await deps2.createWorkerClient({
|
|
2935
|
+
contextPath: dbDir,
|
|
2936
|
+
requestTimeoutMs: timeoutMs
|
|
2937
|
+
});
|
|
2938
|
+
} catch (err) {
|
|
2939
|
+
return {
|
|
2940
|
+
error: `error: ${errorToMessage(err)}`,
|
|
2941
|
+
exitCode: 1
|
|
2942
|
+
};
|
|
2943
|
+
}
|
|
2944
|
+
try {
|
|
2945
|
+
const gateResult = await versionGate(client, dbDir);
|
|
2946
|
+
if (gateResult) return gateResult;
|
|
2947
|
+
if (deps2.startMcpServer) {
|
|
2948
|
+
await deps2.startMcpServer(
|
|
2949
|
+
dbDir,
|
|
2950
|
+
() => deps2.createWorkerClient({
|
|
2951
|
+
contextPath: dbDir,
|
|
2952
|
+
requestTimeoutMs: timeoutMs
|
|
2953
|
+
}),
|
|
2954
|
+
maxRetries
|
|
2955
|
+
);
|
|
2956
|
+
}
|
|
2957
|
+
return { exitCode: 0 };
|
|
2958
|
+
} catch (err) {
|
|
2959
|
+
return {
|
|
2960
|
+
error: `error: mcp failed: ${errorToMessage(err)}`,
|
|
2961
|
+
exitCode: 1
|
|
2962
|
+
};
|
|
2963
|
+
} finally {
|
|
2964
|
+
client.disconnect();
|
|
2965
|
+
}
|
|
2966
|
+
}
|
|
2967
|
+
async function handleMigrate(options, deps2) {
|
|
2968
|
+
const dbDir = deps2.findDb(options.dbPath);
|
|
2969
|
+
if (!dbDir) {
|
|
2970
|
+
const basePath = options.dbPath ?? process.cwd();
|
|
2971
|
+
return {
|
|
2972
|
+
error: `error: no .kbdb database found at ${basePath}`,
|
|
2973
|
+
exitCode: 1
|
|
2974
|
+
};
|
|
2975
|
+
}
|
|
2976
|
+
let client;
|
|
2977
|
+
try {
|
|
2978
|
+
client = await deps2.createWorkerClient({
|
|
2979
|
+
contextPath: dbDir
|
|
2980
|
+
});
|
|
2981
|
+
} catch (err) {
|
|
2982
|
+
return {
|
|
2983
|
+
error: `error: ${errorToMessage(err)}`,
|
|
2984
|
+
exitCode: 1
|
|
2985
|
+
};
|
|
2986
|
+
}
|
|
2310
2987
|
try {
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2988
|
+
const versionStatus = await client.checkVersion(dbDir);
|
|
2989
|
+
if (versionStatus.status === "too_new") {
|
|
2990
|
+
return {
|
|
2991
|
+
error: `error: database version ${versionStatus.currentVersion.toString()} is newer than kbdb version ${versionStatus.requiredVersion.toString()} -- upgrade kbdb`,
|
|
2992
|
+
exitCode: 1
|
|
2993
|
+
};
|
|
2994
|
+
}
|
|
2995
|
+
if (versionStatus.status === "needs_migration") {
|
|
2996
|
+
const migrateResult = await client.migrateDatabase(dbDir);
|
|
2997
|
+
return {
|
|
2998
|
+
output: JSON.stringify(migrateResult, null, 2),
|
|
2999
|
+
exitCode: 0
|
|
3000
|
+
};
|
|
3001
|
+
}
|
|
3002
|
+
return { output: "already up to date", exitCode: 0 };
|
|
3003
|
+
} catch (err) {
|
|
3004
|
+
return {
|
|
3005
|
+
error: `error: migrate failed: ${errorToMessage(err)}`,
|
|
3006
|
+
exitCode: 1
|
|
3007
|
+
};
|
|
3008
|
+
} finally {
|
|
3009
|
+
client.disconnect();
|
|
2315
3010
|
}
|
|
2316
3011
|
}
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
} catch {
|
|
3012
|
+
async function handleDataCommand(options, deps2) {
|
|
3013
|
+
const explicitPath = resolveRawDbPath(options);
|
|
3014
|
+
let dbDir = deps2.findDb(explicitPath);
|
|
3015
|
+
if (!dbDir) {
|
|
3016
|
+
const basePath = explicitPath ?? process.cwd();
|
|
3017
|
+
if (!deps2.isStdinTty()) {
|
|
3018
|
+
return {
|
|
3019
|
+
error: `error: no .kbdb database found at ${basePath} -- run \`kbdb --init\` to create one`,
|
|
3020
|
+
exitCode: 1
|
|
3021
|
+
};
|
|
2328
3022
|
}
|
|
2329
|
-
|
|
3023
|
+
const answer = await deps2.promptUser(
|
|
3024
|
+
`No .kbdb database found. Create one in ${basePath}? [y/N] `
|
|
3025
|
+
);
|
|
3026
|
+
if (answer.toLowerCase() !== "y") {
|
|
3027
|
+
return {
|
|
3028
|
+
error: "aborted: no database created",
|
|
3029
|
+
exitCode: 1
|
|
3030
|
+
};
|
|
3031
|
+
}
|
|
3032
|
+
const initResult = deps2.runInit(options);
|
|
3033
|
+
if (!initResult.ok) {
|
|
3034
|
+
return {
|
|
3035
|
+
error: `error: ${initResult.errorMessage ?? "init failed"}`,
|
|
3036
|
+
exitCode: 1
|
|
3037
|
+
};
|
|
3038
|
+
}
|
|
3039
|
+
dbDir = initResult.targetPath;
|
|
2330
3040
|
}
|
|
2331
|
-
|
|
2332
|
-
const
|
|
3041
|
+
log("db path: " + dbDir, 0 /* DEBUG */);
|
|
3042
|
+
const timeoutMs = resolveTimeoutMs(options);
|
|
3043
|
+
const maxRetries = resolveRetryCount(options);
|
|
2333
3044
|
try {
|
|
2334
|
-
|
|
2335
|
-
|
|
2336
|
-
|
|
2337
|
-
|
|
2338
|
-
}
|
|
2339
|
-
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
"workerScript must be provided (resolve at entry point)"
|
|
3045
|
+
const { client, result } = await retryOnTimeout(
|
|
3046
|
+
() => deps2.createWorkerClient({
|
|
3047
|
+
contextPath: dbDir,
|
|
3048
|
+
requestTimeoutMs: timeoutMs
|
|
3049
|
+
}),
|
|
3050
|
+
async (c) => {
|
|
3051
|
+
const gateResult = await versionGate(c, dbDir);
|
|
3052
|
+
if (gateResult) return gateResult;
|
|
3053
|
+
return dispatchCommand(c, options);
|
|
3054
|
+
},
|
|
3055
|
+
maxRetries
|
|
2346
3056
|
);
|
|
3057
|
+
client.disconnect();
|
|
3058
|
+
return result;
|
|
3059
|
+
} catch (err) {
|
|
3060
|
+
return {
|
|
3061
|
+
error: `error: ${errorToMessage(err)}`,
|
|
3062
|
+
exitCode: 1
|
|
3063
|
+
};
|
|
2347
3064
|
}
|
|
2348
|
-
const execPath = runtime2 === "deno" ? "deno" : process.execPath;
|
|
2349
|
-
const args = runtime2 === "deno" ? ["run", "--allow-all", workerScript2, contextPath] : [workerScript2, contextPath];
|
|
2350
|
-
const child = (0, import_node_child_process.spawn)(execPath, args, {
|
|
2351
|
-
detached: true,
|
|
2352
|
-
stdio: "ignore"
|
|
2353
|
-
});
|
|
2354
|
-
child.unref();
|
|
2355
|
-
}
|
|
2356
|
-
|
|
2357
|
-
// src/shared/worker-client/functions/wait-for-daemon.function.ts
|
|
2358
|
-
var import_node_fs7 = require("node:fs");
|
|
2359
|
-
var import_node_path9 = require("node:path");
|
|
2360
|
-
var import_node_os2 = require("node:os");
|
|
2361
|
-
var DEFAULT_TIMEOUT_MS = 1e4;
|
|
2362
|
-
var POLL_INTERVAL_MS = 100;
|
|
2363
|
-
async function waitForDaemon(contextId, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
2364
|
-
const pidPath = (0, import_node_path9.join)((0, import_node_os2.tmpdir)(), `kbdb-${contextId}.pid`);
|
|
2365
|
-
const start = Date.now();
|
|
2366
|
-
while (Date.now() - start < timeoutMs) {
|
|
2367
|
-
if ((0, import_node_fs7.existsSync)(pidPath)) return true;
|
|
2368
|
-
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
2369
|
-
}
|
|
2370
|
-
return false;
|
|
2371
|
-
}
|
|
2372
|
-
|
|
2373
|
-
// src/shared/platform/functions/get-ipc-path.function.ts
|
|
2374
|
-
var import_node_path10 = require("node:path");
|
|
2375
|
-
|
|
2376
|
-
// src/shared/platform/functions/get-tmpdir.function.ts
|
|
2377
|
-
var import_node_os3 = require("node:os");
|
|
2378
|
-
function getTmpdir() {
|
|
2379
|
-
return (0, import_node_os3.tmpdir)();
|
|
2380
|
-
}
|
|
2381
|
-
|
|
2382
|
-
// src/shared/platform/functions/get-ipc-path.function.ts
|
|
2383
|
-
function getIpcPath(ctx) {
|
|
2384
|
-
if (process.platform === "win32") {
|
|
2385
|
-
return `\\\\.\\pipe\\kbdb-${ctx}`;
|
|
2386
|
-
}
|
|
2387
|
-
return (0, import_node_path10.join)(getTmpdir(), `kbdb-${ctx}.sock`);
|
|
2388
3065
|
}
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
const runtime2 = detectRuntime();
|
|
2398
|
-
spawnDaemon(dbPath, runtime2, options?.workerScript);
|
|
2399
|
-
await waitForDaemon(contextId, options?.connectTimeoutMs);
|
|
2400
|
-
daemon = discoverDaemon(contextId);
|
|
2401
|
-
}
|
|
2402
|
-
if (!daemon) {
|
|
2403
|
-
throw new Error(
|
|
2404
|
-
`kbdb worker daemon did not start: ${readCrashReason(contextId)}`
|
|
2405
|
-
);
|
|
3066
|
+
async function handleWorkerLifecycle(options, deps2, action) {
|
|
3067
|
+
const explicitPath = resolveRawDbPath(options);
|
|
3068
|
+
const dbDir = deps2.findDb(explicitPath);
|
|
3069
|
+
if (!dbDir) {
|
|
3070
|
+
return {
|
|
3071
|
+
error: "error: no .kbdb database found at " + (explicitPath ?? process.cwd()),
|
|
3072
|
+
exitCode: 1
|
|
3073
|
+
};
|
|
2406
3074
|
}
|
|
2407
|
-
|
|
2408
|
-
await client.connect();
|
|
2409
|
-
return client;
|
|
3075
|
+
return action(dbDir);
|
|
2410
3076
|
}
|
|
2411
|
-
function
|
|
2412
|
-
const
|
|
2413
|
-
if (
|
|
2414
|
-
return
|
|
3077
|
+
async function versionGate(client, dbDir) {
|
|
3078
|
+
const versionStatus = await client.checkVersion(dbDir);
|
|
3079
|
+
if (versionStatus.status === "needs_migration") {
|
|
3080
|
+
return {
|
|
3081
|
+
error: "error: database needs migration -- run `kbdb --migrate`",
|
|
3082
|
+
exitCode: 1
|
|
3083
|
+
};
|
|
2415
3084
|
}
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
} catch {
|
|
2422
|
-
return "daemon failed to start (crash log unreadable)";
|
|
3085
|
+
if (versionStatus.status === "too_new") {
|
|
3086
|
+
return {
|
|
3087
|
+
error: `error: database version ${versionStatus.currentVersion.toString()} is newer than kbdb version ${versionStatus.requiredVersion.toString()} -- upgrade kbdb`,
|
|
3088
|
+
exitCode: 1
|
|
3089
|
+
};
|
|
2423
3090
|
}
|
|
3091
|
+
return null;
|
|
2424
3092
|
}
|
|
2425
3093
|
|
|
3094
|
+
// src/shared/cli/constants/help-text.constant.ts
|
|
3095
|
+
var HELP_TEXT = generateHelp();
|
|
3096
|
+
|
|
2426
3097
|
// src/shared/mcp/classes/mcp-server.class.ts
|
|
2427
3098
|
var import_node_readline2 = require("node:readline");
|
|
2428
3099
|
|
|
@@ -2456,6 +3127,10 @@ function createToolDefinitions() {
|
|
|
2456
3127
|
type: "string",
|
|
2457
3128
|
enum: ["lexical", "vector", "hybrid"],
|
|
2458
3129
|
description: "Search algorithm (default: lexical)"
|
|
3130
|
+
},
|
|
3131
|
+
relaxed: {
|
|
3132
|
+
type: "boolean",
|
|
3133
|
+
description: "Use relaxed (OR) matching when the strict query returns no results"
|
|
2459
3134
|
}
|
|
2460
3135
|
},
|
|
2461
3136
|
required: ["query"]
|
|
@@ -3136,6 +3811,7 @@ function asStringArray2(value) {
|
|
|
3136
3811
|
return [];
|
|
3137
3812
|
}
|
|
3138
3813
|
async function handleToolCall(client, name, args) {
|
|
3814
|
+
log("tool call: " + name, 0 /* DEBUG */);
|
|
3139
3815
|
try {
|
|
3140
3816
|
switch (name) {
|
|
3141
3817
|
case "search":
|
|
@@ -3179,6 +3855,7 @@ async function handleToolCall(client, name, args) {
|
|
|
3179
3855
|
case "auto-capture-review":
|
|
3180
3856
|
return handleAutoCaptureReview();
|
|
3181
3857
|
default:
|
|
3858
|
+
log("unknown tool: " + name, 2 /* WARNING */);
|
|
3182
3859
|
return {
|
|
3183
3860
|
content: [
|
|
3184
3861
|
{
|
|
@@ -3190,6 +3867,10 @@ async function handleToolCall(client, name, args) {
|
|
|
3190
3867
|
};
|
|
3191
3868
|
}
|
|
3192
3869
|
} catch (err) {
|
|
3870
|
+
log(
|
|
3871
|
+
"tool call failed: " + name + ": " + (err instanceof Error ? err.message : String(err)),
|
|
3872
|
+
3 /* ERROR */
|
|
3873
|
+
);
|
|
3193
3874
|
return {
|
|
3194
3875
|
content: [
|
|
3195
3876
|
{
|
|
@@ -3207,7 +3888,8 @@ async function handleSearch2(client, args) {
|
|
|
3207
3888
|
mode: args["mode"],
|
|
3208
3889
|
limit: args["limit"],
|
|
3209
3890
|
offset: args["offset"],
|
|
3210
|
-
algo: args["algo"]
|
|
3891
|
+
algo: args["algo"],
|
|
3892
|
+
relaxed: args["relaxed"]
|
|
3211
3893
|
});
|
|
3212
3894
|
const stripped = {
|
|
3213
3895
|
...results,
|
|
@@ -3563,6 +4245,7 @@ async function handleResourceRead(client, uri) {
|
|
|
3563
4245
|
]
|
|
3564
4246
|
};
|
|
3565
4247
|
}
|
|
4248
|
+
log(`Unknown resource URI: ${uri}`, 3 /* ERROR */);
|
|
3566
4249
|
throw new Error(`Unknown resource URI: ${uri}`);
|
|
3567
4250
|
}
|
|
3568
4251
|
|
|
@@ -3639,6 +4322,7 @@ async function handleAgentPrompt(name, client) {
|
|
|
3639
4322
|
const agents = await client.listDocumentsByType("agent");
|
|
3640
4323
|
const doc = agents.find((a) => a.title === agentName);
|
|
3641
4324
|
if (!doc) {
|
|
4325
|
+
log("agent not found: " + agentName, 3 /* ERROR */);
|
|
3642
4326
|
throw new Error("agent not found: " + agentName);
|
|
3643
4327
|
}
|
|
3644
4328
|
const sections = doc.sections;
|
|
@@ -3683,6 +4367,7 @@ async function handleSkillPrompt(name, promptArgs, client) {
|
|
|
3683
4367
|
}
|
|
3684
4368
|
}
|
|
3685
4369
|
if (matchContent === void 0) {
|
|
4370
|
+
log(`Prompt not found: ${name}`, 3 /* ERROR */);
|
|
3686
4371
|
throw new Error(`Prompt not found: ${name}`);
|
|
3687
4372
|
}
|
|
3688
4373
|
const parsed = JSON.parse(matchContent);
|
|
@@ -3774,6 +4459,131 @@ function shouldEmitLog(messageLevel, threshold) {
|
|
|
3774
4459
|
return messageIndex >= thresholdIndex;
|
|
3775
4460
|
}
|
|
3776
4461
|
|
|
4462
|
+
// src/shared/auto-capture/functions/build-capture-prompt.function.ts
|
|
4463
|
+
function buildCapturePrompt(recentContext) {
|
|
4464
|
+
return "Review the following conversation context and identify factual knowledge worth storing in the knowledge base.\n\nRules:\n- Include durable facts, decisions, preferences, and corrections that would be useful in future sessions.\n- Exclude ephemeral, task-specific, or temporary information that has no lasting value.\n- Format each piece of extracted knowledge as a concise statement suitable for direct storage.\n- If no durable knowledge is found, respond with an empty list.\n\nConversation context:\n" + recentContext;
|
|
4465
|
+
}
|
|
4466
|
+
|
|
4467
|
+
// src/shared/mcp/functions/has-sampling-capability.function.ts
|
|
4468
|
+
function hasSamplingCapability(hostCapabilities) {
|
|
4469
|
+
if (hostCapabilities === null) return false;
|
|
4470
|
+
return Boolean(hostCapabilities["sampling"]);
|
|
4471
|
+
}
|
|
4472
|
+
|
|
4473
|
+
// src/shared/mcp/functions/run-auto-capture.function.ts
|
|
4474
|
+
function isSamplingResponse(v) {
|
|
4475
|
+
if (typeof v !== "object" || v === null) return false;
|
|
4476
|
+
const obj = v;
|
|
4477
|
+
const content = obj["content"];
|
|
4478
|
+
if (typeof content !== "object" || content === null) return false;
|
|
4479
|
+
return typeof content["text"] === "string";
|
|
4480
|
+
}
|
|
4481
|
+
async function runAutoCapture(controller, config, client, hostCapabilities, requestSampling) {
|
|
4482
|
+
try {
|
|
4483
|
+
const trigger = controller.evaluate();
|
|
4484
|
+
log("auto-capture trigger evaluated", 0 /* DEBUG */);
|
|
4485
|
+
if (!trigger.shouldCapture) return;
|
|
4486
|
+
if (!hasSamplingCapability(hostCapabilities)) return;
|
|
4487
|
+
const prompt = buildCapturePrompt("recent conversation context");
|
|
4488
|
+
const messages = [
|
|
4489
|
+
{ role: "user", content: { type: "text", text: prompt } }
|
|
4490
|
+
];
|
|
4491
|
+
const raw = await requestSampling(messages, 1024);
|
|
4492
|
+
if (!isSamplingResponse(raw)) return;
|
|
4493
|
+
const text = raw.content.text.trim();
|
|
4494
|
+
if (!text) return;
|
|
4495
|
+
if (config.dryRun) return;
|
|
4496
|
+
log("auto-capture storing knowledge", 0 /* DEBUG */);
|
|
4497
|
+
await client.addSection({
|
|
4498
|
+
sectionType: "text/markdown",
|
|
4499
|
+
content: text,
|
|
4500
|
+
title: "Auto-captured knowledge"
|
|
4501
|
+
});
|
|
4502
|
+
} catch {
|
|
4503
|
+
log("auto-capture error (non-fatal)", 0 /* DEBUG */);
|
|
4504
|
+
}
|
|
4505
|
+
}
|
|
4506
|
+
|
|
4507
|
+
// src/shared/auto-capture/functions/evaluate-trigger.function.ts
|
|
4508
|
+
function evaluateTrigger(config, state) {
|
|
4509
|
+
log("evaluating auto-capture trigger conditions", 0 /* DEBUG */);
|
|
4510
|
+
if (!config.enabled) {
|
|
4511
|
+
return {
|
|
4512
|
+
shouldCapture: false,
|
|
4513
|
+
reason: "auto-capture is disabled"
|
|
4514
|
+
};
|
|
4515
|
+
}
|
|
4516
|
+
if (state.totalCapturesThisSession >= config.maxCapturesPerSession) {
|
|
4517
|
+
return {
|
|
4518
|
+
shouldCapture: false,
|
|
4519
|
+
reason: "session capture limit reached"
|
|
4520
|
+
};
|
|
4521
|
+
}
|
|
4522
|
+
const elapsed = state.lastCaptureTimestamp ? Date.now() - state.lastCaptureTimestamp : Infinity;
|
|
4523
|
+
if (elapsed < config.minIntervalMs) {
|
|
4524
|
+
return {
|
|
4525
|
+
shouldCapture: false,
|
|
4526
|
+
reason: "within minimum interval"
|
|
4527
|
+
};
|
|
4528
|
+
}
|
|
4529
|
+
if (state.toolCallsSinceLastCapture < config.triggerAfterToolCalls) {
|
|
4530
|
+
return {
|
|
4531
|
+
shouldCapture: false,
|
|
4532
|
+
reason: "tool call threshold not yet reached"
|
|
4533
|
+
};
|
|
4534
|
+
}
|
|
4535
|
+
return { shouldCapture: true, reason: "trigger threshold met" };
|
|
4536
|
+
}
|
|
4537
|
+
|
|
4538
|
+
// src/shared/auto-capture/classes/auto-capture-controller.class.ts
|
|
4539
|
+
var AutoCaptureController = class {
|
|
4540
|
+
toolCallsSinceLastCapture = 0;
|
|
4541
|
+
lastCaptureTimestamp = 0;
|
|
4542
|
+
totalCapturesThisSession = 0;
|
|
4543
|
+
config;
|
|
4544
|
+
/** @param config - the auto-capture configuration to use */
|
|
4545
|
+
constructor(config) {
|
|
4546
|
+
this.config = config;
|
|
4547
|
+
}
|
|
4548
|
+
/** Record one tool call for trigger counting. */
|
|
4549
|
+
recordToolCall() {
|
|
4550
|
+
this.toolCallsSinceLastCapture += 1;
|
|
4551
|
+
}
|
|
4552
|
+
/**
|
|
4553
|
+
* Evaluates the current state against the trigger criteria.
|
|
4554
|
+
*
|
|
4555
|
+
* When the trigger fires, advances the session counters so the
|
|
4556
|
+
* next evaluation respects rate limiting and the session cap.
|
|
4557
|
+
*
|
|
4558
|
+
* @returns the trigger decision with a human-readable reason
|
|
4559
|
+
*/
|
|
4560
|
+
evaluate() {
|
|
4561
|
+
log("evaluating auto-capture trigger", 0 /* DEBUG */);
|
|
4562
|
+
const trigger = evaluateTrigger(this.config, this.state());
|
|
4563
|
+
if (trigger.shouldCapture) {
|
|
4564
|
+
this.totalCapturesThisSession += 1;
|
|
4565
|
+
this.lastCaptureTimestamp = Date.now();
|
|
4566
|
+
this.toolCallsSinceLastCapture = 0;
|
|
4567
|
+
}
|
|
4568
|
+
return trigger;
|
|
4569
|
+
}
|
|
4570
|
+
/** Reset all counters, e.g. on client disconnect. */
|
|
4571
|
+
reset() {
|
|
4572
|
+
log("resetting auto-capture controller", 0 /* DEBUG */);
|
|
4573
|
+
this.toolCallsSinceLastCapture = 0;
|
|
4574
|
+
this.lastCaptureTimestamp = 0;
|
|
4575
|
+
this.totalCapturesThisSession = 0;
|
|
4576
|
+
}
|
|
4577
|
+
/** Returns a snapshot of the current controller state. */
|
|
4578
|
+
state() {
|
|
4579
|
+
return {
|
|
4580
|
+
toolCallsSinceLastCapture: this.toolCallsSinceLastCapture,
|
|
4581
|
+
lastCaptureTimestamp: this.lastCaptureTimestamp,
|
|
4582
|
+
totalCapturesThisSession: this.totalCapturesThisSession
|
|
4583
|
+
};
|
|
4584
|
+
}
|
|
4585
|
+
};
|
|
4586
|
+
|
|
3777
4587
|
// src/shared/mcp/constants/mcp-error-codes.constant.ts
|
|
3778
4588
|
var PARSE_ERROR = -32700;
|
|
3779
4589
|
var METHOD_NOT_FOUND = -32601;
|
|
@@ -3783,21 +4593,63 @@ var RESOURCE_NOT_FOUND = -32002;
|
|
|
3783
4593
|
var McpServer = class {
|
|
3784
4594
|
client;
|
|
3785
4595
|
contextPath;
|
|
4596
|
+
autoCaptureConfig;
|
|
4597
|
+
clientFactory;
|
|
4598
|
+
maxRetries;
|
|
4599
|
+
autoCaptureController = null;
|
|
3786
4600
|
initialized = false;
|
|
3787
4601
|
hostCapabilities = null;
|
|
3788
4602
|
logLevel = null;
|
|
3789
4603
|
subscriptions = /* @__PURE__ */ new Set();
|
|
3790
4604
|
nextRequestId = 1;
|
|
3791
4605
|
pendingRequests = /* @__PURE__ */ new Map();
|
|
3792
|
-
|
|
4606
|
+
/**
|
|
4607
|
+
* @param client - worker client providing knowledge-base operations
|
|
4608
|
+
* @param contextPath - absolute path to the `.kbdb` directory
|
|
4609
|
+
* @param autoCaptureConfig - optional auto-capture configuration;
|
|
4610
|
+
* when provided the server activates auto-capture on connection
|
|
4611
|
+
* @param clientFactory - creates a fresh worker client (for retry)
|
|
4612
|
+
* @param maxRetries - max retries on REQUEST_TIMEOUT
|
|
4613
|
+
*/
|
|
4614
|
+
constructor(client, contextPath, autoCaptureConfig, clientFactory, maxRetries) {
|
|
3793
4615
|
this.client = client;
|
|
3794
4616
|
this.contextPath = contextPath ?? "";
|
|
4617
|
+
this.autoCaptureConfig = autoCaptureConfig ?? null;
|
|
4618
|
+
this.clientFactory = clientFactory ?? null;
|
|
4619
|
+
this.maxRetries = maxRetries ?? DEFAULT_RETRY_COUNT;
|
|
4620
|
+
}
|
|
4621
|
+
async reconnectClient() {
|
|
4622
|
+
if (!this.clientFactory) {
|
|
4623
|
+
log("no client factory for reconnect", 3 /* ERROR */);
|
|
4624
|
+
throw new Error("no client factory for reconnect");
|
|
4625
|
+
}
|
|
4626
|
+
this.client.disconnect();
|
|
4627
|
+
this.client = await this.clientFactory();
|
|
4628
|
+
log("MCP client reconnected", 0 /* DEBUG */);
|
|
4629
|
+
}
|
|
4630
|
+
async withRetry(fn) {
|
|
4631
|
+
for (let attempt = 0; ; attempt++) {
|
|
4632
|
+
try {
|
|
4633
|
+
return await fn();
|
|
4634
|
+
} catch (err) {
|
|
4635
|
+
const code = err.code;
|
|
4636
|
+
if (code !== "REQUEST_TIMEOUT" || attempt >= this.maxRetries || !this.clientFactory) {
|
|
4637
|
+
throw err;
|
|
4638
|
+
}
|
|
4639
|
+
log(
|
|
4640
|
+
"request timeout, reconnecting (attempt " + (attempt + 1).toString() + "/" + this.maxRetries.toString() + ")",
|
|
4641
|
+
2 /* WARNING */
|
|
4642
|
+
);
|
|
4643
|
+
await this.reconnectClient();
|
|
4644
|
+
}
|
|
4645
|
+
}
|
|
3795
4646
|
}
|
|
3796
4647
|
async listen() {
|
|
3797
4648
|
const rl = (0, import_node_readline2.createInterface)({
|
|
3798
4649
|
input: process.stdin,
|
|
3799
4650
|
terminal: false
|
|
3800
4651
|
});
|
|
4652
|
+
log("MCP server listening on stdin", 0 /* DEBUG */);
|
|
3801
4653
|
let pending = Promise.resolve();
|
|
3802
4654
|
await new Promise((resolve4) => {
|
|
3803
4655
|
rl.on("line", (line) => {
|
|
@@ -3805,7 +4657,10 @@ var McpServer = class {
|
|
|
3805
4657
|
});
|
|
3806
4658
|
rl.on("close", () => {
|
|
3807
4659
|
void pending.then(() => {
|
|
4660
|
+
this.autoCaptureController?.reset();
|
|
4661
|
+
this.autoCaptureController = null;
|
|
3808
4662
|
this.client.disconnect();
|
|
4663
|
+
log("MCP stdin closed", 0 /* DEBUG */);
|
|
3809
4664
|
resolve4();
|
|
3810
4665
|
});
|
|
3811
4666
|
});
|
|
@@ -3869,6 +4724,7 @@ var McpServer = class {
|
|
|
3869
4724
|
*/
|
|
3870
4725
|
async requestSampling(messages, maxTokens) {
|
|
3871
4726
|
if (!this.hostCapabilities?.["sampling"]) {
|
|
4727
|
+
log("Host does not support sampling", 3 /* ERROR */);
|
|
3872
4728
|
throw new Error("Host does not support sampling");
|
|
3873
4729
|
}
|
|
3874
4730
|
return this.sendRequest("sampling/createMessage", {
|
|
@@ -3915,10 +4771,15 @@ var McpServer = class {
|
|
|
3915
4771
|
return null;
|
|
3916
4772
|
}
|
|
3917
4773
|
const request = parsed;
|
|
4774
|
+
log("MCP request: " + request.method, 0 /* DEBUG */);
|
|
3918
4775
|
if (request.id === void 0) {
|
|
3919
4776
|
if (request.method === "notifications/initialized" || request.method === "notifications/cancelled") {
|
|
3920
4777
|
if (request.method === "notifications/initialized" && !this.initialized) {
|
|
3921
4778
|
this.initialized = true;
|
|
4779
|
+
log("MCP initialized", 1 /* INFO */);
|
|
4780
|
+
if (this.autoCaptureConfig !== null) {
|
|
4781
|
+
this.autoCaptureController = new AutoCaptureController(this.autoCaptureConfig);
|
|
4782
|
+
}
|
|
3922
4783
|
void this.runStartupHealthCheck();
|
|
3923
4784
|
}
|
|
3924
4785
|
}
|
|
@@ -3952,7 +4813,7 @@ var McpServer = class {
|
|
|
3952
4813
|
protocolVersion: "2025-11-25",
|
|
3953
4814
|
serverInfo: {
|
|
3954
4815
|
name: "kbdb",
|
|
3955
|
-
version:
|
|
4816
|
+
version: VERSION
|
|
3956
4817
|
},
|
|
3957
4818
|
capabilities: {
|
|
3958
4819
|
tools: {},
|
|
@@ -3993,11 +4854,10 @@ var McpServer = class {
|
|
|
3993
4854
|
const rawName = params["name"];
|
|
3994
4855
|
const name = typeof rawName === "string" ? rawName : "";
|
|
3995
4856
|
const args = params["arguments"] ?? {};
|
|
3996
|
-
const result = await
|
|
3997
|
-
this.client,
|
|
3998
|
-
name,
|
|
3999
|
-
args
|
|
4857
|
+
const result = await this.withRetry(
|
|
4858
|
+
() => handleToolCall(this.client, name, args)
|
|
4000
4859
|
);
|
|
4860
|
+
this.afterToolCall();
|
|
4001
4861
|
return { jsonrpc: "2.0", id, result };
|
|
4002
4862
|
}
|
|
4003
4863
|
case "resources/read": {
|
|
@@ -4005,9 +4865,8 @@ var McpServer = class {
|
|
|
4005
4865
|
const rawUri = params["uri"];
|
|
4006
4866
|
const uri = typeof rawUri === "string" ? rawUri : "";
|
|
4007
4867
|
try {
|
|
4008
|
-
const result = await
|
|
4009
|
-
this.client,
|
|
4010
|
-
uri
|
|
4868
|
+
const result = await this.withRetry(
|
|
4869
|
+
() => handleResourceRead(this.client, uri)
|
|
4011
4870
|
);
|
|
4012
4871
|
return { jsonrpc: "2.0", id, result };
|
|
4013
4872
|
} catch (err) {
|
|
@@ -4112,6 +4971,23 @@ var McpServer = class {
|
|
|
4112
4971
|
const json = JSON.stringify(response);
|
|
4113
4972
|
process.stdout.write(json + "\n");
|
|
4114
4973
|
}
|
|
4974
|
+
/**
|
|
4975
|
+
* Records a tool call in the auto-capture controller and fires
|
|
4976
|
+
* a capture when the trigger condition is met.
|
|
4977
|
+
*/
|
|
4978
|
+
afterToolCall() {
|
|
4979
|
+
const ctrl = this.autoCaptureController;
|
|
4980
|
+
const cfg = this.autoCaptureConfig;
|
|
4981
|
+
if (ctrl === null || cfg === null) return;
|
|
4982
|
+
ctrl.recordToolCall();
|
|
4983
|
+
void runAutoCapture(
|
|
4984
|
+
ctrl,
|
|
4985
|
+
cfg,
|
|
4986
|
+
this.client,
|
|
4987
|
+
this.hostCapabilities,
|
|
4988
|
+
(messages, maxTokens) => this.requestSampling(messages, maxTokens)
|
|
4989
|
+
);
|
|
4990
|
+
}
|
|
4115
4991
|
/**
|
|
4116
4992
|
* Runs an integrity check immediately after the MCP handshake
|
|
4117
4993
|
* completes. Emits a `notifications/message` warning when the
|
|
@@ -4136,8 +5012,134 @@ var McpServer = class {
|
|
|
4136
5012
|
};
|
|
4137
5013
|
|
|
4138
5014
|
// src/shared/mcp/functions/create-mcp-server.function.ts
|
|
4139
|
-
function createMcpServer(client) {
|
|
4140
|
-
|
|
5015
|
+
function createMcpServer(client, contextPath, autoCaptureConfig, clientFactory, maxRetries) {
|
|
5016
|
+
log("creating MCP server", 0 /* DEBUG */);
|
|
5017
|
+
return new McpServer(
|
|
5018
|
+
client,
|
|
5019
|
+
contextPath,
|
|
5020
|
+
autoCaptureConfig,
|
|
5021
|
+
clientFactory,
|
|
5022
|
+
maxRetries
|
|
5023
|
+
);
|
|
5024
|
+
}
|
|
5025
|
+
|
|
5026
|
+
// src/shared/worker-daemon/constants/daemon-defaults.constant.ts
|
|
5027
|
+
var DEFAULT_ITEM_LIMIT = 1e3;
|
|
5028
|
+
var DEFAULT_INDEX_LIMIT = 100;
|
|
5029
|
+
var DEFAULT_TIMEOUT_MS2 = 3e5;
|
|
5030
|
+
var DEFAULT_ITEM_TTL_MS = 6e4;
|
|
5031
|
+
|
|
5032
|
+
// src/shared/worker-daemon/functions/parse-embedding-section.function.ts
|
|
5033
|
+
function parseEmbeddingSection(entries) {
|
|
5034
|
+
const provider = entries.get("provider");
|
|
5035
|
+
if (!provider) {
|
|
5036
|
+
return void 0;
|
|
5037
|
+
}
|
|
5038
|
+
const model = entries.get("model");
|
|
5039
|
+
const endpoint = entries.get("endpoint");
|
|
5040
|
+
const dimensionsRaw = entries.get("dimensions");
|
|
5041
|
+
const dimensions = dimensionsRaw ? parseInt(dimensionsRaw, 10) || void 0 : void 0;
|
|
5042
|
+
return {
|
|
5043
|
+
provider,
|
|
5044
|
+
...model !== void 0 ? { model } : {},
|
|
5045
|
+
...endpoint !== void 0 ? { endpoint } : {},
|
|
5046
|
+
...dimensions !== void 0 ? { dimensions } : {}
|
|
5047
|
+
};
|
|
5048
|
+
}
|
|
5049
|
+
|
|
5050
|
+
// src/shared/auto-capture/constants/auto-capture-defaults.constant.ts
|
|
5051
|
+
var AUTO_CAPTURE_DEFAULTS = {
|
|
5052
|
+
enabled: false,
|
|
5053
|
+
triggerAfterToolCalls: 5,
|
|
5054
|
+
minIntervalMs: 6e4,
|
|
5055
|
+
maxCapturesPerSession: 10,
|
|
5056
|
+
dryRun: false
|
|
5057
|
+
};
|
|
5058
|
+
|
|
5059
|
+
// src/shared/worker-daemon/functions/parse-auto-capture-section.function.ts
|
|
5060
|
+
function parseAutoCaptureSection(entries) {
|
|
5061
|
+
const enabled = entries.has("enabled") ? entries.get("enabled") === "true" : AUTO_CAPTURE_DEFAULTS.enabled;
|
|
5062
|
+
const dryRun = entries.has("dry_run") ? entries.get("dry_run") === "true" : AUTO_CAPTURE_DEFAULTS.dryRun;
|
|
5063
|
+
const triggerRaw = entries.get("trigger_after_tool_calls");
|
|
5064
|
+
const triggerAfterToolCalls = triggerRaw ? parseInt(triggerRaw, 10) || AUTO_CAPTURE_DEFAULTS.triggerAfterToolCalls : AUTO_CAPTURE_DEFAULTS.triggerAfterToolCalls;
|
|
5065
|
+
const intervalRaw = entries.get("min_interval_ms");
|
|
5066
|
+
const minIntervalMs = intervalRaw ? parseInt(intervalRaw, 10) || AUTO_CAPTURE_DEFAULTS.minIntervalMs : AUTO_CAPTURE_DEFAULTS.minIntervalMs;
|
|
5067
|
+
const capRaw = entries.get("max_captures_per_session");
|
|
5068
|
+
const maxCapturesPerSession = capRaw ? parseInt(capRaw, 10) || AUTO_CAPTURE_DEFAULTS.maxCapturesPerSession : AUTO_CAPTURE_DEFAULTS.maxCapturesPerSession;
|
|
5069
|
+
return {
|
|
5070
|
+
enabled,
|
|
5071
|
+
triggerAfterToolCalls,
|
|
5072
|
+
minIntervalMs,
|
|
5073
|
+
maxCapturesPerSession,
|
|
5074
|
+
dryRun
|
|
5075
|
+
};
|
|
5076
|
+
}
|
|
5077
|
+
|
|
5078
|
+
// src/shared/worker-daemon/functions/parse-worker-toml.function.ts
|
|
5079
|
+
function applyRootKey(acc, key, value) {
|
|
5080
|
+
switch (key) {
|
|
5081
|
+
case "item_limit":
|
|
5082
|
+
acc.itemLimit = parseInt(value, 10) || DEFAULT_ITEM_LIMIT;
|
|
5083
|
+
break;
|
|
5084
|
+
case "index_limit":
|
|
5085
|
+
acc.indexLimit = parseInt(value, 10) || DEFAULT_INDEX_LIMIT;
|
|
5086
|
+
break;
|
|
5087
|
+
case "timeout_ms":
|
|
5088
|
+
acc.timeoutMs = parseInt(value, 10) || DEFAULT_TIMEOUT_MS2;
|
|
5089
|
+
break;
|
|
5090
|
+
case "item_ttl_ms":
|
|
5091
|
+
acc.itemTtlMs = parseInt(value, 10) || DEFAULT_ITEM_TTL_MS;
|
|
5092
|
+
break;
|
|
5093
|
+
default:
|
|
5094
|
+
break;
|
|
5095
|
+
}
|
|
5096
|
+
}
|
|
5097
|
+
function parseWorkerToml(text, contextPath) {
|
|
5098
|
+
let section = "";
|
|
5099
|
+
const embeddingEntries = /* @__PURE__ */ new Map();
|
|
5100
|
+
const autoCaptureEntries = /* @__PURE__ */ new Map();
|
|
5101
|
+
const acc = {
|
|
5102
|
+
itemLimit: DEFAULT_ITEM_LIMIT,
|
|
5103
|
+
indexLimit: DEFAULT_INDEX_LIMIT,
|
|
5104
|
+
timeoutMs: DEFAULT_TIMEOUT_MS2,
|
|
5105
|
+
itemTtlMs: DEFAULT_ITEM_TTL_MS
|
|
5106
|
+
};
|
|
5107
|
+
for (const line of text.split("\n")) {
|
|
5108
|
+
const trimmed = line.trim();
|
|
5109
|
+
if (trimmed === "[embedding]") {
|
|
5110
|
+
section = "embedding";
|
|
5111
|
+
continue;
|
|
5112
|
+
}
|
|
5113
|
+
if (trimmed === "[auto_capture]") {
|
|
5114
|
+
section = "auto_capture";
|
|
5115
|
+
continue;
|
|
5116
|
+
}
|
|
5117
|
+
if (trimmed.startsWith("[")) {
|
|
5118
|
+
section = "";
|
|
5119
|
+
continue;
|
|
5120
|
+
}
|
|
5121
|
+
if (trimmed.startsWith("#") || !trimmed.includes("=")) continue;
|
|
5122
|
+
const eqIdx = trimmed.indexOf("=");
|
|
5123
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
5124
|
+
const value = trimmed.slice(eqIdx + 1).trim();
|
|
5125
|
+
if (section === "embedding") {
|
|
5126
|
+
embeddingEntries.set(key, value);
|
|
5127
|
+
continue;
|
|
5128
|
+
}
|
|
5129
|
+
if (section === "auto_capture") {
|
|
5130
|
+
autoCaptureEntries.set(key, value);
|
|
5131
|
+
continue;
|
|
5132
|
+
}
|
|
5133
|
+
applyRootKey(acc, key, value);
|
|
5134
|
+
}
|
|
5135
|
+
const embedding = parseEmbeddingSection(embeddingEntries);
|
|
5136
|
+
const autoCapture = autoCaptureEntries.size > 0 ? parseAutoCaptureSection(autoCaptureEntries) : void 0;
|
|
5137
|
+
return {
|
|
5138
|
+
contextPath,
|
|
5139
|
+
...acc,
|
|
5140
|
+
...embedding !== void 0 ? { embedding } : {},
|
|
5141
|
+
...autoCapture !== void 0 ? { autoCapture } : {}
|
|
5142
|
+
};
|
|
4141
5143
|
}
|
|
4142
5144
|
|
|
4143
5145
|
// src/cli.ts
|
|
@@ -4147,18 +5149,36 @@ var baseDir = resolveBaseDir(import_meta.url, import_meta.dirname);
|
|
|
4147
5149
|
var workerScript = resolveWorkerScript(baseDir.scriptDir, runtime);
|
|
4148
5150
|
var deps = {
|
|
4149
5151
|
isStdinTty,
|
|
5152
|
+
isStdoutTty: () => process.stdout.isTTY,
|
|
4150
5153
|
promptUser,
|
|
4151
5154
|
createWorkerClient: (opts) => createWorkerClient({ ...opts, workerScript }),
|
|
4152
5155
|
findDb,
|
|
4153
5156
|
runInit,
|
|
4154
|
-
startMcpServer: async (contextPath) => {
|
|
5157
|
+
startMcpServer: async (contextPath, clientFactory, maxRetries) => {
|
|
5158
|
+
log("starting MCP server", 1 /* INFO */);
|
|
4155
5159
|
const client = await createWorkerClient({
|
|
4156
5160
|
contextPath,
|
|
4157
5161
|
workerScript
|
|
4158
5162
|
});
|
|
4159
5163
|
try {
|
|
4160
|
-
const
|
|
5164
|
+
const tomlPath = (0, import_node_path12.join)(contextPath, "worker.toml");
|
|
5165
|
+
let autoCaptureConfig;
|
|
5166
|
+
try {
|
|
5167
|
+
const tomlText = (0, import_node_fs9.readFileSync)(tomlPath, "utf-8");
|
|
5168
|
+
const daemonConfig = parseWorkerToml(tomlText, contextPath);
|
|
5169
|
+
autoCaptureConfig = daemonConfig.autoCapture;
|
|
5170
|
+
} catch {
|
|
5171
|
+
}
|
|
5172
|
+
const server = createMcpServer(
|
|
5173
|
+
client,
|
|
5174
|
+
contextPath,
|
|
5175
|
+
autoCaptureConfig,
|
|
5176
|
+
clientFactory,
|
|
5177
|
+
maxRetries
|
|
5178
|
+
);
|
|
5179
|
+
log("MCP server listening on stdio", 0 /* DEBUG */);
|
|
4161
5180
|
await server.listen();
|
|
5181
|
+
log("MCP server closed", 1 /* INFO */);
|
|
4162
5182
|
} finally {
|
|
4163
5183
|
client.disconnect();
|
|
4164
5184
|
}
|
|
@@ -4170,7 +5190,7 @@ async function main() {
|
|
|
4170
5190
|
console.log(result.output);
|
|
4171
5191
|
}
|
|
4172
5192
|
if (result.error) {
|
|
4173
|
-
|
|
5193
|
+
log(result.error, 3 /* ERROR */);
|
|
4174
5194
|
}
|
|
4175
5195
|
if (result.exitCode !== 0) {
|
|
4176
5196
|
process.exitCode = result.exitCode;
|
|
@@ -4178,7 +5198,7 @@ async function main() {
|
|
|
4178
5198
|
}
|
|
4179
5199
|
main().catch((err) => {
|
|
4180
5200
|
const msg = err instanceof Error ? err.message : String(err);
|
|
4181
|
-
|
|
5201
|
+
log("error: " + msg, 3 /* ERROR */);
|
|
4182
5202
|
process.exitCode = 1;
|
|
4183
5203
|
});
|
|
4184
5204
|
//# sourceMappingURL=cli.cjs.map
|