@dikolab/kbdb 0.6.1 → 0.6.2
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 +33 -6
- package/README.md.bak +33 -6
- package/dist/README.md +33 -6
- package/dist/cli.cjs +662 -217
- package/dist/cli.cjs.map +3 -3
- package/dist/cli.mjs +662 -217
- package/dist/cli.mjs.map +3 -3
- package/dist/kbdb-worker.cjs +71 -12
- package/dist/kbdb-worker.cjs.map +3 -3
- package/dist/src/shared/cli/constants/recfile-field-maps.constant.d.ts +3 -1
- package/dist/src/shared/cli/functions/format-command-output.function.d.ts +0 -4
- package/dist/src/shared/cli/functions/format-command-text.function.d.ts +1 -0
- package/dist/src/shared/cli/functions/format-mcp-output.function.d.ts +5 -4
- package/dist/src/shared/cli/functions/format-output.function.d.ts +3 -7
- package/dist/src/shared/cli/functions/format-text-output.function.d.ts +3 -2
- package/dist/src/shared/cli/functions/run-agent-search.function.d.ts +13 -0
- package/dist/src/shared/cli/functions/run-check.function.d.ts +1 -1
- package/dist/src/shared/cli/functions/run-content.function.d.ts +18 -14
- package/dist/src/shared/cli/functions/run-learn.function.d.ts +6 -11
- package/dist/src/shared/cli/functions/run-skill-search.function.d.ts +13 -0
- package/dist/src/shared/cli/functions/wrap-mcp-envelope.function.d.ts +8 -0
- package/dist/src/shared/cli/typings/cli-options.interface.d.ts +6 -0
- package/dist/src/shared/cli/typings/learn-client.interface.d.ts +6 -2
- package/dist/src/shared/cli/typings/learn-result.model.d.ts +4 -0
- package/dist/src/shared/cli/typings/search-display.model.d.ts +2 -2
- package/dist/src/shared/mcp/constants/tool-agent-search.constant.d.ts +3 -0
- package/dist/src/shared/mcp/constants/tool-skill-search.constant.d.ts +3 -0
- package/dist/src/shared/mcp/functions/format-search-results.function.d.ts +25 -0
- package/dist/src/shared/mcp/functions/handle-agent-get.function.d.ts +4 -4
- package/dist/src/shared/mcp/functions/handle-agent-list.function.d.ts +3 -7
- package/dist/src/shared/mcp/functions/handle-agent-search.function.d.ts +11 -0
- package/dist/src/shared/mcp/functions/handle-recall.function.d.ts +1 -1
- package/dist/src/shared/mcp/functions/handle-skill-search.function.d.ts +11 -0
- package/dist/src/shared/mcp/functions/handle-tool-search.function.d.ts +3 -3
- package/dist/src/shared/mcp/typings/mcp-client.interface.d.ts +2 -2
- package/dist/src/shared/mcp/typings/mcp-worker-client.interface.d.ts +2 -2
- package/dist/src/shared/worker-client/typings/add-section-result.model.d.ts +6 -12
- package/dist/src/shared/worker-client/typings/status-result.model.d.ts +2 -2
- package/dist/src/shared/worker-daemon/functions/strip-recall-by-depth.function.d.ts +22 -0
- package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
- package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
- package/dist/worker.mjs +71 -12
- package/dist/worker.mjs.map +3 -3
- package/package.json +1 -1
package/dist/cli.mjs.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/cli.ts", "../src/shared/cli/constants/defaults.constant.ts", "../src/shared/cli/functions/parse-args.function.ts", "../src/shared/cli/functions/format-text-output.function.ts", "../src/shared/cli/functions/format-mcp-output.function.ts", "../src/shared/cli/functions/resolve-recfile-key.function.ts", "../src/shared/cli/functions/render-recfile-value.function.ts", "../src/shared/cli/functions/format-recfile-output.function.ts", "../src/shared/cli/constants/recfile-field-maps.constant.ts", "../src/shared/cli/functions/format-output.function.ts", "../src/shared/cli/constants/recfile-command-field-map.constant.ts", "../src/shared/cli/functions/format-command-output.function.ts", "../src/shared/cli/functions/run-search.function.ts", "../src/shared/cli/functions/resolve-kbid-prefix.function.ts", "../src/shared/cli/functions/run-recall.function.ts", "../src/shared/cli/functions/run-export.function.ts", "../src/shared/cli/functions/run-learn.function.ts", "../src/shared/cli/functions/collect-files.function.ts", "../src/shared/cli/functions/compute-directory-level.function.ts", "../src/shared/cli/functions/run-unlearn.function.ts", "../src/shared/cli/functions/run-content.function.ts", "../src/shared/cli/functions/run-check.function.ts", "../src/shared/cli/functions/run-gc.function.ts", "../src/shared/cli/functions/run-rebuild.function.ts", "../src/shared/cli/functions/find-db.function.ts", "../src/shared/cli/functions/run-init.function.ts", "../src/shared/cli/functions/install-default-skills.function.ts", "../src/shared/cli/functions/error-to-message.function.ts", "../src/shared/cli/functions/is-stdin-tty.function.ts", "../src/shared/cli/functions/prompt-user.function.ts", "../src/shared/cli/functions/run-status.function.ts", "../src/shared/cli/functions/run-db-init.function.ts", "../src/shared/cli/functions/run-db-migrate.function.ts", "../src/shared/mcp/functions/extract-skill-arguments.function.ts", "../src/shared/mcp/functions/serialize-skill-content.function.ts", "../src/shared/cli/functions/run-skill-learn.function.ts", "../src/shared/cli/functions/run-skill-list.function.ts", "../src/shared/mcp/functions/parse-skill-content.function.ts", "../src/shared/cli/functions/run-skill-get.function.ts", "../src/shared/cli/functions/run-skill-delete.function.ts", "../src/shared/cli/functions/run-agent-create.function.ts", "../src/shared/cli/functions/run-agent-list.function.ts", "../src/shared/cli/functions/run-agent-get.function.ts", "../src/shared/cli/functions/run-agent-delete.function.ts", "../src/shared/cli/functions/run-import.function.ts", "../src/shared/cli/functions/hydrate-search-previews.function.ts", "../src/shared/cli/functions/dispatch-command.function.ts", "../src/shared/version/constants/version.constant.ts", "../src/shared/cli/functions/generate-help.function.ts", "../src/shared/cli/functions/resolve-db-dir.function.ts", "../src/shared/cli/functions/format-db-not-found.function.ts", "../src/shared/cli/functions/run-db-path.function.ts", "../src/shared/worker-client/classes/worker-client.class.ts", "../src/shared/worker-client/functions/discover-daemon.function.ts", "../src/shared/platform/functions/is-process-alive.function.ts", "../src/shared/worker-client/functions/resolve-db-path.function.ts", "../src/shared/worker-client/functions/compute-context-id.function.ts", "../src/shared/worker-client/functions/spawn-daemon.function.ts", "../src/shared/worker-client/functions/build-deno-permissions.function.ts", "../src/shared/worker-client/functions/wait-for-daemon.function.ts", "../src/shared/worker-client/functions/read-crash-reason.function.ts", "../src/shared/worker-client/functions/resolve-spawn-script.function.ts", "../src/shared/worker-client/functions/create-worker-client.function.ts", "../src/shared/cli/functions/run-worker-stop.function.ts", "../src/shared/cli/functions/run-worker-restart.function.ts", "../src/shared/worker-client/functions/retry-on-timeout.function.ts", "../src/shared/worker-client/constants/request-timeout.constant.ts", "../src/shared/worker-client/constants/retry-defaults.constant.ts", "../src/shared/cli/functions/run-cli.function.ts", "../src/shared/cli/constants/help-text.constant.ts", "../src/shared/mcp/classes/mcp-server.class.ts", "../src/shared/mcp/functions/create-tool-definitions.function.ts", "../src/shared/mcp/functions/create-resource-templates.function.ts", "../src/shared/mcp/functions/handle-agent-create.function.ts", "../src/shared/mcp/functions/handle-agent-list.function.ts", "../src/shared/mcp/functions/handle-agent-get.function.ts", "../src/shared/mcp/functions/handle-agent-delete.function.ts", "../src/shared/mcp/functions/handle-recall.function.ts", "../src/shared/mcp/functions/handle-tool-call.function.ts", "../src/shared/mcp/functions/handle-resource-read.function.ts", "../src/shared/mcp/functions/create-prompt-definitions.function.ts", "../src/shared/mcp/functions/handle-prompt-get.function.ts", "../src/shared/mcp/functions/handle-completion.function.ts", "../src/shared/mcp/functions/handle-roots-list.function.ts", "../src/shared/mcp/functions/should-emit-log.function.ts", "../src/shared/auto-capture/functions/build-capture-prompt.function.ts", "../src/shared/mcp/functions/has-sampling-capability.function.ts", "../src/shared/mcp/functions/run-auto-capture.function.ts", "../src/shared/auto-capture/functions/evaluate-trigger.function.ts", "../src/shared/auto-capture/classes/auto-capture-controller.class.ts", "../src/shared/mcp/constants/mcp-error-codes.constant.ts", "../src/shared/mcp/functions/create-mcp-server.function.ts"],
|
|
4
|
-
"sourcesContent": ["// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * @module\n *\n * CLI and MCP server executable for kbdb. Provides the\n * `kbdb` command with 18 subcommands for managing a\n * file-based knowledge base, and an MCP server mode\n * for AI agent integration.\n */\n\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getArgs } from './shared/runtime/index.ts';\nimport {\n runCli,\n isStdinTty,\n promptUser,\n findDb,\n runInit,\n} from './shared/cli/index.ts';\nimport type { CliDeps } from './shared/cli/index.ts';\nimport { createWorkerClient } from './shared/worker-client/index.ts';\nimport { createMcpServer } from './shared/mcp/index.ts';\nimport type { McpWorkerClient } from './shared/mcp/typings/mcp-client.interface.ts';\nimport { parseWorkerToml } from './shared/worker-daemon/functions/parse-worker-toml.function.ts';\nimport { log } from './shared/log/functions/log.function.ts';\nimport { LogLevel } from './shared/log/typings/log-level.type.ts';\n\nconst deps: CliDeps = {\n isStdinTty,\n isStdoutTty: () => process.stdout.isTTY,\n promptUser,\n createWorkerClient: (opts) => createWorkerClient(opts),\n findDb,\n runInit,\n startMcpServer: async (contextPath, clientFactory, maxRetries) => {\n log('starting MCP server', LogLevel.INFO);\n const client = await createWorkerClient({ contextPath });\n try {\n const tomlPath = join(contextPath, 'worker.toml');\n let autoCaptureConfig;\n try {\n const tomlText = readFileSync(tomlPath, 'utf-8');\n const daemonConfig = parseWorkerToml(tomlText, contextPath);\n autoCaptureConfig = daemonConfig.autoCapture;\n } catch {\n // worker.toml absent or unreadable\n }\n const server = createMcpServer(\n client,\n contextPath,\n autoCaptureConfig,\n clientFactory as\n | (() => Promise<McpWorkerClient>)\n | undefined,\n maxRetries,\n );\n log('MCP server listening on stdio', LogLevel.DEBUG);\n await server.listen();\n log('MCP server closed', LogLevel.INFO);\n } finally {\n client.disconnect();\n }\n },\n};\n\nasync function main(): Promise<void> {\n const result = await runCli(getArgs(), deps);\n if (result.output) {\n // eslint-disable-next-line no-console\n console.log(result.output);\n }\n if (result.error) {\n log(result.error, LogLevel.ERROR);\n }\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n}\n\nmain().catch((err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err);\n log('error: ' + msg, LogLevel.ERROR);\n process.exitCode = 1;\n});\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Default maximum number of search results returned per query. */\nexport const DEFAULT_LIMIT = 20;\n\n/** Default output format when `--format` is not specified. */\nexport const DEFAULT_FORMAT = 'rec' as const;\n\n/** Default search mode when `--mode` is not specified. */\nexport const DEFAULT_MODE = 'sections' as const;\n\n/**\n * File extensions recognised as importable documents by the learn\n * command. Extensions are lowercase and include the leading dot.\n */\nexport const SUPPORTED_EXTENSIONS = [\n '.md',\n '.txt',\n '.rst',\n '.adoc',\n] as const;\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport {\n DEFAULT_FORMAT,\n DEFAULT_LIMIT,\n DEFAULT_MODE,\n} from '../constants/defaults.constant.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { parseLogLevel } from '../../log/functions/parse-log-level.function.ts';\n\n/**\n * Parses a raw argument vector into a structured `CliOptions` object.\n *\n * Recognises `--help` / `-h` and `--version` / `-v` as early-exit\n * flags that set the command and return immediately. All other flags\n * consume the next token as their value. The first non-flag token\n * becomes the command; subsequent non-flag tokens become `args`.\n *\n * Compound commands are supported: when the first positional token is\n * a group name (`db`, `skill`, `agent`, or `worker`), the next\n * positional token is joined with a hyphen to form the compound\n * command (e.g. `db init` \u2192 `'db-init'`,\n * `worker stop` \u2192 `'worker-stop'`).\n *\n * Context-aware `--help`: when `--help` or `-h` appears after a\n * command has been set, the existing command is moved to `args[0]`\n * and the command is set to `'help'`, enabling per-command help.\n *\n * Deprecated flags `--init` and `--migrate` emit a warning to stderr\n * before setting the corresponding command.\n *\n * @param argv - argument strings (typically `process.argv.slice(2)`)\n * @returns fully populated `CliOptions` with defaults applied\n */\nexport function parseArgs(argv: string[]): CliOptions {\n const options: CliOptions = {\n command: '',\n format: DEFAULT_FORMAT,\n mode: DEFAULT_MODE,\n limit: DEFAULT_LIMIT,\n args: [],\n };\n\n let i = 0;\n while (i < argv.length) {\n const arg = argv[i];\n switch (arg) {\n case '--help':\n case '-h':\n if (options.command) {\n options.args.unshift(options.command);\n options.command = 'help';\n } else {\n options.command = 'help';\n }\n return options;\n case '--version':\n options.command = 'version';\n return options;\n case '-v':\n case '--verbose': {\n const next = argv[i + 1];\n if (next && !next.startsWith('-')) {\n options.logLevel = parseLogLevel(next);\n i++;\n } else {\n options.logLevel = LogLevel.WARNING;\n }\n break;\n }\n case '-vv':\n case '--verbose-info':\n options.logLevel = LogLevel.INFO;\n break;\n case '-vvv':\n case '--verbose-debug':\n options.logLevel = LogLevel.DEBUG;\n break;\n case '--init':\n options.command = 'init';\n break;\n case '--migrate':\n options.command = 'migrate';\n break;\n case '--db':\n options.dbPath = argv[++i];\n break;\n case '--format':\n case '-f':\n options.format = (argv[++i] ??\n DEFAULT_FORMAT) as CliOptions['format'];\n options.formatExplicit = true;\n break;\n case '--mode':\n case '-m':\n options.mode = (argv[++i] ??\n DEFAULT_MODE) as CliOptions['mode'];\n break;\n case '--limit':\n case '-l':\n options.limit =\n parseInt(argv[++i] ?? '', 10) || DEFAULT_LIMIT;\n break;\n case '--offset':\n case '-o':\n options.offset = Math.max(\n 0,\n parseInt(argv[++i] ?? '', 10) || 0,\n );\n break;\n case '--algo':\n options.algo = argv[++i];\n break;\n case '--title':\n options.title = argv[++i];\n break;\n case '--description':\n options.description = argv[++i];\n break;\n case '--docid':\n options.docid = argv[++i];\n break;\n case '--name':\n options.name = argv[++i];\n break;\n case '--persona':\n options.persona = argv[++i];\n break;\n case '--body':\n options.body = argv[++i];\n break;\n case '--skills':\n options.skills = (argv[++i] ?? '').split(',');\n break;\n case '--tags':\n options.tags = (argv[++i] ?? '').split(',');\n break;\n case '--replace':\n options.replace = true;\n break;\n case '--level':\n case '--weight': {\n const raw = argv[++i];\n const n = Number(raw);\n if (!Number.isInteger(n) || n < 1 || n > 6) {\n throw new Error(\n `Invalid level \"${raw}\": must be integer 1-6`,\n );\n }\n options.level = n;\n break;\n }\n case '--depth':\n case '-d':\n options.depth = Math.min(\n 3,\n Math.max(0, parseInt(argv[++i] ?? '', 10) || 0),\n );\n break;\n case '--content':\n case '-c':\n options.content = true;\n break;\n case '--relaxed':\n options.relaxed = true;\n break;\n case '--from':\n options.from = argv[++i];\n break;\n case '--dry-run':\n options.dryRun = true;\n break;\n case '--export-format':\n options.exportFormat = (argv[++i] ??\n 'git') as CliOptions['exportFormat'];\n break;\n case '--timeout-ms':\n options.timeoutMs =\n parseInt(argv[++i] ?? '', 10) || undefined;\n break;\n case '--retry':\n options.retry = parseInt(argv[++i] ?? '', 10) || undefined;\n break;\n case '--non-interactive':\n options.nonInteractive = true;\n break;\n default:\n if (!options.command) {\n options.command = arg;\n } else if (\n !options.args.length &&\n (options.command === 'db' ||\n options.command === 'skill' ||\n options.command === 'agent' ||\n options.command === 'worker')\n ) {\n options.command = `${options.command}-${arg}`;\n } else {\n options.args.push(arg);\n }\n }\n i++;\n }\n\n return options;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\n\n/**\n * Formats a paged search result as a numbered human-readable\n * text list with a paging footer and optional \"more\" hint.\n *\n * @param paged - paginated search results to render\n * @returns formatted string ready for stdout\n */\nexport function formatTextOutput(paged: PagedSearchDisplay): string {\n if (paged.items.length === 0) return 'No results found.';\n const start = paged.offset + 1;\n const end = paged.offset + paged.items.length;\n\n const lines = paged.items\n .map((r, i) => {\n const num = paged.offset + i + 1;\n const heading = r.heading ?? '(untitled)';\n const terms = r.matched_terms.join(', ');\n const fields = r.matched_fields.join(', ');\n const confidencePct = (r.confidence * 100).toFixed(0);\n return (\n `${String(num)}. [${r.kbid}] ${heading}` +\n ` (score: ${r.score.toFixed(4)},` +\n ` confidence: ${confidencePct}%)\\n` +\n ` ${r.snippet || r.preview || '(no snippet)'}\\n` +\n ` type: ${r.type}` +\n ` terms: ${terms}` +\n (fields ? ` fields: ${fields}` : '')\n );\n })\n .join('\\n\\n');\n\n const footer =\n `\\nShowing ${String(start)}-${String(end)}` +\n ` of ${String(paged.total)} results`;\n const hint = paged.has_more\n ? `\\nUse --offset ${String(end)} to see more`\n : '';\n\n return lines + footer + hint;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\n\n/**\n * Formats a paged search result as a JSON string compatible\n * with the MCP (Model Context Protocol) `text` content block.\n *\n * @param paged - paginated search results to serialise\n * @returns MCP-compatible JSON string ready for stdout\n */\nexport function formatMcpOutput(paged: PagedSearchDisplay): string {\n const mcpItems = paged.items.map((r) => ({\n kbid: r.kbid,\n heading: r.heading,\n type: r.type,\n docids: r.docids,\n snippet: r.snippet,\n matched_terms: r.matched_terms,\n matched_fields: r.matched_fields,\n created_at: r.created_at,\n }));\n return JSON.stringify(\n {\n type: 'text',\n text: paged.items\n .map(\n (r) =>\n `[${r.kbid}] ${r.heading ?? '(untitled)'}` +\n ` \u2014 ${r.snippet || r.preview}`,\n )\n .join('\\n'),\n items: mcpItems,\n total: paged.total,\n offset: paged.offset,\n limit: paged.limit,\n has_more: paged.has_more,\n relaxed: paged.relaxed,\n },\n null,\n 2,\n );\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Resolves a dot-notation property path (e.g.\n * `'cacheStats.contentCount'`) against an object, returning\n * `undefined` if any segment along the path is missing.\n *\n * @param obj - the object to traverse\n * @param key - dot-separated property path\n */\nexport function resolveRecfileKey(obj: unknown, key: string): unknown {\n const parts = key.split('.');\n let current: unknown = obj;\n for (const part of parts) {\n if (current == null || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Renders a value for recfile output, or returns `null` when the\n * value is absent and the field should be omitted.\n *\n * Arrays render comma-separated; booleans render as `'true'` or\n * `'false'`; `null`, `undefined`, empty strings, and empty\n * arrays are treated as absent.\n *\n * @param value - the value to render\n */\nexport function renderRecfileValue(value: unknown): string | null {\n if (value === null || value === undefined) return null;\n if (Array.isArray(value)) {\n if (value.length === 0) return null;\n return value.map(String).join(', ');\n }\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n if (typeof value === 'number') return String(value);\n if (typeof value === 'string') return value === '' ? null : value;\n return JSON.stringify(value);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { RecfileFieldMap } from '../typings/recfile-field-map.type.ts';\nimport { resolveRecfileKey } from './resolve-recfile-key.function.ts';\nimport { renderRecfileValue } from './render-recfile-value.function.ts';\n\n/**\n * Formats one or more records as recfile (GNU recutils style)\n * output: `Field: Value` pairs, blank-line separated records,\n * and `+ ` continuation lines for multi-line values.\n *\n * @param data - a single record or an array of records\n * @param fields - ordered field map controlling which\n * properties are rendered and in what order\n */\nexport function formatRecfileOutput(\n data: unknown,\n fields: RecfileFieldMap,\n): string {\n const records = Array.isArray(data) ? data : [data];\n return records\n .map((record) => formatRecord(record, fields))\n .filter(Boolean)\n .join('\\n\\n');\n}\n\nfunction formatRecord(\n record: unknown,\n fields: RecfileFieldMap,\n): string {\n if (!record || typeof record !== 'object') return '';\n const lines: string[] = [];\n for (const [field, key] of fields) {\n const value = resolveRecfileKey(record, key);\n const rendered = renderRecfileValue(value);\n if (rendered === null) continue;\n lines.push(formatField(field, rendered));\n }\n return lines.join('\\n');\n}\n\nfunction formatField(field: string, value: string): string {\n const lines = value.split('\\n');\n if (lines.length === 1) return `${field}: ${lines[0]}`;\n return [\n `${field}: ${lines[0]}`,\n ...lines.slice(1).map((line) => `+ ${line}`),\n ].join('\\n');\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { RecfileFieldMap } from '../typings/recfile-field-map.type.ts';\n\n/** Field map for search results (per item in `items[]`). */\nexport const SEARCH_FIELDS: RecfileFieldMap = [\n ['kbid', 'kbid'],\n ['heading', 'heading'],\n ['score', 'score'],\n ['confidence', 'confidence'],\n ['type', 'type'],\n ['terms', 'matched_terms'],\n ['fields', 'matched_fields'],\n ['snippet', 'snippet'],\n ['level', 'level'],\n] as const;\n\n/** Field map for learn results (per item in array). */\nexport const LEARN_FIELDS: RecfileFieldMap = [\n ['kbid', 'kbid'],\n ['path', 'path'],\n ['size', 'size'],\n ['skipped', 'skipped'],\n ['superseded', 'superseded'],\n ['warnings', 'warnings'],\n ['level', 'level'],\n] as const;\n\n/** Field map for unlearn (remove) result. */\nexport const UNLEARN_FIELDS: RecfileFieldMap = [\n ['removed', 'removed'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n\n/** Field map for recall results (per item). */\nexport const RECALL_FIELDS: RecfileFieldMap = [\n ['kbid', 'kbid'],\n ['heading', 'heading'],\n ['type', 'type'],\n ['docids', 'docids'],\n ['content', 'content'],\n ['level', 'level'],\n] as const;\n\n/** Field map for export result. */\nexport const EXPORT_FIELDS: RecfileFieldMap = [\n ['path', 'path'],\n ['sections', 'sections_exported'],\n ['documents', 'documents_exported'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n\n/** Field map for import result. */\nexport const IMPORT_FIELDS: RecfileFieldMap = [\n ['sections', 'sections_imported'],\n ['documents', 'documents_imported'],\n ['rebuilt', 'rebuilt'],\n ['dry_run', 'dry_run'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n\n/** Field map for status result. */\nexport const STATUS_FIELDS: RecfileFieldMap = [\n ['initialized', 'initialized'],\n ['path', 'contextPath'],\n ['content_cached', 'cacheStats.contentCount'],\n ['index_cached', 'cacheStats.indexCount'],\n] as const;\n\n/** Field map for check (integrity) result. */\nexport const CHECK_FIELDS: RecfileFieldMap = [\n ['ok', 'ok'],\n ['sections_checked', 'sections_checked'],\n ['documents_checked', 'documents_checked'],\n ['references_checked', 'references_checked'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n\n/** Field map for gc result. */\nexport const GC_FIELDS: RecfileFieldMap = [\n ['removed_sections', 'removed_sections'],\n ['removed_bytes', 'removed_bytes'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n\n/** Field map for rebuild result. */\nexport const REBUILD_FIELDS: RecfileFieldMap = [\n ['sections_reindexed', 'sections_reindexed'],\n ['terms_indexed', 'terms_indexed'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { OutputFormat } from '../typings/cli-options.interface.ts';\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\nimport { formatTextOutput } from './format-text-output.function.ts';\nimport { formatMcpOutput } from './format-mcp-output.function.ts';\nimport { formatRecfileOutput } from './format-recfile-output.function.ts';\nimport { SEARCH_FIELDS } from '../constants/recfile-field-maps.constant.ts';\n\n/**\n * Serialises a paged search result into the requested output\n * format string.\n *\n * - `'json'` -- pretty-printed JSON envelope\n * - `'text'` -- numbered human-readable list with paging footer\n * - `'rec'` -- recfile field records, one per result\n * - `'mcp'` -- JSON envelope compatible with MCP protocol\n *\n * @param paged - paginated search results to format\n * @param format - target output format\n * @returns formatted string ready for stdout\n */\nexport function formatOutput(\n paged: PagedSearchDisplay,\n format: OutputFormat,\n): string {\n switch (format) {\n case 'json':\n return JSON.stringify(paged, null, 2);\n case 'text':\n return formatTextOutput(paged);\n case 'rec':\n return formatRecfileOutput(paged.items, SEARCH_FIELDS);\n case 'mcp':\n return formatMcpOutput(paged);\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { RecfileFieldMap } from '../typings/recfile-field-map.type.ts';\nimport {\n CHECK_FIELDS,\n EXPORT_FIELDS,\n GC_FIELDS,\n IMPORT_FIELDS,\n LEARN_FIELDS,\n REBUILD_FIELDS,\n RECALL_FIELDS,\n STATUS_FIELDS,\n UNLEARN_FIELDS,\n} from './recfile-field-maps.constant.ts';\n\n/**\n * Looks up the recfile field map for a dispatch command name.\n * Commands without an entry (e.g. `search`, which renders via\n * `formatOutput` instead) fall back to JSON in\n * `formatCommandOutput`.\n */\nexport const RECFILE_COMMAND_FIELD_MAP: Readonly<\n Partial<Record<string, RecfileFieldMap>>\n> = {\n learn: LEARN_FIELDS,\n unlearn: UNLEARN_FIELDS,\n recall: RECALL_FIELDS,\n export: EXPORT_FIELDS,\n import: IMPORT_FIELDS,\n status: STATUS_FIELDS,\n check: CHECK_FIELDS,\n gc: GC_FIELDS,\n rebuild: REBUILD_FIELDS,\n};\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { OutputFormat } from '../typings/cli-options.interface.ts';\nimport { formatRecfileOutput } from './format-recfile-output.function.ts';\nimport { RECFILE_COMMAND_FIELD_MAP } from '../constants/recfile-command-field-map.constant.ts';\n\n/**\n * Formats a command result for the given output format.\n *\n * `'rec'` output is routed through the recfile field map\n * registered for `command`; commands without a registered map\n * fall back to pretty-printed JSON.\n *\n * @param data - the command result to render\n * @param format - target output format\n * @param command - dispatch command name used to look up the\n * recfile field map (e.g. `'learn'`, `'status'`)\n */\nexport function formatCommandOutput(\n data: unknown,\n format: OutputFormat,\n command: string,\n): string {\n switch (format) {\n case 'rec': {\n const fields = RECFILE_COMMAND_FIELD_MAP[command];\n return fields\n ? formatRecfileOutput(data, fields)\n : JSON.stringify(data, null, 2);\n }\n case 'json':\n case 'text':\n case 'mcp':\n return JSON.stringify(data, null, 2);\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** A single raw search result item returned by the daemon. */\ninterface RawSearchItem {\n /** Knowledge-base identifier of the matched section. */\n readonly kbid: string;\n /** Section heading, or null when untitled. */\n readonly heading: string | null;\n /** MIME type of the section content. */\n readonly type: string;\n /** Document IDs this section belongs to. */\n readonly docids: readonly string[];\n /** Relevance score from the ranking engine. */\n readonly score: number;\n /** KWIC excerpt centered on the highest-scoring matched term. */\n readonly snippet: string;\n /** Query terms that matched within this section. */\n readonly matched_terms: readonly string[];\n /**\n * Fields that contained at least one match.\n * May be absent from older daemon versions.\n */\n readonly matched_fields?: readonly string[];\n /**\n * Normalised confidence score (0.0-1.0) relative to the top result.\n * May be absent from older daemon versions.\n */\n readonly confidence?: number;\n /**\n * ISO 8601 creation timestamp of the section.\n * May be absent from older daemon versions.\n */\n readonly created_at?: string;\n}\n\n/** Raw paginated search response from the daemon. */\ninterface RawSearchResponse {\n /** Result items for the current page. */\n readonly items: readonly RawSearchItem[];\n /** Total number of matches across all pages. */\n readonly total: number;\n /** Number of results skipped. */\n readonly offset: number;\n /** Maximum results per page. */\n readonly limit: number;\n /** Whether more results exist beyond this page. */\n readonly has_more: boolean;\n /**\n * When `true`, the engine relaxed the query to produce results.\n * May be absent from older daemon versions.\n */\n readonly relaxed?: boolean;\n /** Server-side computation time in milliseconds. */\n readonly elapsed_ms?: number;\n /** Algorithm that produced these results. */\n readonly search_mode?: string;\n /** Retrieval strategy used (e.g. `'lexical'`, `'rrf'`). */\n readonly retrieval_method?: string;\n}\n\n/**\n * Minimal client interface required by `runSearch`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface SearchClient {\n /**\n * Searches the knowledge base and returns paginated results.\n *\n * @param params - query, mode, limit, and offset\n */\n search(params: {\n query: string;\n mode?: string;\n limit?: number;\n offset?: number;\n algo?: string;\n relaxed?: boolean;\n }): Promise<RawSearchResponse>;\n}\n\n/**\n * Executes a search query via the provided client and maps the\n * daemon results to the `PagedSearchDisplay` format used by the\n * CLI.\n *\n * Returns an empty paged result without calling the client when\n * `options.args` contains no query terms.\n *\n * @param client - search client to delegate to\n * @param options - parsed CLI options supplying query args and\n * search parameters\n */\nexport async function runSearch(\n client: SearchClient,\n options: CliOptions,\n): Promise<PagedSearchDisplay> {\n log('searching: ' + options.args.join(' '), LogLevel.DEBUG);\n const query = options.args.join(' ').trim();\n if (!query) {\n return {\n items: [],\n total: 0,\n offset: 0,\n limit: options.limit,\n has_more: false,\n relaxed: false,\n };\n }\n\n const results = await client.search({\n query,\n mode: options.mode,\n limit: options.limit,\n offset: options.offset,\n algo: options.algo,\n relaxed: options.relaxed,\n });\n\n log(\n 'search returned ' + results.total.toString() + ' results',\n LogLevel.DEBUG,\n );\n\n return {\n items: results.items.map((r) => ({\n kbid: r.kbid,\n heading: r.heading,\n type: r.type,\n docids: r.docids,\n score: r.score,\n confidence: r.confidence ?? 0,\n snippet: r.snippet,\n matched_terms: r.matched_terms,\n matched_fields: r.matched_fields ?? [],\n created_at: r.created_at ?? '',\n preview: '',\n })),\n total: results.total,\n offset: results.offset,\n limit: results.limit,\n has_more: results.has_more,\n relaxed: results.relaxed ?? false,\n elapsed_ms: results.elapsed_ms,\n search_mode: results.search_mode,\n retrieval_method: results.retrieval_method,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface for listing section kbids.\n *\n * Decouples prefix resolution from the concrete\n * `WorkerClient` so tests can use lightweight mocks.\n */\nexport interface PrefixResolver {\n /** Returns all sections of the given type. */\n listByType(\n sectionType: string,\n ): Promise<readonly { kbid: string }[]>;\n}\n\n/** Section types to scan when resolving a kbid prefix. */\nconst SECTION_TYPES = ['text', 'code', 'image'] as const;\n\n/**\n * Resolves a potentially short kbid prefix to its full\n * 26-character identifier.\n *\n * Full-length identifiers (>= 26 chars) are returned as-is.\n * For shorter prefixes, all section types are scanned to find\n * matching kbids. Throws when no match is found or the prefix\n * is ambiguous (matches more than one kbid).\n *\n * @param prefix - full or partial kbid string\n * @param client - client providing `listByType`\n * @returns the resolved full kbid\n * @throws when no match or ambiguous match is found\n */\nexport async function resolveKbidPrefix(\n prefix: string,\n client: PrefixResolver,\n): Promise<string> {\n if (prefix.length >= 26) return prefix;\n\n const seen = new Set<string>();\n for (const type of SECTION_TYPES) {\n const records = await client.listByType(type);\n for (const r of records) {\n if (r.kbid.startsWith(prefix)) seen.add(r.kbid);\n }\n }\n\n if (seen.size === 0) {\n const msg = `no section matches prefix \"${prefix}\"`;\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n if (seen.size > 1) {\n const msg =\n `ambiguous prefix \"${prefix}\":` +\n ` ${seen.size.toString()} matches`;\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n\n return [...seen][0];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { RecallResult } from '../../worker-client/typings/recall-result.model.ts';\nimport type { PrefixResolver } from './resolve-kbid-prefix.function.ts';\nimport { resolveKbidPrefix } from './resolve-kbid-prefix.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** Maximum allowed expansion depth for recall operations. */\nconst MAX_RECALL_DEPTH = 3;\n\n/**\n * Minimal client interface required by `runRecall`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n * Extends `PrefixResolver` so short kbid prefixes can be resolved\n * before the recall call is made.\n */\nexport interface RecallClient extends PrefixResolver {\n /**\n * Retrieves full content and context for one or more sections\n * by their knowledge-base identifiers.\n *\n * @param params - section identifier(s) and optional expansion\n * depth (0--3)\n * @returns a single `RecallResult` when `kbid` is supplied, or\n * a `RecallResult[]` when `kbids` is supplied\n */\n recall(params: {\n kbid?: string;\n kbids?: string[];\n depth?: number;\n }): Promise<RecallResult | RecallResult[]>;\n}\n\n/**\n * Retrieves full content and progressive context for one or more\n * sections by kbid via the provided client.\n *\n * Returns an error result when no kbids are provided in\n * `options.args`. Short kbid prefixes in `options.args` are\n * resolved to full identifiers before the recall call. For a single\n * kbid, calls `client.recall` with the `kbid` parameter and returns\n * the single `RecallResult`. For multiple kbids, calls\n * `client.recall` with the `kbids` array.\n *\n * The `depth` option is read from `options.depth`, defaulting to 0\n * and clamped to the range 0--3.\n *\n * @param client - recall client to delegate to\n * @param options - parsed CLI options supplying kbids in `args` and\n * expansion depth in `depth`\n * @returns the `RecallResult` or `RecallResult[]` from the client,\n * or an error object when no kbids are provided\n * @throws when a prefix matches no section or is ambiguous\n */\nexport async function runRecall(\n client: RecallClient,\n options: CliOptions,\n): Promise<RecallResult | RecallResult[] | { error: string }> {\n log('running recall', LogLevel.DEBUG);\n if (options.args.length === 0) {\n return { error: 'no kbid provided' };\n }\n\n const depth = Math.min(\n MAX_RECALL_DEPTH,\n Math.max(0, options.depth ?? 0),\n );\n\n const resolved = await Promise.all(\n options.args.map((a) => resolveKbidPrefix(a, client)),\n );\n\n if (resolved.length === 1) {\n return client.recall({ kbid: resolved[0], depth });\n }\n\n return client.recall({ kbids: resolved, depth });\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { resolve } from 'node:path';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { ExportResult } from '../../worker-client/typings/export-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runExport`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface ExportClient {\n /**\n * Exports the database to the given directory path.\n *\n * @param params - optional absolute target path; the daemon\n * picks its own default, relative to the database directory,\n * when `path` is `undefined`\n * @returns export report with the resolved path and file counts\n */\n export(params: { path?: string }): Promise<ExportResult>;\n}\n\n/**\n * Exports the knowledge-base database to a target directory via the\n * provided client.\n *\n * The target path is taken from `options.args[0]` and resolved\n * against the current working directory so that the daemon --\n * which may run with a different working directory -- always\n * receives an absolute path. When no argument is given, the daemon\n * picks its own default.\n *\n * @param client - export client to delegate to\n * @param options - parsed CLI options whose first positional\n * argument, if present, is the target directory path\n * @returns the export result containing the resolved path and file\n * counts\n */\nexport async function runExport(\n client: ExportClient,\n options: CliOptions,\n): Promise<ExportResult> {\n log('running export', LogLevel.DEBUG);\n const path =\n options.args.length > 0\n ? resolve(process.cwd(), options.args[0])\n : undefined;\n return client.export({ path });\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { readFileSync } from 'node:fs';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { LearnResult } from '../typings/learn-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { collectFiles } from './collect-files.function.ts';\nimport { computeDirectoryLevel } from './compute-directory-level.function.ts';\n\n/** Enriched add-section result returned by the daemon. */\ninterface AddSectionResult {\n /** Knowledge-base identifier assigned to the new section. */\n readonly kbid: string;\n /**\n * Kbid of the section superseded via `--replace`,\n * or `null` / `undefined` when none.\n */\n readonly superseded?: string | null;\n /**\n * Advisory warning strings (e.g. `\"heading_missing\"`).\n * May be absent from older daemon versions.\n */\n readonly warnings?: string[];\n /**\n * Near-duplicate sections with similarity >= 0.85.\n * May be absent from older daemon versions.\n */\n readonly near_duplicates?: {\n readonly kbid: string;\n readonly similarity: number;\n }[];\n}\n\n/**\n * Minimal client interface required by `runLearn`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface LearnClient {\n /**\n * Ingests a content section into the knowledge base.\n *\n * @param params - section metadata and raw text content\n * @returns enriched result containing the new kbid plus\n * optional supersession, warnings, and near-duplicate info\n */\n addSection(params: {\n sectionType: string;\n content: string;\n title?: string;\n description?: string;\n docid?: string;\n tags?: string[];\n replace?: boolean;\n /**\n * Absolute path to the source file. Required for supersession\n * via source key when `replace` is `true`.\n */\n sourcePath?: string;\n /**\n * Hierarchical level (1-6). Explicitly set via `--level`, or\n * auto-detected from directory depth. `undefined` means no\n * level (the engine defaults to 1).\n */\n level?: number;\n }): Promise<AddSectionResult>;\n}\n\n/** Injectable I/O for testing without real stdin. */\nexport interface LearnIO {\n readStdin: () => Promise<string>;\n}\n\n/**\n * Ingests one or more files or directories listed in `options.args`\n * into the knowledge base via the provided client.\n *\n * Each argument is resolved to a set of supported files. Unsupported\n * extensions, dotfiles, dot-directories, and non-existent paths are\n * silently skipped. The `-` argument reads content from stdin\n * (consumed only once).\n *\n * When `options.level` is unset, the level sent for each file is\n * auto-detected from its depth relative to the target argument\n * (root = 1, each subdirectory +1, capped at 6). Stdin input has no\n * directory to derive a level from, so it is sent unset unless\n * `options.level` is explicit.\n *\n * @param client - learn client to delegate ingestion to\n * @param options - parsed CLI options whose `args` list targets to\n * ingest\n * @param io - injectable I/O (defaults to reading process.stdin)\n * @returns one `LearnResult` per file successfully ingested\n */\nexport async function runLearn(\n client: LearnClient,\n options: CliOptions,\n io?: LearnIO,\n): Promise<LearnResult[]> {\n log(\n 'learning ' + options.args.length.toString() + ' targets',\n LogLevel.DEBUG,\n );\n const results: LearnResult[] = [];\n let stdinConsumed = false;\n const readStdin = io?.readStdin ?? readProcessStdin;\n\n for (const target of options.args) {\n if (target === '-') {\n if (stdinConsumed) continue;\n stdinConsumed = true;\n const content = await readStdin();\n const result = await client.addSection({\n sectionType: 'text',\n content,\n title: options.title,\n description: options.description,\n docid: options.docid,\n tags: options.tags,\n replace: options.replace,\n level: options.level,\n });\n results.push(mapAddSectionResult(result, '-', content.length));\n continue;\n }\n\n const files = collectFiles(target);\n for (const file of files) {\n const content = readFileSync(file, 'utf-8');\n const result = await client.addSection({\n sectionType: 'text',\n content,\n title: options.title,\n description: options.description,\n docid: options.docid,\n tags: options.tags,\n replace: options.replace,\n sourcePath: file,\n level: options.level ?? computeDirectoryLevel(file, target),\n });\n results.push(\n mapAddSectionResult(result, file, content.length),\n );\n }\n }\n\n log(\n 'learned ' + results.length.toString() + ' sections',\n LogLevel.DEBUG,\n );\n return results;\n}\n\n/**\n * Maps an `AddSectionResult` to a `LearnResult` record.\n *\n * @param result - raw result from `client.addSection()`\n * @param path - source file path or `'-'` for stdin\n * @param size - UTF-8 character count of the ingested content\n */\nfunction mapAddSectionResult(\n result: AddSectionResult,\n path: string,\n size: number,\n): LearnResult {\n return {\n kbid: result.kbid,\n path,\n size,\n skipped: false,\n superseded: result.superseded ?? null,\n warnings: result.warnings ?? [],\n near_duplicates: result.near_duplicates ?? [],\n };\n}\n\nfunction readProcessStdin(): Promise<string> {\n return new Promise<string>((resolve) => {\n const chunks: Buffer[] = [];\n process.stdin.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n process.stdin.on('end', () => {\n resolve(Buffer.concat(chunks).toString('utf-8'));\n });\n process.stdin.resume();\n });\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { readdirSync, statSync } from 'node:fs';\nimport { basename, extname, join } from 'node:path';\nimport { SUPPORTED_EXTENSIONS } from '../constants/defaults.constant.ts';\n\n/**\n * Resolves a single target path to a flat list of supported files.\n *\n * When `target` is a file, returns it wrapped in an array if its\n * extension is in `SUPPORTED_EXTENSIONS` and it is not a dotfile;\n * otherwise returns `[]`. When `target` is a directory, recursively\n * collects all matching files, skipping dot-entries at every level.\n * Returns `[]` for non-existent or inaccessible paths.\n *\n * @param target - file or directory path to resolve\n * @returns flat array of absolute or relative paths to supported files\n */\nexport function collectFiles(target: string): string[] {\n try {\n const stat = statSync(target);\n if (stat.isFile()) {\n return isSupportedFile(target) ? [target] : [];\n }\n if (stat.isDirectory()) {\n return scanDirectory(target);\n }\n } catch {\n // Non-existent or inaccessible path -- skip\n }\n return [];\n}\n\nfunction scanDirectory(dir: string): string[] {\n const files: string[] = [];\n for (const entry of readdirSync(dir)) {\n if (entry.startsWith('.')) continue;\n const full = join(dir, entry);\n try {\n const stat = statSync(full);\n if (stat.isDirectory()) {\n files.push(...scanDirectory(full));\n } else if (isSupportedFile(full)) {\n files.push(full);\n }\n } catch {\n // Skip inaccessible entries\n }\n }\n return files;\n}\n\nfunction isSupportedFile(path: string): boolean {\n if (basename(path).startsWith('.')) return false;\n const ext = extname(path).toLowerCase();\n return (SUPPORTED_EXTENSIONS as readonly string[]).includes(ext);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Maximum hierarchical level. Deeper paths are clamped to this. */\nconst MAX_LEVEL = 6;\n\n/**\n * Derives a hierarchical level (1-6) from a file's depth relative\n * to the target path it was learned from.\n *\n * A file at the root of `basePath` is level 1; each intervening\n * subdirectory adds one level, up to `MAX_LEVEL`. When `filePath`\n * equals `basePath` (a single file target), the result is 1.\n *\n * @param filePath - absolute path to the file being learned\n * @param basePath - the target path originally passed on the CLI\n * (a file or directory)\n * @returns the computed level, clamped between 1 and `MAX_LEVEL`\n */\nexport function computeDirectoryLevel(\n filePath: string,\n basePath: string,\n): number {\n const relative = filePath.slice(basePath.length).replace(/^\\//, '');\n const depth = relative.split('/').length - 1;\n return Math.min(depth + 1, MAX_LEVEL);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { PrefixResolver } from './resolve-kbid-prefix.function.ts';\nimport { resolveKbidPrefix } from './resolve-kbid-prefix.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** Removal result returned by `UnlearnClient.removeSection`. */\ninterface RemoveSectionResult {\n /** `true` when the section was found and successfully removed. */\n readonly removed: boolean;\n /** Time taken to perform the removal, in milliseconds. */\n readonly elapsed_ms: number;\n}\n\n/**\n * Minimal client interface required by `runUnlearn`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n * Extends `PrefixResolver` so short kbid prefixes can be resolved\n * before each section is removed.\n */\nexport interface UnlearnClient extends PrefixResolver {\n /**\n * Removes a section from the knowledge base.\n *\n * @param kbid - identifier of the section to remove\n * @returns removal result with `removed` flag and elapsed time\n */\n removeSection(kbid: string): Promise<RemoveSectionResult>;\n}\n\n/** Result record produced for each kbid processed by the unlearn command. */\nexport interface UnlearnResult {\n /** Knowledge-base identifier that was targeted for removal. */\n kbid: string;\n /** `true` when the section was found and successfully removed. */\n removed: boolean;\n}\n\n/**\n * Removes the knowledge-base sections identified by `options.args`\n * via the provided client.\n *\n * Short kbid prefixes in `options.args` are resolved to full\n * identifiers before removal. Each kbid is processed independently.\n * If a kbid does not exist in the knowledge base, `removed` is set\n * to `false` rather than throwing.\n *\n * @param client - unlearn client to delegate removal to\n * @param options - parsed CLI options whose `args` list the kbids to\n * remove\n * @returns one `UnlearnResult` per kbid processed\n * @throws when a prefix matches no section or is ambiguous\n */\nexport async function runUnlearn(\n client: UnlearnClient,\n options: CliOptions,\n): Promise<UnlearnResult[]> {\n log('running unlearn', LogLevel.DEBUG);\n const results: UnlearnResult[] = [];\n for (const arg of options.args) {\n const kbid = await resolveKbidPrefix(arg, client);\n const result = await client.removeSection(kbid);\n results.push({ kbid, removed: result.removed });\n }\n return results;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { PrefixResolver } from './resolve-kbid-prefix.function.ts';\nimport { resolveKbidPrefix } from './resolve-kbid-prefix.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** Result returned by content composition. */\ninterface ContentResult {\n /** MIME type of the composed output, always `'text/markdown'`. */\n readonly type: 'text/markdown';\n /** The composed Markdown string. */\n readonly data: string;\n /** Character count of `data` (not byte count). */\n readonly total: number;\n}\n\n/**\n * Minimal client interface required by `runContent`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n * Extends `PrefixResolver` so short kbid prefixes can be resolved\n * before the content call is made.\n */\nexport interface ContentClient extends PrefixResolver {\n /**\n * Composes a rendered Markdown document from one or more kbid\n * or docid identifiers.\n *\n * @param ids - list of kbid or docid identifiers (may be mixed)\n * @returns composed Markdown result with character count\n */\n content(ids: string[]): Promise<ContentResult>;\n}\n\n/**\n * Composes and returns a rendered Markdown document from the\n * identifiers listed in `options.args`.\n *\n * Short kbid prefixes in `options.args` are resolved to full\n * identifiers before calling `client.content`. The caller is\n * responsible for writing the result to stdout.\n *\n * @param client - content client to delegate composition to\n * @param options - parsed CLI options whose `args` list the kbid or\n * docid identifiers to compose\n * @returns the composed content result from the daemon\n * @throws when a prefix matches no section or is ambiguous\n */\nexport async function runContent(\n client: ContentClient,\n options: CliOptions,\n): Promise<ContentResult> {\n log('running content', LogLevel.DEBUG);\n const resolved = await Promise.all(\n options.args.map((a) => resolveKbidPrefix(a, client)),\n );\n return client.content(resolved);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** A single integrity error found during a database check. */\ninterface IntegrityError {\n /**\n * The category of integrity violation detected.\n *\n * - `'checksum_mismatch'` -- stored content does not match its hash\n * - `'orphan_section'` -- section not referenced by any document\n * - `'orphan_document'` -- document references no existing sections\n * - `'broken_reference'` -- a marker references a non-existent entity\n * - `'type_mismatch'` -- stored MIME type conflicts with content\n * - `'circular_reference'` -- marker chain contains a cycle\n */\n readonly type:\n | 'checksum_mismatch'\n | 'orphan_section'\n | 'orphan_document'\n | 'broken_reference'\n | 'type_mismatch'\n | 'circular_reference';\n /** Identifier of the entity (kbid or docid) that has the issue. */\n readonly entity: string;\n /** Human-readable description of the specific problem. */\n readonly detail: string;\n}\n\n/**\n * A single entry in the divergent-content map.\n * Groups kbids under a common source key.\n */\ninterface DivergentContentEntry {\n /** Source key that has multiple divergent content versions. */\n readonly sourceKey: string;\n /** Kbids of sections sharing this source key but with different content. */\n readonly kbids: string[];\n}\n\n/**\n * Integrity check report returned by the daemon.\n */\ninterface IntegrityCheckResult {\n /** `true` when all checks passed and no errors were found. */\n readonly ok: boolean;\n /** All integrity errors found; empty when `ok` is `true`. */\n readonly errors: IntegrityError[];\n /** Total number of sections examined. */\n readonly sections_checked: number;\n /** Total number of documents examined. */\n readonly documents_checked: number;\n /** Total number of marker references checked. */\n readonly references_checked: number;\n /** Time taken to complete the check, in milliseconds. */\n readonly elapsed_ms: number;\n /**\n * Sections that share a source key but have divergent content.\n * Each entry groups the kbids under a common source key.\n * Empty when no divergent content is found.\n */\n readonly divergent_content: DivergentContentEntry[];\n}\n\n/** Raw daemon response from `integrityCheck`. */\ninterface RawIntegrityCheckResult {\n /** `true` when all checks passed and no errors were found. */\n readonly ok: boolean;\n /** All integrity errors found; empty when `ok` is `true`. */\n readonly errors: IntegrityError[];\n /** Total number of sections examined. */\n readonly sections_checked: number;\n /** Total number of documents examined. */\n readonly documents_checked: number;\n /** Total number of marker references checked. */\n readonly references_checked: number;\n /** Time taken to complete the check, in milliseconds. */\n readonly elapsed_ms: number;\n /**\n * Encoded divergent-content map.\n *\n * Format: `sk1:kbid1,kbid2;sk2:kbid3,kbid4`\n *\n * Each semicolon-separated segment is a source key followed by\n * a colon and a comma-separated list of kbids. Absent when no\n * divergent content exists.\n */\n readonly divergent_content?: string;\n}\n\n/**\n * Minimal client interface required by `runCheck`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface CheckClient {\n /**\n * Runs an integrity check on the knowledge-base database.\n *\n * @returns a report of all issues found; `ok` is `true` when\n * no errors were detected\n */\n integrityCheck(): Promise<RawIntegrityCheckResult>;\n}\n\n/**\n * Parses the encoded `divergent_content` string from the daemon\n * into a structured array.\n *\n * Input format: `sk1:kbid1,kbid2;sk2:kbid3,kbid4`\n *\n * @param encoded - raw encoded string, or empty / absent\n * @returns structured entries grouped by source key\n */\nfunction parseDivergentContent(\n encoded: string | undefined,\n): DivergentContentEntry[] {\n if (!encoded) return [];\n return encoded\n .split(';')\n .filter((segment) => segment.includes(':'))\n .map((segment) => {\n const colonIdx = segment.indexOf(':');\n const sourceKey = segment.slice(0, colonIdx);\n const kbids = segment\n .slice(colonIdx + 1)\n .split(',')\n .filter((k) => k.length > 0);\n return { sourceKey, kbids };\n })\n .filter((entry) => entry.kbids.length > 0);\n}\n\n/**\n * Runs an integrity check on the database and returns the report.\n *\n * Delegates to `client.integrityCheck()`, then parses the encoded\n * `divergent_content` field into structured form. The caller is\n * responsible for printing the result to stdout and setting the\n * process exit code based on `result.ok`.\n *\n * @param client - check client to delegate to\n * @param _options - parsed CLI options (unused; reserved for future flags)\n * @returns the integrity check report with parsed `divergent_content`\n */\nexport async function runCheck(\n client: CheckClient,\n _options: CliOptions,\n): Promise<IntegrityCheckResult> {\n log('running check', LogLevel.DEBUG);\n const raw = await client.integrityCheck();\n return {\n ok: raw.ok,\n errors: raw.errors,\n sections_checked: raw.sections_checked,\n documents_checked: raw.documents_checked,\n references_checked: raw.references_checked,\n elapsed_ms: raw.elapsed_ms,\n divergent_content: parseDivergentContent(raw.divergent_content),\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Garbage collection report returned by the daemon.\n */\ninterface GcResult {\n /** Number of unreferenced sections removed. */\n readonly removed_sections: number;\n /** Total bytes freed by removing unreferenced sections. */\n readonly removed_bytes: number;\n /** Time taken to complete garbage collection, in milliseconds. */\n readonly elapsed_ms: number;\n /**\n * Number of sections whose `source_path` file no longer\n * contains their heading text (advisory; not auto-removed).\n * Absent on older daemon versions.\n */\n readonly stale_sources?: number;\n}\n\n/**\n * Minimal client interface required by `runGc`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface GcClient {\n /**\n * Removes unreferenced sections from the database.\n *\n * @returns a report of sections removed and bytes freed\n */\n gc(): Promise<GcResult>;\n}\n\n/**\n * Runs garbage collection on the database and returns the report.\n *\n * Delegates to `client.gc()`. The caller is responsible for printing\n * the result to stdout.\n *\n * @param client - gc client to delegate to\n * @param _options - parsed CLI options (unused; reserved for future flags)\n * @returns the garbage collection report from the daemon\n */\nexport async function runGc(\n client: GcClient,\n _options: CliOptions,\n): Promise<GcResult> {\n log('running gc', LogLevel.DEBUG);\n return client.gc();\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Index rebuild report returned by the daemon.\n */\ninterface RebuildResult {\n /** Number of text and code sections that were re-indexed. */\n readonly sections_reindexed: number;\n /** Total number of unique terms written to the rebuilt indexes. */\n readonly terms_indexed: number;\n /** Time taken to complete the rebuild, in milliseconds. */\n readonly elapsed_ms: number;\n}\n\n/**\n * Minimal client interface required by `runRebuild`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface RebuildClient {\n /**\n * Reconstructs all index files from section files and document\n * manifests on disk. Text and code sections are re-tokenized;\n * image sections are skipped.\n *\n * @returns a report of sections and terms re-indexed\n */\n rebuildIndexes(): Promise<RebuildResult>;\n}\n\n/**\n * Rebuilds all database indexes and returns the report.\n *\n * Delegates to `client.rebuildIndexes()`. The caller is responsible\n * for printing the result to stdout.\n *\n * @param client - rebuild client to delegate to\n * @param _options - parsed CLI options (unused; reserved for future flags)\n * @returns the index rebuild report from the daemon\n */\nexport async function runRebuild(\n client: RebuildClient,\n _options: CliOptions,\n): Promise<RebuildResult> {\n log('running rebuild', LogLevel.DEBUG);\n return client.rebuildIndexes();\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\n\n/**\n * Locates the `.kbdb` database directory.\n *\n * When `dbPath` is provided, checks only that directory.\n * When omitted, walks up from the current working directory\n * until a `.kbdb` directory is found or the filesystem root\n * is reached.\n *\n * @param dbPath - explicit base directory; skips traversal\n * @returns absolute path to `.kbdb`, or `null` when not found\n */\nexport function findDb(dbPath?: string): string | null {\n if (dbPath) {\n const target = join(resolve(dbPath), '.kbdb');\n return existsSync(target) ? target : null;\n }\n let current = process.cwd();\n let parent = dirname(current);\n while (parent !== current) {\n const candidate = join(current, '.kbdb');\n if (existsSync(candidate)) return candidate;\n current = parent;\n parent = dirname(current);\n }\n const candidate = join(current, '.kbdb');\n return existsSync(candidate) ? candidate : null;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { installDefaultSkills } from './install-default-skills.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Result returned by `runInit` describing whether the directory was\n * successfully initialised.\n */\nexport interface InitResult {\n /** `true` when the database directory was created successfully. */\n readonly ok: boolean;\n /** Absolute path to the directory that was (or should have been) initialised. */\n readonly targetPath: string;\n /**\n * Human-readable error message when `ok` is `false`.\n * `undefined` when `ok` is `true`.\n */\n readonly errorMessage?: string;\n}\n\nconst DB_FORMAT_VERSION = 1;\n\nconst CATALOG_TOML = `version = ${DB_FORMAT_VERSION.toString()}\nsection_count = 0\ndocument_count = 0\ncreated_at = 0\nupdated_at = 0\nchecksum = \"\"\n`;\n\nconst WORKER_TOML = '# kbdb worker configuration\\n';\n\nconst GITIGNORE = [\n '# kbdb binary indexes (auto-generated)',\n 'corpus.bin',\n 'inverted.idx',\n 'positional.idx',\n '',\n].join('\\n');\n\n/**\n * Creates the `.kbdb` directory scaffold directly on disk.\n *\n * This mirrors the Rust `init_directory` in\n * `engine/crates/fs-database/src/scaffold.rs` and does not\n * require a running worker daemon.\n */\nfunction createScaffold(dbDir: string): void {\n mkdirSync(dbDir, { recursive: true });\n mkdirSync(join(dbDir, 'sections'));\n mkdirSync(join(dbDir, 'documents'));\n writeFileSync(join(dbDir, 'catalog.toml'), CATALOG_TOML);\n writeFileSync(join(dbDir, 'corpus.bin'), '');\n writeFileSync(join(dbDir, 'inverted.idx'), '');\n writeFileSync(join(dbDir, 'positional.idx'), '');\n writeFileSync(join(dbDir, 'worker.toml'), WORKER_TOML);\n writeFileSync(join(dbDir, '.gitignore'), GITIGNORE);\n}\n\n/**\n * Initialises a new `.kbdb` database directory.\n *\n * Creates the full scaffold directly on disk without requiring a\n * running worker daemon. Resolves the target path from\n * `options.dbPath` or `process.cwd()`.\n *\n * @param options - parsed CLI options supplying the optional `dbPath`\n * @returns init result indicating success or failure\n */\nexport function runInit(options: CliOptions): InitResult {\n log('running init', LogLevel.DEBUG);\n const basePath = options.dbPath\n ? resolve(options.dbPath)\n : process.cwd();\n const dbDir = join(basePath, '.kbdb');\n\n try {\n if (existsSync(dbDir)) {\n return {\n ok: false,\n targetPath: dbDir,\n errorMessage: `database directory already exists: ${dbDir}`,\n };\n }\n createScaffold(dbDir);\n installDefaultSkills(dbDir);\n return { ok: true, targetPath: dbDir };\n } catch (err: unknown) {\n const errorMessage =\n err instanceof Error ? err.message : String(err);\n return { ok: false, targetPath: dbDir, errorMessage };\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { createHash } from 'node:crypto';\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * RFC 4648 base32 alphabet (upper-case, no padding).\n * Used to encode the SHA-256-derived kbid bytes.\n */\nconst BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n\n/**\n * Encodes a byte array as a lowercase base32 string without padding.\n *\n * Mirrors the `data_encoding::BASE32_NOPAD` encoding used in the\n * Rust engine's `KbId::from_content`.\n *\n * @param bytes - raw bytes to encode\n * @returns lowercase base32-encoded string\n */\nfunction base32Encode(bytes: Uint8Array): string {\n let result = '';\n let bits = 0;\n let value = 0;\n for (const byte of bytes) {\n value = (value << 8) | byte;\n bits += 8;\n while (bits >= 5) {\n result += BASE32_ALPHABET[(value >>> (bits - 5)) & 0x1f];\n bits -= 5;\n }\n }\n if (bits > 0) {\n result += BASE32_ALPHABET[(value << (5 - bits)) & 0x1f];\n }\n return result.toLowerCase();\n}\n\n/**\n * Computes a 26-character kbid for a section using the same algorithm\n * as the Rust engine's `hash_section`.\n *\n * Algorithm:\n * 1. Build input: `\"section <mime> <byteLen>\\0<content>\"`\n * 2. SHA-256 hash the input\n * 3. Take the first 16 bytes\n * 4. Base32 encode (RFC 4648, no padding), lowercased \u2192 26 chars\n *\n * @param mimeType - MIME type string (e.g. `\"text/markdown\"`)\n * @param content - UTF-8 section content string\n * @returns 26-character lowercase base32 kbid\n */\nfunction computeSectionKbid(mimeType: string, content: string): string {\n const contentBytes = Buffer.from(content, 'utf-8');\n const header = `section ${mimeType} ${contentBytes.length.toString()}\\0`;\n const headerBytes = Buffer.from(header, 'utf-8');\n const input = Buffer.concat([headerBytes, contentBytes]);\n const hash = createHash('sha256').update(input).digest();\n const truncated = new Uint8Array(hash.buffer, 0, 16);\n return base32Encode(truncated);\n}\n\n/**\n * Escapes backslashes and double-quotes in a string for TOML inline\n * string values.\n *\n * Mirrors the `escape_toml_str` function in the Rust engine.\n *\n * @param s - string to escape\n * @returns escaped string safe for use inside TOML double-quoted strings\n */\nfunction escapeToml(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Serializes a skill section record to the `.section` file format.\n *\n * Format:\n * ```\n * kbid = \"...\"\n * section_type = \"text/markdown\"\n * type_name = \"skill\"\n * title = \"...\"\n * description = \"...\"\n * size = 0\n * token_count = 0\n * heading_token_count = 0\n * body_token_count = 0\n * code_token_count = 0\n * created_at = 0\n * checksum = \"...\"\n *\n * ---\n * <json content>\n * ```\n *\n * @param kbid - 26-char content-addressed identifier\n * @param title - skill name used as section title\n * @param description - human-readable description\n * @param content - serialised JSON skill definition\n * @returns file content string\n */\nfunction serializeSkillSection(\n kbid: string,\n title: string,\n description: string,\n content: string,\n): string {\n const size = Buffer.byteLength(content, 'utf-8');\n const header = [\n `kbid = \"${escapeToml(kbid)}\"`,\n `section_type = \"text/markdown\"`,\n `type_name = \"skill\"`,\n `title = \"${escapeToml(title)}\"`,\n `description = \"${escapeToml(description)}\"`,\n `size = ${size.toString()}`,\n `token_count = 0`,\n `heading_token_count = 0`,\n `body_token_count = 0`,\n `code_token_count = 0`,\n `created_at = 0`,\n `checksum = \"${escapeToml(kbid)}\"`,\n '',\n ].join('\\n');\n return `${header}\\n---\\n${content}`;\n}\n\n/** Descriptor for a skill to install. */\ninterface SkillDescriptor {\n /** Unique skill name (kebab-case). */\n readonly name: string;\n /** Human-readable description. */\n readonly description: string;\n /** Template body text. */\n readonly body: string;\n}\n\n/**\n * Installs a single skill section file under `sectionsDir`.\n *\n * Creates the shard subdirectory if it does not exist. Skips\n * writing if the section file already exists, preserving any\n * user modifications.\n *\n * @param sectionsDir - absolute path to `.kbdb/sections`\n * @param skill - skill definition to serialise and store\n */\nfunction installSkill(\n sectionsDir: string,\n skill: SkillDescriptor,\n): void {\n const content = JSON.stringify({\n name: skill.name,\n description: skill.description,\n arguments: [],\n body: skill.body,\n });\n const kbid = computeSectionKbid('text/markdown', content);\n const prefix = kbid.slice(0, 2);\n const shardDir = join(sectionsDir, prefix);\n const filePath = join(shardDir, `${kbid}.section`);\n\n if (existsSync(filePath)) {\n return;\n }\n\n mkdirSync(shardDir, { recursive: true });\n\n const fileContent = serializeSkillSection(\n kbid,\n skill.name,\n skill.description,\n content,\n );\n writeFileSync(filePath, fileContent, 'utf-8');\n}\n\n/**\n * Body text for the `query-guidance` default skill.\n *\n * Teaches AI agents how to effectively search the knowledge base\n * using lexical BM25F queries.\n */\nconst QUERY_GUIDANCE_BODY =\n 'This knowledge base uses lexical search (stemmed BM25F), not' +\n ' semantic/vector search. Follow these guidelines for effective' +\n ' retrieval:\\n\\n' +\n '1. Issue MULTIPLE short keyword queries rather than one long' +\n ' natural-language question. Each query should target 2-3' +\n ' specific terms.\\n\\n' +\n '2. EXPAND SYNONYMS yourself. \"login\" will not match \"sign-in\"' +\n ' unless both terms appear in the content. Try alternative' +\n ' phrasings: search for \"login\", then \"sign-in\", then' +\n ' \"authentication\".\\n\\n' +\n '3. USE BOOLEAN AND PHRASE SYNTAX:\\n' +\n ' - Exact phrases: \"error handling\"\\n' +\n ' - Boolean AND: auth AND token\\n' +\n ' - Boolean OR: cache OR redis\\n' +\n ' - Exclusion: auth -oauth\\n\\n' +\n '4. LEAN ON HEADINGS. Headings carry 2x weight in ranking.' +\n ' Search for terms that are likely in section titles.\\n\\n' +\n '5. STEMMING IS AUTOMATIC. \"connections\" matches \"connect\",' +\n ' \"running\" matches \"run\". You do not need to try inflected' +\n ' forms.\\n\\n' +\n '6. USE RECALL AFTER SEARCH. After finding relevant sections' +\n ' with search, use recall with increasing depth (0-3) to' +\n ' progressively expand context: depth 0 = full content, depth' +\n ' 1 = parent documents + back-references, depth 2 = siblings' +\n ' + forward references, depth 3 = referenced sections.\\n\\n' +\n '7. CODE IDENTIFIERS ARE SPLIT. camelCase and snake_case names' +\n ' are decomposed: getUserById becomes searchable as \"get\",' +\n ' \"user\", \"by\", \"id\".\\n\\n' +\n '8. PAGINATION. Default limit is 20 results. Use offset for' +\n ' additional pages if total > limit.';\n\n/**\n * Body text for the `memory-protocol` default skill.\n *\n * Teaches AI agents when and what to store in the knowledge base\n * to keep it accurate and useful.\n */\nconst MEMORY_PROTOCOL_BODY =\n 'Follow these guidelines to keep the knowledge base accurate' +\n ' and useful:\\n\\n' +\n '1. STORE DURABLE FACTS: decisions, architecture choices,' +\n ' configuration values, corrections to prior knowledge, API' +\n ' contracts, and resolved incidents. These are the facts that' +\n ' matter weeks later.\\n\\n' +\n '2. DO NOT STORE: transient conversation context, debugging' +\n ' output, ephemeral task state, raw log dumps, or information' +\n ' that changes every session. The brain should contain' +\n ' knowledge, not activity logs.\\n\\n' +\n '3. SEARCH BEFORE STORING. Always search the knowledge base' +\n ' before adding new content. If a section already covers the' +\n ' topic, use learn with --replace to update it rather than' +\n ' creating a duplicate.\\n\\n' +\n '4. USE --replace FOR CORRECTIONS. When a fact changes (e.g.,' +\n ' rate limit updated from 100 to 200 req/min), re-learn the' +\n ' corrected content with --replace so the old version is' +\n ' superseded. Without --replace, both the old and new versions' +\n ' coexist with equal ranking.\\n\\n' +\n '5. ATTACH TAGS for scoping. Use tags like project name,' +\n ' domain, or topic (e.g., --tags auth,api,v2) so queries can' +\n ' be filtered by scope later.\\n\\n' +\n '6. PREFER RECENT RESULTS. When search returns multiple' +\n ' sections covering the same topic, prefer the one with the' +\n ' most recent created_at timestamp -- it is more likely to' +\n ' reflect the current state.\\n\\n' +\n '7. USE RECALL AFTER SEARCH. After finding relevant sections,' +\n ' use recall with increasing depth (0-3) to expand context' +\n ' progressively before making decisions.\\n\\n' +\n '8. INCLUDE HEADINGS. Always provide a descriptive title when' +\n ' storing content. Headings carry 2x ranking weight -- omitting' +\n ' them significantly reduces searchability.';\n\n/**\n * Default skills installed on every fresh `kbdb db init`.\n *\n * These provide baseline guidance that improves AI agent\n * effectiveness out of the box. They are regular skill sections\n * and can be deleted by users.\n */\nconst DEFAULT_SKILLS: readonly SkillDescriptor[] = [\n {\n name: 'query-guidance',\n description:\n 'How to effectively search this knowledge base.' +\n ' Read this before issuing search queries.',\n body: QUERY_GUIDANCE_BODY,\n },\n {\n name: 'memory-protocol',\n description:\n 'Guidelines for what to store in this knowledge base' +\n ' and when. Read this before using the learn tool.',\n body: MEMORY_PROTOCOL_BODY,\n },\n];\n\n/**\n * Writes the two default skills (`query-guidance` and\n * `memory-protocol`) as section files directly into the `.kbdb`\n * directory scaffold.\n *\n * Called by `runInit` after the directory scaffold is created.\n * Does not require a running worker daemon. Skips any skill whose\n * section file already exists so user modifications are preserved.\n *\n * @param dbDir - absolute path to the `.kbdb` directory\n */\nexport function installDefaultSkills(dbDir: string): void {\n const sectionsDir = join(dbDir, 'sections');\n for (const skill of DEFAULT_SKILLS) {\n installSkill(sectionsDir, skill);\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Converts an unknown thrown value to a human-readable message.\n *\n * @param err - the caught value\n * @returns the error message string\n */\nexport function errorToMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Returns `true` when stdin is an interactive terminal.\n *\n * @param stdin - readable stream to check (defaults to\n * `process.stdin`)\n */\nexport function isStdinTty(\n stdin: NodeJS.ReadStream = process.stdin,\n): boolean {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- isTTY is undefined at runtime for non-TTY despite Node types saying boolean\n return stdin.isTTY ?? false;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { createInterface } from 'node:readline';\n\n/** Injectable I/O for testing without real stdin. */\nexport interface PromptIO {\n ask: (question: string) => Promise<string>;\n}\n\n/**\n * Prompts the user on stdin (TTY only) and returns the\n * trimmed reply.\n *\n * @param question - the prompt text to display\n * @param io - injectable I/O (defaults to readline on\n * process.stdin/stdout)\n */\nexport async function promptUser(\n question: string,\n io?: PromptIO,\n): Promise<string> {\n const ask = io?.ask ?? askReadline;\n const answer = await ask(question);\n return answer.trim();\n}\n\nfunction askReadline(question: string): Promise<string> {\n return new Promise<string>((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer);\n });\n });\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runStatus`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface StatusClient {\n dbStatus(): Promise<unknown>;\n}\n\n/**\n * Retrieves the database status and returns the summary report.\n *\n * Delegates to `client.dbStatus()`. The caller is responsible\n * for serialising the result and setting the process exit code.\n *\n * @param client - status client to delegate to\n * @param _options - parsed CLI options (unused; reserved for\n * future flags)\n * @returns the status report from the daemon\n */\nexport async function runStatus(\n client: StatusClient,\n _options: CliOptions,\n): Promise<unknown> {\n log('running status', LogLevel.DEBUG);\n return client.dbStatus();\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { InitResult } from './run-init.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Callable signature for the init operation injected into\n * `runDbInit`.\n */\nexport type RunInitFn = (options: CliOptions) => InitResult;\n\n/**\n * Executes the `db init` compound command by delegating to the\n * provided `runInit` function and mapping the result to a\n * `CommandResult`.\n *\n * Accepts `runInit` as an injectable parameter so the function\n * can be tested without touching the filesystem.\n *\n * @param options - parsed CLI options (forwarded to `runInitFn`)\n * @param runInitFn - function that performs the actual\n * initialisation\n * @returns a `CommandResult` with JSON output on success or an\n * error message on failure\n */\nexport function runDbInit(\n options: CliOptions,\n runInitFn: RunInitFn,\n): CommandResult {\n log('running db-init', LogLevel.DEBUG);\n const result = runInitFn(options);\n if (result.ok) {\n return {\n output: JSON.stringify(\n { path: result.targetPath, created: true },\n null,\n 2,\n ),\n exitCode: 0,\n };\n }\n return {\n error: result.errorMessage ?? 'init failed',\n exitCode: 1,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { MigrateResult } from '../../worker-client/typings/migrate-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runDbMigrate`.\n *\n * Intentionally narrower than `MigrateClient` from\n * `run-migrate.function.ts` \u2014 this variant skips the version\n * check and unconditionally runs migrations. Callers that need\n * version-aware migration should use `runMigrate` instead.\n */\nexport interface DbMigrateClient {\n /**\n * Runs all pending database migrations.\n *\n * @param targetPath - absolute path to the `.kbdb` database root\n */\n migrateDatabase(targetPath: string): Promise<MigrateResult>;\n}\n\n/**\n * Runs database migrations unconditionally via `client.migrateDatabase`.\n *\n * Resolves the target path from `options.dbPath` when provided,\n * falling back to `process.cwd()`. Does not perform a version\n * compatibility check before migrating \u2014 use `runMigrate` for\n * version-aware migration flows.\n *\n * @param client - database migration client to delegate to\n * @param options - parsed CLI options supplying the optional\n * `dbPath`\n * @returns the migration report returned by the daemon\n */\nexport async function runDbMigrate(\n client: DbMigrateClient,\n options: CliOptions,\n): Promise<MigrateResult> {\n log('running db-migrate', LogLevel.DEBUG);\n const dbPath = options.dbPath ?? process.cwd();\n return client.migrateDatabase(dbPath);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { SkillArgument } from '../typings/skill-types.interface.ts';\n\n/**\n * Extracts `{{argName}}` placeholder names from a skill body string\n * and returns them as `SkillArgument` objects marked as required.\n *\n * Each placeholder is included only once regardless of how many\n * times it appears, and the returned array preserves the order of\n * first occurrence.\n *\n * @param body - skill body template text to scan for placeholders\n * @returns ordered, deduplicated list of argument definitions\n */\nexport function extractSkillArguments(body: string): SkillArgument[] {\n const seen = new Set<string>();\n const args: SkillArgument[] = [];\n const re = /\\{\\{(\\w+)\\}\\}/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(body)) !== null) {\n const name = match[1];\n if (!seen.has(name)) {\n seen.add(name);\n args.push({ name, required: true });\n }\n }\n return args;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { SkillDefinition } from '../typings/skill-types.interface.ts';\n\n/**\n * Serializes a `SkillDefinition` to a JSON string suitable for\n * storage as a knowledge-base section's `content` field.\n *\n * @param skill - skill definition to serialize\n * @returns JSON string representation of the skill\n */\nexport function serializeSkillContent(skill: SkillDefinition): string {\n return JSON.stringify(skill);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { AddSectionResult } from '../../worker-client/typings/add-section-result.model.ts';\nimport { extractSkillArguments } from '../../mcp/functions/extract-skill-arguments.function.ts';\nimport { serializeSkillContent } from '../../mcp/functions/serialize-skill-content.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runSkillLearn`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface SkillLearnClient {\n /**\n * Stores a skill section in the knowledge base.\n *\n * @param params - section type, serialized JSON content,\n * and optional title and description\n * @returns result containing the assigned kbid\n */\n addSection(params: {\n readonly sectionType: string;\n readonly content: string;\n readonly title?: string;\n readonly description?: string;\n }): Promise<AddSectionResult>;\n}\n\n/**\n * Creates or updates a skill definition in the knowledge base.\n *\n * Validates that `--name` and `--body` are provided, extracts\n * `{{argName}}` placeholders from the body, serializes the skill\n * to JSON, and stores it as a `'skill'` section.\n *\n * @param client - client used to store the skill section\n * @param options - parsed CLI options with `name` and `body` fields\n * @returns a `CommandResult` with the stored section info or an error\n */\nexport async function runSkillLearn(\n client: SkillLearnClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running skill-learn', LogLevel.DEBUG);\n const name = options.name;\n if (!name) {\n return { error: '--name is required', exitCode: 1 };\n }\n const body = options.body;\n if (!body) {\n return { error: '--body is required', exitCode: 1 };\n }\n const args = extractSkillArguments(body);\n const skill = {\n name,\n description: options.description,\n arguments: args.length > 0 ? args : undefined,\n body,\n };\n const json = serializeSkillContent(skill);\n const result = await client.addSection({\n sectionType: 'skill',\n content: json,\n title: name,\n description: options.description,\n });\n return {\n output: JSON.stringify(result, null, 2),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * A single row returned by `listByType` for the skill client.\n */\ninterface SkillRecord {\n /** Knowledge-base identifier for the skill section. */\n kbid: string;\n /** Skill name stored as the section title. */\n title: string | null;\n /** Optional skill description stored on the section. */\n description: string | null;\n /** Serialized `SkillDefinition` JSON stored as section content. */\n content: string;\n}\n\n/**\n * Minimal client interface required by `runSkillList`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface SkillListClient {\n /**\n * Retrieves all sections stored with the given type name.\n *\n * @param sectionType - the type name to filter by\n * @returns matching section rows\n */\n listByType(sectionType: string): Promise<SkillRecord[]>;\n}\n\n/**\n * Lists all skill definitions stored in the knowledge base.\n *\n * Calls `client.listByType('skill')` and maps each record to a\n * summary that includes the argument count parsed from the JSON\n * content. Parse errors default the argument count to `0`.\n *\n * @param client - client used to list skill sections\n * @param _options - parsed CLI options (unused; reserved for future flags)\n * @returns a `CommandResult` containing a JSON array of skill summaries\n */\nexport async function runSkillList(\n client: SkillListClient,\n _options: CliOptions,\n): Promise<CommandResult> {\n log('running skill-list', LogLevel.DEBUG);\n const records = await client.listByType('skill');\n const items = records.map((r) => {\n let argumentCount = 0;\n try {\n const parsed = JSON.parse(r.content) as Record<\n string,\n unknown\n >;\n if (Array.isArray(parsed['arguments'])) {\n argumentCount = parsed['arguments'].length;\n }\n } catch {\n // ignore parse errors\n }\n return {\n kbid: r.kbid,\n name: r.title,\n description: r.description,\n argumentCount,\n };\n });\n return {\n output: JSON.stringify(items, null, 2),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport type {\n SkillArgument,\n SkillDefinition,\n} from '../typings/skill-types.interface.ts';\n\n/**\n * Parses a JSON string into a `SkillDefinition`.\n *\n * Validates that the required `name` and `body` fields are present\n * and are non-empty strings, then returns the full definition\n * including optional `description` and `arguments`.\n *\n * @param json - JSON string representing a serialized skill\n * @returns the parsed skill definition\n * @throws {SyntaxError} when `json` is not valid JSON\n * @throws {Error} when `name` is missing or empty\n * @throws {Error} when `body` is missing or not a string\n */\nexport function parseSkillContent(json: string): SkillDefinition {\n const raw = JSON.parse(json) as Record<string, unknown>;\n if (typeof raw['name'] !== 'string' || !raw['name']) {\n log('skill name is required', LogLevel.ERROR);\n throw new Error('skill name is required');\n }\n if (typeof raw['body'] !== 'string') {\n log('skill body is required', LogLevel.ERROR);\n throw new Error('skill body is required');\n }\n return {\n name: raw['name'],\n description:\n typeof raw['description'] === 'string'\n ? raw['description']\n : undefined,\n arguments: Array.isArray(raw['arguments'])\n ? (raw['arguments'] as SkillArgument[])\n : undefined,\n body: raw['body'],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { parseSkillContent } from '../../mcp/functions/parse-skill-content.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runSkillGet`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface SkillGetClient {\n /**\n * Retrieves one or more sections by their knowledge-base IDs.\n *\n * @param kbids - list of knowledge-base identifiers to fetch\n * @returns matching section rows\n */\n readSections(\n kbids: string[],\n ): Promise<{ kbid: string; content: string }[]>;\n\n /**\n * Retrieves all sections stored with the given type name.\n *\n * @param sectionType - the type name to filter by\n * @returns matching section rows\n */\n listByType(\n sectionType: string,\n ): Promise<\n { kbid: string; title: string | null; content: string }[]\n >;\n}\n\n/**\n * Retrieves a skill definition by name or kbid.\n *\n * Accepts the identifier as the first positional argument or as\n * `options.name`. When the identifier looks like a hex hash\n * (16 or more hex characters) it is tried as a kbid first; if\n * no section is found it falls back to a name lookup. When the\n * identifier is not hex-like it goes directly to name lookup.\n * For name lookups the most recently stored match (last in the\n * array) is returned.\n *\n * @param client - client used to look up the skill section\n * @param options - parsed CLI options; first positional arg or `name`\n * is used as the identifier\n * @returns a `CommandResult` containing the serialized\n * `SkillDefinition` JSON or an error message\n */\nexport async function runSkillGet(\n client: SkillGetClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running skill-get', LogLevel.DEBUG);\n const identifier = options.args[0] ?? options.name;\n if (!identifier) {\n return {\n error: 'skill name or kbid required',\n exitCode: 1,\n };\n }\n let content: string | undefined;\n // Try as kbid first when it looks like a hex hash.\n if (/^[0-9a-f]{16,}$/i.test(identifier)) {\n const sections = await client.readSections([identifier]);\n if (sections.length > 0) {\n content = sections[0]?.content;\n }\n }\n // If not found by kbid, try by name.\n if (content === undefined) {\n const records = await client.listByType('skill');\n const match = records.filter((r) => r.title === identifier).pop();\n if (match) {\n content = match.content;\n }\n }\n if (content === undefined) {\n return {\n error: `skill not found: ${identifier}`,\n exitCode: 1,\n };\n }\n const skill = parseSkillContent(content);\n return {\n output: JSON.stringify(skill, null, 2),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runSkillDelete`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface SkillDeleteClient {\n /**\n * Removes a section from the knowledge base.\n *\n * @param kbid - knowledge-base identifier of the section to remove\n * @returns result indicating whether the section was found and removed\n */\n removeSection(kbid: string): Promise<{ removed: boolean }>;\n}\n\n/**\n * Deletes a skill section from the knowledge base by its kbid.\n *\n * The kbid must be supplied as the first positional argument. Returns\n * an error result if it is missing.\n *\n * @param client - client used to remove the skill section\n * @param options - parsed CLI options; `args[0]` is the kbid\n * @returns a `CommandResult` with the kbid and removal status\n */\nexport async function runSkillDelete(\n client: SkillDeleteClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running skill-delete', LogLevel.DEBUG);\n const kbid = options.args[0];\n if (!kbid) {\n return { error: 'kbid is required', exitCode: 1 };\n }\n const result = await client.removeSection(kbid);\n return {\n output: JSON.stringify(\n { kbid, removed: result.removed },\n null,\n 2,\n ),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { AddSectionResult } from '../../worker-client/typings/add-section-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runAgentCreate`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface AgentCreateClient {\n /**\n * Ingests a content section into the knowledge base.\n *\n * @param params - section type label, raw content, and optional\n * metadata\n * @returns result object containing the assigned knowledge-base\n * identifier\n */\n addSection(params: {\n readonly sectionType: string;\n readonly content: string;\n readonly title?: string;\n readonly description?: string;\n }): Promise<AddSectionResult>;\n\n /**\n * Groups a set of sections under a named document.\n *\n * @param title - human-readable document title\n * @param kbids - identifiers of the sections to group\n * @param docType - application-level document type tag; omit or\n * pass an empty string for untagged documents\n * @returns the assigned document identifier\n */\n groupSections(\n title: string,\n kbids: string[],\n docType?: string,\n ): Promise<string>;\n\n /**\n * Retrieves one or more sections by their identifiers.\n *\n * @param kbids - list of knowledge-base identifiers to fetch\n * @returns sections found; missing kbids are omitted from the result\n */\n readSections(kbids: string[]): Promise<{ kbid: string }[]>;\n}\n\n/**\n * Creates a new agent in the knowledge base.\n *\n * Validates `--name` and `--persona` options, verifies that all\n * referenced skill kbids exist, stores agent metadata as a JSON\n * section, and groups all sections under a single document.\n *\n * @param client - agent create client to delegate operations to\n * @param options - parsed CLI options providing `name`, `persona`,\n * optional `description`, and optional `skills` kbid list\n * @returns a `CommandResult` with serialised creation info or an\n * error message and a non-zero exit code\n */\nexport async function runAgentCreate(\n client: AgentCreateClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running agent-create', LogLevel.DEBUG);\n const name = options.name;\n if (!name) {\n return { error: '--name is required', exitCode: 1 };\n }\n const persona = options.persona;\n if (!persona) {\n return { error: '--persona is required', exitCode: 1 };\n }\n const skills = options.skills ?? [];\n\n if (skills.length > 0) {\n const sections = await client.readSections(skills);\n const found = new Set(sections.map((s) => s.kbid));\n const missing = skills.filter((k) => !found.has(k));\n if (missing.length > 0) {\n return {\n error: `skill not found: ${missing.join(', ')}`,\n exitCode: 1,\n };\n }\n }\n\n const metadata = JSON.stringify({\n name,\n description: options.description ?? '',\n persona,\n });\n\n const metaResult = await client.addSection({\n sectionType: 'text',\n content: metadata,\n title: name,\n description: options.description,\n });\n\n const allKbids = [metaResult.kbid, ...skills];\n const docid = await client.groupSections(name, allKbids, 'agent');\n\n return {\n output: JSON.stringify(\n { docid, name, skillCount: skills.length },\n null,\n 2,\n ),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** A document summary as returned by `listDocumentsByType`. */\ninterface DocumentSummary {\n /** Unique document identifier. */\n readonly docid: string;\n /** Human-readable document title used as the agent name. */\n readonly title: string;\n /** Ordered list of section references for this document. */\n readonly sections: readonly { kbid: string; position: number }[];\n}\n\n/**\n * Minimal client interface required by `runAgentList`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface AgentListClient {\n /**\n * Retrieves all documents whose type name matches the given string.\n *\n * @param docType - the application-level document type to filter by\n * @returns all document summaries with a matching type name\n */\n listDocumentsByType(docType: string): Promise<DocumentSummary[]>;\n}\n\n/**\n * Lists all agents stored in the knowledge base.\n *\n * Retrieves all documents with `doc_type: 'agent'` and returns a\n * summary list. The `skillCount` for each agent is\n * `Math.max(0, sections.length - 1)` because the first section\n * always holds the agent's metadata JSON rather than a skill\n * reference.\n *\n * @param client - agent list client to delegate retrieval to\n * @param _options - parsed CLI options (unused; reserved for future\n * filtering flags)\n * @returns a `CommandResult` with serialised agent summary list\n */\nexport async function runAgentList(\n client: AgentListClient,\n _options: CliOptions,\n): Promise<CommandResult> {\n log('running agent-list', LogLevel.DEBUG);\n const docs = await client.listDocumentsByType('agent');\n const items = docs.map((d) => ({\n docid: d.docid,\n name: d.title,\n skillCount: Math.max(0, d.sections.length - 1),\n }));\n return {\n output: JSON.stringify(items, null, 2),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** A document section reference as returned by `retrieveDocument`. */\ninterface DocumentSection {\n /** Knowledge-base identifier of the section. */\n readonly kbid: string;\n /** Zero-based position of the section within the document. */\n readonly position: number;\n}\n\n/** A document record as returned by `retrieveDocument`. */\ninterface AgentDocument {\n /** Unique document identifier. */\n readonly docid: string;\n /** Human-readable document title used as agent name fallback. */\n readonly title: string;\n /** Ordered list of section references. */\n readonly sections: DocumentSection[];\n}\n\n/** A section record as returned by `readSections`. */\ninterface SectionRecord {\n /** Knowledge-base identifier of the section. */\n readonly kbid: string;\n /** Raw text content stored in the section. */\n readonly content: string;\n}\n\n/**\n * Minimal client interface required by `runAgentGet`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface AgentGetClient {\n /**\n * Retrieves a full document record including its ordered sections.\n *\n * @param docid - identifier of the document to retrieve\n * @returns the document record\n */\n retrieveDocument(docid: string): Promise<unknown>;\n\n /**\n * Retrieves one or more sections by their identifiers.\n *\n * @param kbids - list of knowledge-base identifiers to fetch\n * @returns sections found; missing kbids are omitted from the result\n */\n readSections(kbids: string[]): Promise<SectionRecord[]>;\n}\n\n/**\n * Reads agent metadata from the first section's JSON content.\n * Falls back to `fallbackName` when the section is absent or the\n * content cannot be parsed.\n */\nasync function readAgentMeta(\n client: AgentGetClient,\n metaKbid: string,\n fallbackName: string,\n): Promise<{ name: string; description: string; persona: string }> {\n const sections = await client.readSections([metaKbid]);\n const first = sections.at(0);\n if (!first) {\n return { name: fallbackName, description: '', persona: '' };\n }\n try {\n const meta = JSON.parse(first.content) as Record<string, unknown>;\n return {\n name:\n typeof meta['name'] === 'string'\n ? meta['name']\n : fallbackName,\n description:\n typeof meta['description'] === 'string'\n ? meta['description']\n : '',\n persona:\n typeof meta['persona'] === 'string' ? meta['persona'] : '',\n };\n } catch {\n return { name: fallbackName, description: '', persona: '' };\n }\n}\n\n/**\n * Resolves skill names by reading each skill section's JSON content.\n * Returns `null` for any reference whose section no longer exists\n * (dangling reference).\n */\nasync function resolveSkills(\n client: AgentGetClient,\n skillRefs: DocumentSection[],\n): Promise<{ kbid: string; name: string | null; position: number }[]> {\n if (skillRefs.length === 0) {\n return [];\n }\n const kbids = skillRefs.map((r) => r.kbid);\n const sections = await client.readSections(kbids);\n const sectionMap = new Map(sections.map((s) => [s.kbid, s]));\n return skillRefs.map((ref) => {\n const sec = sectionMap.get(ref.kbid);\n if (!sec) {\n return { kbid: ref.kbid, name: null, position: ref.position };\n }\n try {\n const parsed = JSON.parse(sec.content) as Record<\n string,\n unknown\n >;\n const skillName =\n typeof parsed['name'] === 'string' ? parsed['name'] : null;\n return {\n kbid: ref.kbid,\n name: skillName,\n position: ref.position,\n };\n } catch {\n return { kbid: ref.kbid, name: null, position: ref.position };\n }\n });\n}\n\n/**\n * Retrieves a full agent definition from the knowledge base.\n *\n * Reads the agent document identified by `options.args[0]`, extracts\n * metadata (name, description, persona) from the first section, and\n * resolves skill names from the remaining sections. Dangling skill\n * references appear with `name: null`.\n *\n * @param client - agent get client to delegate retrieval to\n * @param options - parsed CLI options; `args[0]` must be the docid\n * @returns a `CommandResult` with serialised agent definition or an\n * error message and a non-zero exit code\n */\nexport async function runAgentGet(\n client: AgentGetClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running agent-get', LogLevel.DEBUG);\n const docid = options.args[0];\n if (!docid) {\n return { error: 'docid is required', exitCode: 1 };\n }\n\n const doc = (await client.retrieveDocument(docid)) as AgentDocument;\n const metaKbid = doc.sections[0]?.kbid;\n const skillRefs = doc.sections.slice(1);\n\n const { name, description, persona } = metaKbid\n ? await readAgentMeta(client, metaKbid, doc.title)\n : { name: doc.title, description: '', persona: '' };\n\n const skills = await resolveSkills(client, skillRefs);\n\n return {\n output: JSON.stringify(\n { docid, name, description, persona, skills },\n null,\n 2,\n ),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runAgentDelete`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface AgentDeleteClient {\n /**\n * Removes the document grouping for the given document.\n *\n * The sections themselves are not deleted; only the grouping\n * record is removed.\n *\n * @param docid - identifier of the document grouping to remove\n */\n removeGrouping(docid: string): Promise<void>;\n}\n\n/**\n * Deletes an agent from the knowledge base.\n *\n * Removes the document grouping identified by `options.args[0]`.\n * Skill sections referenced by the agent are not deleted; only\n * the grouping record is removed.\n *\n * @param client - agent delete client to delegate removal to\n * @param options - parsed CLI options; `args[0]` must be the docid\n * @returns a `CommandResult` confirming removal or an error message\n * with a non-zero exit code\n */\nexport async function runAgentDelete(\n client: AgentDeleteClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running agent-delete', LogLevel.DEBUG);\n const docid = options.args[0];\n if (!docid) {\n return { error: 'docid is required', exitCode: 1 };\n }\n await client.removeGrouping(docid);\n return {\n output: JSON.stringify({ docid, removed: true }, null, 2),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { resolve } from 'node:path';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { ImportResult } from '../../worker-client/typings/import-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runImport`.\n */\nexport interface ImportClient {\n /**\n * Imports an exported database from the given directory.\n *\n * @param params - source path and dry-run flag\n * @returns import report with counts and timing\n */\n import(params: {\n from: string;\n dryRun: boolean;\n }): Promise<ImportResult>;\n}\n\n/**\n * Imports an exported knowledge-base from the path specified by\n * `--from`, delegating to the worker client.\n *\n * The path is resolved against the current working directory so\n * that the daemon -- which may run with a different working\n * directory -- always receives an absolute path.\n *\n * @param client - import client to delegate to\n * @param options - parsed CLI options with `from` path\n * @returns the import result with section/document counts\n * @throws when `--from` is not provided\n */\nexport async function runImport(\n client: ImportClient,\n options: CliOptions,\n): Promise<ImportResult> {\n const from = options.from;\n if (!from) {\n const msg = 'import requires --from <path>';\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n return client.import({\n from: resolve(process.cwd(), from),\n dryRun: options.dryRun === true,\n });\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\nimport type { ContentClient } from './run-content.function.ts';\n\n/**\n * Hydrates each result's `preview` field with the actual section\n * content fetched from the client.\n *\n * Failures for individual results are caught and suppressed so that\n * one unavailable section does not prevent other previews from\n * being returned.\n *\n * @param client - content client used to fetch section text\n * @param paged - mutable search display records to hydrate\n */\nexport async function hydrateSearchPreviews(\n client: ContentClient,\n paged: PagedSearchDisplay,\n): Promise<void> {\n await Promise.all(\n paged.items.map(async (result) => {\n try {\n const contentResult = await client.content([result.kbid]);\n result.preview = contentResult.data;\n } catch {\n // Leave preview as empty string on failure.\n }\n }),\n );\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { DispatchClient } from '../typings/dispatch-client.type.ts';\nimport type { LearnIO } from './run-learn.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { runSearch } from './run-search.function.ts';\nimport { runLearn } from './run-learn.function.ts';\nimport { runUnlearn } from './run-unlearn.function.ts';\nimport { runContent } from './run-content.function.ts';\nimport { runCheck } from './run-check.function.ts';\nimport { runGc } from './run-gc.function.ts';\nimport { runRebuild } from './run-rebuild.function.ts';\nimport { runStatus } from './run-status.function.ts';\nimport { runDbInit } from './run-db-init.function.ts';\nimport { runInit } from './run-init.function.ts';\nimport { runDbMigrate } from './run-db-migrate.function.ts';\nimport { runSkillLearn } from './run-skill-learn.function.ts';\nimport { runSkillList } from './run-skill-list.function.ts';\nimport { runSkillGet } from './run-skill-get.function.ts';\nimport { runSkillDelete } from './run-skill-delete.function.ts';\nimport { runAgentCreate } from './run-agent-create.function.ts';\nimport { runAgentList } from './run-agent-list.function.ts';\nimport { runAgentGet } from './run-agent-get.function.ts';\nimport { runAgentDelete } from './run-agent-delete.function.ts';\nimport { runRecall } from './run-recall.function.ts';\nimport { runExport } from './run-export.function.ts';\nimport { runImport } from './run-import.function.ts';\nimport { formatOutput } from './format-output.function.ts';\nimport { formatCommandOutput } from './format-command-output.function.ts';\nimport { errorToMessage } from './error-to-message.function.ts';\nimport { hydrateSearchPreviews } from './hydrate-search-previews.function.ts';\n\nexport type { DispatchClient } from '../typings/dispatch-client.type.ts';\n\n/**\n * Routes a parsed CLI command to the appropriate handler and\n * returns a `CommandResult` without touching process globals.\n *\n * @param client - worker client covering all data commands\n * @param options - parsed CLI options with command and args\n * @param io - optional injectable I/O for learn stdin\n */\nexport async function dispatchCommand(\n client: DispatchClient,\n options: CliOptions,\n io?: LearnIO,\n): Promise<CommandResult> {\n log('dispatching command: ' + options.command, LogLevel.DEBUG);\n switch (options.command) {\n case 'learn':\n return handleLearn(client, options, io);\n case 'unlearn':\n return handleUnlearn(client, options);\n case 'search':\n return handleSearch(client, options);\n case 'recall':\n return handleRecall(client, options);\n case 'content':\n return handleContent(client, options);\n case 'check':\n return handleCheck(client, options);\n case 'gc':\n return handleGc(client, options);\n case 'rebuild':\n return handleRebuild(client, options);\n case 'status':\n return handleStatus(client, options);\n case 'export':\n return handleExport(client, options);\n case 'import':\n return handleImport(client, options);\n case 'db-init':\n return handleDbInit(options);\n case 'db-migrate':\n return handleDbMigrate(client, options);\n case 'skill-learn': {\n const result = await runSkillLearn(client, options);\n return result;\n }\n case 'skill-list': {\n const result = await runSkillList(client, options);\n return result;\n }\n case 'skill-get': {\n const result = await runSkillGet(client, options);\n return result;\n }\n case 'skill-delete': {\n const result = await runSkillDelete(client, options);\n return result;\n }\n case 'agent-create': {\n const result = await runAgentCreate(client, options);\n return result;\n }\n case 'agent-list': {\n const result = await runAgentList(client, options);\n return result;\n }\n case 'agent-get': {\n const result = await runAgentGet(client, options);\n return result;\n }\n case 'agent-delete': {\n const result = await runAgentDelete(client, options);\n return result;\n }\n default:\n log('unknown command: ' + options.command, LogLevel.WARNING);\n return {\n error: `unknown command: ${options.command}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleLearn(\n client: DispatchClient,\n options: CliOptions,\n io?: LearnIO,\n): Promise<CommandResult> {\n try {\n const results = await runLearn(client, options, io);\n return {\n output: formatCommandOutput(results, options.format, 'learn'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `learn failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleUnlearn(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const results = await runUnlearn(client, options);\n return {\n output: formatCommandOutput(\n results,\n options.format,\n 'unlearn',\n ),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `unlearn failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleSearch(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const results = await runSearch(client, options);\n if (options.content) {\n await hydrateSearchPreviews(client, results);\n }\n return {\n output: formatOutput(results, options.format),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `search failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleRecall(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runRecall(client, options);\n if ('error' in result) {\n return {\n error: `error: ${result.error}`,\n exitCode: 1,\n };\n }\n return {\n output: formatCommandOutput(result, options.format, 'recall'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `recall failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleExport(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runExport(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'export'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `export failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleImport(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runImport(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'import'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `import failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleContent(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runContent(client, options);\n if (options.format === 'rec') {\n return { output: result.data, exitCode: 0 };\n }\n return {\n output: JSON.stringify(result, null, 2),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `content failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleCheck(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runCheck(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'check'),\n exitCode: result.ok ? 0 : 1,\n };\n } catch (err) {\n return {\n error: `check failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleGc(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runGc(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'gc'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `gc failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleRebuild(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runRebuild(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'rebuild'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `rebuild failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleStatus(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runStatus(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'status'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `status failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nfunction handleDbInit(options: CliOptions): CommandResult {\n return runDbInit(options, runInit);\n}\n\nasync function handleDbMigrate(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runDbMigrate(client, options);\n return {\n output: formatCommandOutput(\n result,\n options.format,\n 'db-migrate',\n ),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `db-migrate failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Current package version, kept in sync with package.json. */\nexport const VERSION = '0.6.1';\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { VERSION } from '../../version/index.ts';\n\n/**\n * The set of all recognised top-level command names,\n * including group commands (`db`, `skill`, `agent`, `worker`).\n */\nconst KNOWN_COMMANDS = new Set([\n 'learn',\n 'unlearn',\n 'search',\n 'recall',\n 'content',\n 'check',\n 'gc',\n 'rebuild',\n 'status',\n 'export',\n 'mcp',\n 'db',\n 'skill',\n 'agent',\n 'worker',\n]);\n\n/** Subcommands available under each group command. */\nconst GROUP_SUBCOMMANDS: Readonly<\n Record<string, readonly (readonly [string, string])[]>\n> = {\n db: [\n ['init', 'Initialise a new .kbdb directory'],\n ['migrate', 'Migrate database to current format'],\n ['path', 'Show resolved database path'],\n ],\n skill: [\n ['learn', 'Create a new skill definition'],\n ['list', 'List all skills'],\n ['get', 'Retrieve a skill by name or kbid'],\n ['delete', 'Remove a skill'],\n ],\n agent: [\n ['create', 'Create an agent with skill refs'],\n ['list', 'List all agents'],\n ['get', 'Retrieve an agent by docid'],\n ['delete', 'Remove an agent'],\n ],\n worker: [\n ['stop', 'Stop the worker daemon'],\n ['restart', 'Restart the worker daemon'],\n ],\n};\n\n/**\n * Returns `true` when `cmd` is a recognised command name.\n *\n * Accepts both simple top-level names (`'learn'`, `'db'`)\n * and the hyphenated compound form produced by `parseArgs`\n * when a group + subcommand precedes `--help`\n * (e.g. `'db-init'`, `'skill-learn'`).\n */\nexport function isKnownCommand(cmd: string): boolean {\n if (KNOWN_COMMANDS.has(cmd)) {\n return true;\n }\n // Check hyphenated compound form: 'db-init', 'skill-learn'\n const dashIdx = cmd.indexOf('-');\n if (dashIdx < 0) {\n return false;\n }\n const group = cmd.slice(0, dashIdx);\n return group in GROUP_SUBCOMMANDS;\n}\n\n/**\n * Generates contextual help text for the `kbdb` CLI.\n *\n * Three levels of detail are produced depending on\n * how many command tokens are supplied:\n *\n * - No arguments: global help listing all commands.\n * - `command` only: command-level help. When `command`\n * is a hyphenated compound (`'db-init'`), it is split\n * into group + subcommand automatically. Group\n * commands show a subcommand listing; leaf commands\n * show detailed help; unknown commands show an error\n * prefix followed by global help.\n * - `command` + `subcommand`: detailed help for that\n * specific subcommand (falls back to group help when\n * the subcommand is not recognised).\n *\n * @param command - optional top-level command token,\n * or a hyphenated compound such as `'db-init'`\n * @param subcommand - optional subcommand token\n */\nexport function generateHelp(\n command?: string,\n subcommand?: string,\n): string {\n if (!command) {\n return generateGlobalHelp();\n }\n // Handle compound form produced by parseArgs:\n // 'db-init' -> group='db', sub='init'\n if (!subcommand && command.includes('-')) {\n const dashIdx = command.indexOf('-');\n const group = command.slice(0, dashIdx);\n const sub = command.slice(dashIdx + 1);\n if (group in GROUP_SUBCOMMANDS) {\n return generateSubcommandHelp(group, sub);\n }\n }\n if (subcommand) {\n return generateSubcommandHelp(command, subcommand);\n }\n return generateCommandHelp(command);\n}\n\n// ---------------------------------------------------------------------------\n// Level 1: Global help\n// ---------------------------------------------------------------------------\n\nfunction generateGlobalHelp(): string {\n return (\n `kbdb v${VERSION} - File-based knowledge base` +\n ` database for AI agents\\n` +\n `\\n` +\n `Usage: kbdb [options]\\n` +\n ` kbdb <command> [options] ...[parameters]\\n` +\n ` kbdb <command> <subcommand> [options]` +\n ` ...[params]\\n` +\n `\\n` +\n `Knowledge Base:\\n` +\n ` learn Import content from` +\n ` files/stdin\\n` +\n ` unlearn Remove sections by kbid\\n` +\n ` search Query the knowledge base\\n` +\n ` recall Retrieve section context` +\n ` by kbid\\n` +\n ` content Compose rendered content` +\n ` from ids\\n` +\n `\\n` +\n `Database:\\n` +\n ` db init Initialise a new .kbdb` +\n ` directory\\n` +\n ` db migrate Migrate database to current` +\n ` format\\n` +\n ` db path Show resolved database` +\n ` path\\n` +\n `\\n` +\n `Maintenance:\\n` +\n ` check Verify knowledge base` +\n ` integrity\\n` +\n ` gc Garbage collect unreferenced\\n` +\n ` sections\\n` +\n ` rebuild Reconstruct all index` +\n ` files\\n` +\n ` status Show database status\\n` +\n ` export Snapshot database for` +\n ` backup\\n` +\n `\\n` +\n `Skills:\\n` +\n ` skill learn Create a new skill` +\n ` definition\\n` +\n ` skill list List all skills\\n` +\n ` skill get Retrieve a skill by name` +\n ` or kbid\\n` +\n ` skill delete Remove a skill\\n` +\n `\\n` +\n `Agents:\\n` +\n ` agent create Create an agent with skill` +\n ` refs\\n` +\n ` agent list List all agents\\n` +\n ` agent get Retrieve an agent by docid\\n` +\n ` agent delete Remove an agent\\n` +\n `\\n` +\n `Worker:\\n` +\n ` worker stop Stop the worker daemon\\n` +\n ` worker restart Restart the worker daemon\\n` +\n `\\n` +\n `Server:\\n` +\n ` mcp Start MCP server mode` +\n ` (stdio)\\n` +\n `\\n` +\n `Global Options:\\n` +\n ` -h, --help Show this help message\\n` +\n ` -v, --version Show version information\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n ` --format <fmt> Output format` +\n ` (json|text|mcp)\\n` +\n `\\n` +\n `Run \"kbdb <command> --help\" for detailed` +\n ` information.\\n`\n );\n}\n\n// ---------------------------------------------------------------------------\n// Level 2: Command help\n// ---------------------------------------------------------------------------\n\nfunction generateCommandHelp(command: string): string {\n if (command in GROUP_SUBCOMMANDS) {\n return generateGroupHelp(command);\n }\n const leaf = LEAF_HELP[command];\n if (leaf) {\n return leaf;\n }\n return `Unknown command: ${command}\\n\\n` + generateGlobalHelp();\n}\n\nfunction generateGroupHelp(group: string): string {\n const subs = GROUP_SUBCOMMANDS[group] ?? [];\n const subLines = subs\n .map(([name, desc]) => ` ${name.padEnd(20)}${desc}`)\n .join('\\n');\n const desc = GROUP_DESCRIPTIONS[group] ?? group;\n return (\n `kbdb ${group} - ${desc}\\n` +\n `\\n` +\n `Usage: kbdb ${group} <subcommand> [options]\\n` +\n `\\n` +\n `Subcommands:\\n` +\n `${subLines}\\n` +\n `\\n` +\n `Global Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n ` -h, --help Show this help message\\n` +\n `\\n` +\n `Run \"kbdb ${group} <subcommand> --help\"` +\n ` for details.\\n`\n );\n}\n\n/** One-line description for each group command. */\nconst GROUP_DESCRIPTIONS: Readonly<Record<string, string>> = {\n db: 'Database management',\n skill: 'Skill management',\n agent: 'Agent management',\n worker: 'Worker daemon management',\n};\n\n// ---------------------------------------------------------------------------\n// Leaf command help texts\n// ---------------------------------------------------------------------------\n\nconst LEAF_HELP: Readonly<Record<string, string>> = {\n learn:\n `kbdb learn - Import content from files or stdin\\n` +\n `\\n` +\n `Usage: kbdb learn [options] <path | ->...\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <path | -> File path, directory,` +\n ` or - for stdin\\n` +\n `\\n` +\n `Options:\\n` +\n ` --title <title> Section title\\n` +\n ` --description <d> Section description\\n` +\n ` --docid <docid> Document ID to group` +\n ` under\\n` +\n ` --tags <t,...> Comma-separated tags\\n` +\n ` --replace Supersede existing section` +\n ` by source key\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON array of { kbid, path, size, skipped,\\n` +\n ` superseded, warnings,` +\n ` near_duplicates }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb learn README.md\\n` +\n ` kbdb learn ./docs/\\n` +\n ` kbdb learn --tags auth,api --replace doc.md\\n` +\n ` cat notes.txt | kbdb learn -\\n`,\n\n unlearn:\n `kbdb unlearn - Remove sections by kbid\\n` +\n `\\n` +\n `Usage: kbdb unlearn [options] <kbid>...\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <kbid> 26-character knowledge` +\n ` base identifier\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON array of { kbid, removed }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb unlearn abcdef1234567890abcdef1234\\n` +\n ` kbdb unlearn id1 id2 id3\\n`,\n\n search:\n `kbdb search - Query the knowledge base\\n` +\n `\\n` +\n `Usage: kbdb search [options] <query>...\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <query> One or more query terms\\n` +\n `\\n` +\n `Options:\\n` +\n ` --mode <mode> Result granularity` +\n ` (sections|documents|stats)\\n` +\n ` --limit <n> Max results (default: 20)\\n` +\n ` --format <fmt> Output format` +\n ` (json|text|mcp)\\n` +\n ` --content, -c Hydrate results with` +\n ` section content\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON array of { kbid, score, preview,` +\n ` matches }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb search \"machine learning\"\\n` +\n ` kbdb search --limit 5 --format text query\\n` +\n ` kbdb search --mode documents --content term\\n`,\n\n recall:\n `kbdb recall - Retrieve section context by kbid\\n` +\n `\\n` +\n `Usage: kbdb recall [options] <kbid>...\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <kbid> 26-character knowledge` +\n ` base identifier\\n` +\n `\\n` +\n `Options:\\n` +\n ` --depth <n>, -d Expansion depth (0-3,` +\n ` default: 0)\\n` +\n ` --tags <t,...> Filter by tags\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON RecallResult or RecallResult[]\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb recall abcdef1234567890abcdef1234\\n` +\n ` kbdb recall kbid1 --depth 2\\n`,\n\n content:\n `kbdb content - Compose rendered content from ids\\n` +\n `\\n` +\n `Usage: kbdb content [options] <id>...\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <id> kbid or docid identifier\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { type, data, total }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb content abcdef1234567890abcdef1234\\n` +\n ` kbdb content id1 id2\\n`,\n\n check:\n `kbdb check - Verify knowledge base integrity\\n` +\n `\\n` +\n `Usage: kbdb check [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { ok, errors }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb check\\n` +\n ` kbdb check --db /path/to/project\\n`,\n\n gc:\n `kbdb gc - Garbage collect unreferenced sections\\n` +\n `\\n` +\n `Usage: kbdb gc [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { removed_sections, removed_bytes }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb gc\\n` +\n ` kbdb gc --db /path/to/project\\n`,\n\n rebuild:\n `kbdb rebuild - Reconstruct all index files\\n` +\n `\\n` +\n `Usage: kbdb rebuild [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { sections_reindexed, terms_indexed }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb rebuild\\n` +\n ` kbdb rebuild --db /path/to/project\\n`,\n\n status:\n `kbdb status - Show database status\\n` +\n `\\n` +\n `Usage: kbdb status [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON database status object\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb status\\n` +\n ` kbdb status --db /path/to/project\\n`,\n\n export:\n `kbdb export - Snapshot database for backup\\n` +\n `\\n` +\n `Usage: kbdb export [options] [<path>]\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <path> Output directory path\\n` +\n ` (default: ./kbdb-export/)\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { path, sections_exported,` +\n ` documents_exported }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb export\\n` +\n ` kbdb export ./my-backup\\n` +\n ` kbdb export --db /path/to/project\\n`,\n\n mcp:\n `kbdb mcp - Start MCP server mode (stdio)\\n` +\n `\\n` +\n `Usage: kbdb mcp [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Environment:\\n` +\n ` KBDB_DB_DIR Fallback database path\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb mcp --db /path/to/project\\n` +\n ` KBDB_DB_DIR=/path/to/project kbdb mcp\\n`,\n};\n\n// ---------------------------------------------------------------------------\n// Level 3: Subcommand help\n// ---------------------------------------------------------------------------\n\n/**\n * Detailed help texts keyed by `\"group-subcommand\"`.\n * Falls back to group help when the key is absent.\n */\nconst SUBCOMMAND_HELP: Readonly<Record<string, string>> = {\n 'db-init':\n `kbdb db init - Initialise a new .kbdb directory\\n` +\n `\\n` +\n `Usage: kbdb db init [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to create .kbdb in\\n` +\n ` (default: current directory)\\n` +\n ` -h, --help Show this help message\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { path, created }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb db init\\n` +\n ` kbdb db init --db /path/to/project\\n`,\n\n 'db-migrate':\n `kbdb db migrate - Migrate database to current` +\n ` format\\n` +\n `\\n` +\n `Usage: kbdb db migrate [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path containing .kbdb\\n` +\n ` (default: current directory)\\n` +\n ` -h, --help Show this help message\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON MigrateResult or \"already up to date\"\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb db migrate\\n` +\n ` kbdb db migrate --db /path/to/project\\n`,\n\n 'db-path':\n `kbdb db path - Show resolved database path\\n` +\n `\\n` +\n `Usage: kbdb db path [options]\\n` +\n `\\n` +\n `Prints the absolute path of the .kbdb database\\n` +\n `that would be used by the current command\\n` +\n `context. Useful for debugging database\\n` +\n `resolution.\\n` +\n `\\n` +\n `Resolution order:\\n` +\n ` 1. --db <path> Explicit flag\\n` +\n ` 2. cwd traversal Walk up from cwd\\n` +\n ` 3. KBDB_DB_DIR Environment variable\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n ` --format json Show full diagnostic\\n` +\n ` -h, --help Show this help message\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb db path\\n` +\n ` kbdb db path --format json\\n` +\n ` kbdb db path --db /path/to/project\\n`,\n\n 'skill-learn':\n `kbdb skill learn - Create a new skill definition\\n` +\n `\\n` +\n `Usage: kbdb skill learn [options]` +\n ` --name <n> --body <file|->\\n` +\n `\\n` +\n `Options:\\n` +\n ` --name <name> Skill name (required)\\n` +\n ` --description <d> Skill description\\n` +\n ` --body <file|-> Template body file or` +\n ` stdin (required)\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { kbid, name, arguments }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb skill learn --name summarize` +\n ` --body prompt.txt\\n` +\n ` cat body.txt | kbdb skill learn` +\n ` --name my-skill --body -\\n`,\n\n 'skill-list':\n `kbdb skill list - List all skills\\n` +\n `\\n` +\n `Usage: kbdb skill list [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON array of { kbid, name, description,` +\n ` argumentCount }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb skill list\\n` +\n ` kbdb skill list --db /path/to/project\\n`,\n\n 'skill-get':\n `kbdb skill get - Retrieve a skill by name` +\n ` or kbid\\n` +\n `\\n` +\n `Usage: kbdb skill get [options] <name-or-kbid>\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <name-or-kbid> Skill name or 26-char` +\n ` kbid\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON SkillDefinition object\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb skill get summarize-document\\n` +\n ` kbdb skill get abcdef1234567890abcdef1234\\n`,\n\n 'skill-delete':\n `kbdb skill delete - Remove a skill\\n` +\n `\\n` +\n `Usage: kbdb skill delete [options] <kbid>\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <kbid> 26-character kbid of the` +\n ` skill to remove\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { kbid, removed }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb skill delete abcdef1234567890abcdef1234\\n`,\n\n 'agent-create':\n `kbdb agent create - Create an agent with skill` +\n ` refs\\n` +\n `\\n` +\n `Usage: kbdb agent create [options] --name <n>` +\n ` --persona <file|-> --skills <kbid,...>\\n` +\n `\\n` +\n `Options:\\n` +\n ` --name <name> Agent name (required)\\n` +\n ` --description <d> Agent description\\n` +\n ` --persona <file|-> Persona file or stdin` +\n ` (required)\\n` +\n ` --skills <kbid,...> Comma-separated skill` +\n ` kbids (required)\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { docid, name, skills }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb agent create --name code-reviewer` +\n ` --persona ./p.txt --skills abc123\\n` +\n ` cat persona.txt | kbdb agent create` +\n ` --name my-agent --persona - --skills abc123\\n`,\n\n 'agent-list':\n `kbdb agent list - List all agents\\n` +\n `\\n` +\n `Usage: kbdb agent list [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON array of { docid, name, description,` +\n ` skillCount }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb agent list\\n` +\n ` kbdb agent list --db /path/to/project\\n`,\n\n 'agent-get':\n `kbdb agent get - Retrieve an agent by docid\\n` +\n `\\n` +\n `Usage: kbdb agent get [options] <docid>\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <docid> Agent document identifier\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON AgentDefinition object with resolved` +\n ` skills\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb agent get agent-code-reviewer\\n`,\n\n 'agent-delete':\n `kbdb agent delete - Remove an agent\\n` +\n `\\n` +\n `Usage: kbdb agent delete [options] <docid>\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <docid> Agent document identifier\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { docid, removed }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb agent delete agent-code-reviewer\\n`,\n\n 'worker-stop':\n `kbdb worker stop - Stop the worker daemon\\n` +\n `\\n` +\n `Usage: kbdb worker stop [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb worker stop\\n` +\n ` kbdb worker stop --db /path/to/project\\n`,\n\n 'worker-restart':\n `kbdb worker restart - Restart the worker daemon\\n` +\n `\\n` +\n `Usage: kbdb worker restart [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb worker restart\\n` +\n ` kbdb worker restart --db /path/to/project\\n`,\n};\n\nfunction generateSubcommandHelp(\n command: string,\n subcommand: string,\n): string {\n const key = `${command}-${subcommand}`;\n const text = SUBCOMMAND_HELP[key];\n if (text) {\n return text;\n }\n // Fall back to group help when subcommand is unknown\n return generateCommandHelp(command);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { DbResolution } from '../typings/db-resolution.interface.ts';\n\n/** Options controlling database directory resolution. */\ninterface ResolveDbDirOptions {\n /** Explicit `--db` flag value, if provided. */\n dbPath?: string;\n /** When true, skips cwd upward traversal. */\n skipTraversal?: boolean;\n}\n\n/**\n * Resolves the `.kbdb` database directory using a strict\n * priority chain: explicit `--db` flag, then upward cwd\n * traversal, then the `KBDB_DB_DIR` environment variable.\n *\n * An explicit `--db` flag that fails to resolve returns\n * `null` immediately -- it never falls through to\n * traversal or the environment variable.\n *\n * @param findDb - locates a `.kbdb` directory. Called with\n * a base path to resolve from, or with no argument to\n * trigger upward traversal from the current working\n * directory.\n */\nexport function resolveDbDir(\n options: ResolveDbDirOptions,\n findDb: (basePath?: string) => string | null,\n): DbResolution | null {\n if (options.dbPath) {\n const flagResult = findDb(options.dbPath);\n return flagResult ? { path: flagResult, source: 'flag' } : null;\n }\n\n if (!options.skipTraversal) {\n const traversalResult = findDb();\n if (traversalResult) {\n return { path: traversalResult, source: 'traversal' };\n }\n }\n\n const envDir = process.env['KBDB_DB_DIR'];\n if (envDir) {\n const envResult = findDb(envDir);\n if (envResult) {\n return { path: envResult, source: 'env' };\n }\n }\n\n return null;\n}\n\nexport type { ResolveDbDirOptions };\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Options controlling the \"database not found\" diagnostic. */\ninterface FormatDbNotFoundOptions {\n /** Explicit `--db` flag value, if provided. */\n dbPath?: string;\n /** When true, omits the cwd traversal line and init hint. */\n skipTraversal?: boolean;\n}\n\n/**\n * Formats the error message shown when no `.kbdb` database\n * directory can be resolved.\n *\n * When `options.dbPath` is set, an explicit `--db` flag failed\n * to resolve and a single-line message is returned. Otherwise a\n * multi-line diagnostic lists each fallback that was checked so\n * the user can see why resolution failed.\n *\n * @param options - resolution context that produced the failure\n */\nexport function formatDbNotFound(\n options: FormatDbNotFoundOptions,\n): string {\n if (options.dbPath) {\n return `error: no .kbdb database found at ${options.dbPath}`;\n }\n\n const envValue = process.env['KBDB_DB_DIR'] ?? '(not set)';\n const lines = [\n 'error: no .kbdb database found',\n ' --db: (not set)',\n ];\n\n if (!options.skipTraversal) {\n lines.push(` cwd: ${process.cwd()} (searched upward)`);\n }\n\n lines.push(` KBDB_DB_DIR: ${envValue}`);\n\n if (!options.skipTraversal) {\n lines.push('Run \"kbdb db init\" to create a database.');\n }\n\n return lines.join('\\n');\n}\n\nexport type { FormatDbNotFoundOptions };\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { resolveDbDir } from './resolve-db-dir.function.ts';\nimport { formatDbNotFound } from './format-db-not-found.function.ts';\n\n/**\n * Handles the `kbdb db path` subcommand.\n *\n * Prints the resolved `.kbdb` directory path. With\n * `--format json`, outputs a full diagnostic object\n * showing which source provided the resolution.\n */\nexport function runDbPath(\n options: Pick<CliOptions, 'dbPath' | 'format'>,\n findDb: (basePath?: string) => string | null,\n): CommandResult {\n const resolution = resolveDbDir({ dbPath: options.dbPath }, findDb);\n\n if (!resolution) {\n return {\n error: formatDbNotFound({ dbPath: options.dbPath }),\n exitCode: 1,\n };\n }\n\n if (options.format === 'json') {\n const diagnostic = {\n path: resolution.path,\n source: resolution.source,\n flag: options.dbPath ?? null,\n cwd: process.cwd(),\n env: process.env['KBDB_DB_DIR'] ?? null,\n };\n return {\n output: JSON.stringify(diagnostic, null, 2),\n exitCode: 0,\n };\n }\n\n return { output: resolution.path, exitCode: 0 };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { connect } from 'node:net';\nimport type { Socket } from 'node:net';\nimport { discoverDaemon } from '../functions/discover-daemon.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport type { SearchParams } from '../typings/search-params.model.ts';\nimport type { PagedSearchResult } from '../typings/search-result.model.ts';\nimport type {\n AddSectionParams,\n Section,\n} from '../typings/section.model.ts';\nimport type { StatusResult } from '../typings/status-result.model.ts';\nimport type { AddSectionResult } from '../typings/add-section-result.model.ts';\nimport type { RemoveSectionResult } from '../typings/remove-section-result.model.ts';\nimport type { ContentResult } from '../typings/content-result.model.ts';\nimport type { IntegrityCheckResult } from '../typings/integrity-check-result.model.ts';\nimport type { GcResult } from '../typings/gc-result.model.ts';\nimport type { RebuildResult } from '../typings/rebuild-result.model.ts';\nimport type { MigrateResult } from '../typings/migrate-result.model.ts';\nimport type { VersionStatus } from '../typings/version-status.model.ts';\nimport type { SectionRecord } from '../../wasm-codec/functions/decode-section-records.function.ts';\nimport type { DocumentManifest } from '../../wasm-codec/functions/decode-document-manifest.function.ts';\nimport type {\n RecallParams,\n RecallResult,\n} from '../typings/recall-result.model.ts';\nimport type { ExportResult } from '../typings/export-result.model.ts';\nimport type { ImportResult } from '../typings/import-result.model.ts';\n\n/** Pending JSON-RPC call awaiting a response from the daemon. */\ninterface PendingCall {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n timer?: ReturnType<typeof setTimeout>;\n}\n\n/** Shape of a JSON-RPC 2.0 error object from the daemon. */\ninterface JsonRpcError {\n readonly code: number;\n readonly message: string;\n}\n\n/** Shape of a JSON-RPC 2.0 response from the daemon. */\ninterface JsonRpcResponse {\n readonly id: number;\n readonly result?: unknown;\n readonly error?: JsonRpcError;\n}\n\n/**\n * IPC client that communicates with the worker daemon over a Unix\n * domain socket (or Windows named pipe) using JSON-RPC 2.0 with\n * newline-delimited message framing.\n *\n * Call `connect()` before any other method and `disconnect()` when\n * done to release the underlying socket.\n */\nexport class WorkerClient {\n /** Underlying socket; `null` when not connected. */\n private socket: Socket | null = null;\n\n /** Monotonically increasing request ID counter. */\n private nextId = 1;\n\n /** Map of outstanding request IDs to their resolve/reject pairs. */\n private readonly pending = new Map<number, PendingCall>();\n\n /** Partial line buffer for split TCP/IPC frames. */\n private buffer = '';\n\n /**\n * @param socketPath - absolute path to the daemon's IPC socket\n * (or Windows named pipe path)\n * @param contextId - 16-character context identifier sent as\n * `ctx` in every JSON-RPC request\n * @param requestTimeoutMs - per-request timeout in ms\n * (0 or undefined disables the timeout)\n */\n constructor(\n private readonly socketPath: string,\n private readonly contextId: string,\n private readonly requestTimeoutMs?: number,\n ) {}\n\n /** Whether the underlying socket is connected. */\n get isConnected(): boolean {\n return this.socket !== null;\n }\n\n /**\n * Establishes the IPC connection to the worker daemon.\n *\n * Retries up to 5 times with exponential backoff on\n * transient errors (`ENOENT`, `ECONNREFUSED`).\n *\n * @throws {Error} if the connection cannot be established\n */\n async connect(): Promise<void> {\n log('connecting to ' + this.socketPath, LogLevel.DEBUG);\n const maxRetries = 5;\n let delay = 50;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n await this.tryConnect();\n log('connected', LogLevel.DEBUG);\n return;\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException).code;\n const retriable =\n code === 'ENOENT' || code === 'ECONNREFUSED';\n if (!retriable || attempt === maxRetries) {\n throw err;\n }\n log(\n 'connect retry: attempt=' +\n attempt.toString() +\n ' code=' +\n code +\n ' delay=' +\n delay.toString() +\n 'ms',\n LogLevel.DEBUG,\n );\n await new Promise<void>((r) => setTimeout(r, delay));\n delay = Math.min(delay * 2, 1000);\n }\n }\n }\n\n /** Destroys the IPC socket and clears the connection state. */\n disconnect(): void {\n log('disconnecting client', LogLevel.DEBUG);\n if (this.socket) {\n this.socket.destroy();\n this.socket = null;\n }\n }\n\n /**\n * Kills the daemon process and disconnects the client.\n *\n * Discovers the daemon via PID file and sends `SIGTERM`.\n * Always disconnects the socket regardless of kill outcome.\n */\n killDaemon(): void {\n const info = discoverDaemon(this.contextId);\n log(\n 'killing daemon: pid=' +\n (info ? info.pid.toString() : 'unknown'),\n LogLevel.DEBUG,\n );\n if (info) {\n try {\n process.kill(info.pid, 'SIGTERM');\n } catch {\n // already dead\n }\n }\n this.disconnect();\n }\n\n /**\n * Single connection attempt with keepalive and\n * post-connect failure handlers.\n */\n private async tryConnect(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const sock = connect(this.socketPath, () => {\n sock.removeListener('error', reject);\n sock.setKeepAlive(true, 30_000);\n sock.on('error', (err: Error) => {\n log(\n 'socket error: code=' +\n ((err as NodeJS.ErrnoException).code ??\n err.message),\n LogLevel.DEBUG,\n );\n this.handleSocketFailure(err);\n });\n sock.on('close', () => {\n log('socket closed', LogLevel.DEBUG);\n if (this.pending.size > 0) {\n this.handleSocketFailure(\n new Error('connection closed'),\n );\n }\n this.socket = null;\n });\n this.socket = sock;\n resolve();\n });\n sock.on('error', reject);\n sock.on('data', (chunk: Buffer) => {\n this.handleData(chunk.toString());\n });\n });\n }\n\n /**\n * Rejects all pending calls and marks the client as\n * disconnected.\n */\n private handleSocketFailure(err: Error): void {\n log(\n 'socket failure: pending=' +\n this.pending.size.toString() +\n ' err=' +\n err.message,\n LogLevel.DEBUG,\n );\n const sock = this.socket;\n this.socket = null;\n for (const [id, call] of this.pending) {\n this.pending.delete(id);\n if (call.timer) clearTimeout(call.timer);\n call.reject(err);\n }\n if (sock) sock.destroy();\n }\n\n /**\n * Searches the knowledge base.\n *\n * @param params - query parameters including the search string\n * @returns paginated search results with metadata\n */\n async search(params: SearchParams): Promise<PagedSearchResult> {\n return this.call('search', {\n ...params,\n algo: params.algo,\n }) as Promise<PagedSearchResult>;\n }\n\n /**\n * Retrieves full content and context for one or more sections by\n * their knowledge-base identifiers.\n *\n * @param params - section identifier(s) and optional expansion depth\n * @returns a single `RecallResult` when `kbid` is provided without\n * `kbids`, or a `RecallResult[]` when `kbids` is provided\n */\n async recall(\n params: RecallParams,\n ): Promise<RecallResult | RecallResult[]> {\n return this.call('recall', params) as Promise<\n RecallResult | RecallResult[]\n >;\n }\n\n /**\n * Adds a new section to the knowledge base.\n *\n * @param params - section content and metadata\n * @returns the result including the assigned knowledge-base\n * identifier and indexing statistics\n */\n async addSection(\n params: AddSectionParams,\n ): Promise<AddSectionResult> {\n return this.call(\n 'addSection',\n params,\n ) as Promise<AddSectionResult>;\n }\n\n /**\n * Replaces an existing section's content and metadata.\n *\n * @param kbid - identifier of the section to update\n * @param params - new content and metadata\n * @returns the knowledge-base identifier of the updated section\n */\n async updateSection(\n kbid: string,\n params: AddSectionParams,\n ): Promise<string> {\n return this.call('updateSection', {\n kbid,\n ...params,\n }) as Promise<string>;\n }\n\n /**\n * Removes a section from the knowledge base.\n *\n * @param kbid - identifier of the section to remove\n * @returns removal result with `removed` flag and elapsed time\n */\n async removeSection(kbid: string): Promise<RemoveSectionResult> {\n return this.call('removeSection', {\n kbid,\n }) as Promise<RemoveSectionResult>;\n }\n\n /**\n * Retrieves multiple sections by their identifiers.\n *\n * @param kbids - list of knowledge-base identifiers to fetch\n * @returns sections in the order their IDs were requested\n */\n async readSections(kbids: string[]): Promise<Section[]> {\n return this.call('readSections', {\n kbids,\n }) as Promise<Section[]>;\n }\n\n /**\n * Groups a set of sections under a named document.\n *\n * @param title - human-readable document title\n * @param kbids - identifiers of the sections to group\n * @param docType - application-level document type tag; omit or\n * pass an empty string for untagged documents\n * @returns the assigned document identifier\n */\n async groupSections(\n title: string,\n kbids: string[],\n docType?: string,\n ): Promise<string> {\n const result = (await this.call('groupSections', {\n title,\n kbids,\n docType: docType ?? '',\n })) as { docid: string } | string;\n return typeof result === 'string' ? result : result.docid;\n }\n\n /**\n * Removes the document grouping for the given document.\n *\n * The sections themselves are not deleted; only the grouping\n * record is removed.\n *\n * @param docid - identifier of the document grouping to remove\n */\n async removeGrouping(docid: string): Promise<void> {\n await this.call('removeGrouping', { docid });\n }\n\n /**\n * Retrieves a full document record including its sections.\n *\n * @param docid - identifier of the document to retrieve\n * @returns the document record as returned by the daemon\n */\n async retrieveDocument(docid: string): Promise<unknown> {\n return this.call('retrieveDocument', { docid });\n }\n\n /**\n * Composes a rendered Markdown document from one or more kbid\n * or docid identifiers.\n *\n * @param ids - list of kbid or docid identifiers (may be mixed)\n * @returns composed Markdown result with character count\n */\n async content(ids: string[]): Promise<ContentResult> {\n return this.call('content', { ids }) as Promise<ContentResult>;\n }\n\n /**\n * Runs an integrity check on the knowledge-base database.\n *\n * @returns a report of all issues found; `ok` is `true` when\n * no errors were detected\n */\n async integrityCheck(): Promise<IntegrityCheckResult> {\n return this.call(\n 'integrityCheck',\n {},\n ) as Promise<IntegrityCheckResult>;\n }\n\n /**\n * Removes unreferenced sections from the database.\n *\n * @returns a report of sections removed and bytes freed\n */\n async gc(): Promise<GcResult> {\n return this.call('gc', {}) as Promise<GcResult>;\n }\n\n /**\n * Reconstructs all index files from section files and document\n * manifests on disk. Text and code sections are re-tokenized;\n * image sections are skipped.\n *\n * @returns a report of sections and terms re-indexed\n */\n async rebuildIndexes(): Promise<RebuildResult> {\n return this.call('rebuildIndexes', {}) as Promise<RebuildResult>;\n }\n\n /**\n * Invalidates the in-memory cache entry for a single section.\n *\n * @param kbid - identifier of the section to evict from cache\n */\n async invalidate(kbid: string): Promise<void> {\n await this.call('invalidate', { kbid });\n }\n\n /** Clears all entries from the daemon's in-memory cache. */\n async invalidateAll(): Promise<void> {\n await this.call('invalidateAll', {});\n }\n\n /**\n * Retrieves diagnostic status information from the daemon.\n *\n * @returns current initialization state and cache statistics\n */\n async status(): Promise<StatusResult> {\n return this.call('status', {}) as Promise<StatusResult>;\n }\n\n /**\n * Returns database metadata and status from the daemon,\n * including document count, section count, index size, and\n * cache statistics.\n *\n * @returns database metadata from the daemon's cached state\n */\n async dbStatus(): Promise<StatusResult> {\n return this.call('dbStatus', {}) as Promise<StatusResult>;\n }\n\n /**\n * Initialises a new `.kbdb` database directory at the given path\n * by sending an init request to the worker daemon.\n *\n * The daemon creates all required subdirectories and seed files via\n * the `worker_init_directory` WASM export.\n *\n * @param targetPath - absolute path to the directory that will\n * contain the new `.kbdb` database\n * @throws {Error} if the `.kbdb` directory already exists or the\n * daemon cannot create the layout\n */\n async initDirectory(targetPath: string): Promise<void> {\n await this.call('initDirectory', { targetPath });\n }\n\n /**\n * Runs all pending database migrations for the `.kbdb` directory\n * at the given path.\n *\n * Delegates to the `worker_migrate` WASM export on the daemon.\n * Each migration step updates `catalog.toml` on success, so\n * retrying after a partial failure is safe.\n *\n * @param targetPath - absolute path to the `.kbdb` database root\n * @returns migration report with old version, new version, and\n * number of migration steps applied\n */\n async migrateDatabase(targetPath: string): Promise<MigrateResult> {\n return this.call('migrateDatabase', {\n targetPath,\n }) as Promise<MigrateResult>;\n }\n\n /**\n * Checks the format version of the `.kbdb` database at the given\n * path against the version required by the current WASM engine.\n *\n * This is a read-only operation: it reads `catalog.toml` and\n * returns the compatibility status without making any changes.\n *\n * @param targetPath - absolute path to the `.kbdb` database root\n * @returns version compatibility report\n */\n async checkVersion(targetPath: string): Promise<VersionStatus> {\n return this.call('checkVersion', {\n targetPath,\n }) as Promise<VersionStatus>;\n }\n\n /**\n * Retrieves all sections whose type name matches the given string.\n *\n * @param sectionType - the application-level type name to filter by\n * @returns all section records with a matching type name\n */\n async listByType(sectionType: string): Promise<SectionRecord[]> {\n return this.call('listByType', {\n sectionType,\n }) as Promise<SectionRecord[]>;\n }\n\n /**\n * Retrieves all documents whose type name matches the given string.\n *\n * @param docType - the application-level document type to filter by\n * @returns all document manifests with a matching type name\n */\n async listDocumentsByType(\n docType: string,\n ): Promise<DocumentManifest[]> {\n return this.call('listDocumentsByType', {\n docType,\n }) as Promise<DocumentManifest[]>;\n }\n\n /**\n * Exports the database to a target directory on disk.\n *\n * Copies section files, document manifests, and `catalog.toml`\n * to `params.path`. Index files are not exported because they\n * are derivable from the section and document data.\n *\n * @param params - optional export parameters\n * @param params.path - target directory path; defaults to\n * `./kbdb-export/` when not provided\n * @returns export report with the resolved path and file counts\n */\n async export(params?: {\n path?: string;\n format?: string;\n }): Promise<ExportResult> {\n return this.call('export', {\n targetPath: params?.path || undefined,\n format: params?.format,\n }) as Promise<ExportResult>;\n }\n\n /**\n * Imports an exported database from the given path.\n *\n * @param params - source path and dry-run flag\n * @returns import report with counts and timing\n */\n async import(params: {\n from: string;\n dryRun: boolean;\n }): Promise<ImportResult> {\n return this.call('importDb', {\n sourcePath: params.from,\n dryRun: params.dryRun,\n }) as Promise<ImportResult>;\n }\n\n /**\n * Sends a JSON-RPC 2.0 request and awaits the response.\n *\n * @param method - the RPC method name\n * @param params - parameters to include in the request\n * @throws {Error} if not connected\n * @throws {Error} when the daemon returns an error response\n */\n private async call(\n method: string,\n params: unknown,\n ): Promise<unknown> {\n const socket = this.socket;\n if (!socket) {\n throw new Error('not connected');\n }\n\n const id = this.nextId++;\n log(\n 'call: method=' + method + ' id=' + id.toString(),\n LogLevel.DEBUG,\n );\n const request = {\n jsonrpc: '2.0',\n id,\n method,\n params: { ctx: this.contextId, ...(params as object) },\n };\n\n const timeoutMs = this.requestTimeoutMs;\n return new Promise<unknown>((resolve, reject) => {\n const call: PendingCall = { resolve, reject };\n if (timeoutMs) {\n call.timer = setTimeout(() => {\n if (!this.pending.has(id)) return;\n this.pending.delete(id);\n log(\n 'request timeout after ' + String(timeoutMs) + 'ms',\n LogLevel.WARNING,\n );\n const err = new Error(\n `request timeout after ${String(timeoutMs)}ms`,\n );\n (err as unknown as Record<string, unknown>).code =\n 'REQUEST_TIMEOUT';\n reject(err);\n }, timeoutMs);\n }\n this.pending.set(id, call);\n socket.write(JSON.stringify(request) + '\\n');\n });\n }\n\n /**\n * Processes incoming data from the socket, splitting on newlines\n * and dispatching complete JSON-RPC response objects.\n *\n * @param data - raw string chunk received from the socket\n */\n private handleData(data: string): void {\n this.buffer += data;\n const lines = this.buffer.split('\\n');\n this.buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const response = JSON.parse(line) as JsonRpcResponse;\n const pending = this.pending.get(response.id);\n if (pending) {\n this.pending.delete(response.id);\n if (pending.timer) clearTimeout(pending.timer);\n if (response.error) {\n log(\n 'response error: id=' +\n response.id.toString() +\n ' code=' +\n response.error.code.toString(),\n LogLevel.DEBUG,\n );\n const err = new Error(response.error.message);\n (err as unknown as Record<string, unknown>).code =\n response.error.code;\n pending.reject(err);\n } else {\n log(\n 'response ok: id=' + response.id.toString(),\n LogLevel.DEBUG,\n );\n pending.resolve(response.result);\n }\n } else {\n log(\n 'unmatched response id=' + response.id.toString(),\n LogLevel.DEBUG,\n );\n }\n } catch (parseErr: unknown) {\n log(\n 'json parse error: ' + (parseErr as Error).message,\n LogLevel.DEBUG,\n );\n }\n }\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync, readFileSync, unlinkSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { isProcessAlive } from '../../platform/functions/is-process-alive.function.ts';\nimport type { DaemonInfo } from '../typings/daemon-info.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\nexport type { DaemonInfo };\n\n/**\n * Discovers a running worker daemon for the given context.\n *\n * Reads the PID file at `<tmpdir>/kbdb-<contextId>.pid`. If the\n * file exists and the process is alive, returns its PID and the\n * expected socket path. If the file is stale (process dead or PID\n * unparseable), removes the PID file and returns `null`.\n *\n * @param contextId - the 16-character context identifier\n * @returns daemon location info, or `null` if no live daemon found\n */\nexport function discoverDaemon(contextId: string): DaemonInfo | null {\n log('discovering daemon for context: ' + contextId, LogLevel.DEBUG);\n const pidPath = join(tmpdir(), `kbdb-${contextId}.pid`);\n\n if (!existsSync(pidPath)) {\n log(\n 'no daemon PID file found for context: ' + contextId,\n LogLevel.DEBUG,\n );\n return null;\n }\n\n const pidStr = readFileSync(pidPath, 'utf-8').trim();\n const pid = parseInt(pidStr, 10);\n\n if (isNaN(pid) || !isProcessAlive(pid)) {\n log(\n 'daemon process not alive for context: ' + contextId,\n LogLevel.DEBUG,\n );\n try {\n unlinkSync(pidPath);\n } catch {\n // Stale PID file removal is best-effort\n }\n return null;\n }\n\n log('daemon found: pid=' + pid.toString(), LogLevel.DEBUG);\n const socketPath = join(tmpdir(), `kbdb-${contextId}.sock`);\n\n const crashPath = join(tmpdir(), `kbdb-${contextId}.crash`);\n try {\n unlinkSync(crashPath);\n } catch {\n // stale crash file removal is best-effort\n }\n\n return { pid, socketPath };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Checks whether a process with the given PID is alive.\n *\n * Sends signal `0` to the process, which performs a permission\n * check without sending an actual signal. Returns `true` if the\n * process exists and is reachable, `false` otherwise.\n *\n * @param pid - the process identifier to probe\n */\nexport function isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Resolves the absolute path to the `.kbdb` database directory.\n *\n * Searches for a `.kbdb` sub-directory inside `targetDir`. When\n * `targetDir` is omitted, `process.cwd()` is used as the base.\n *\n * @param targetDir - directory to search in; defaults to cwd\n * @throws {Error} if no `.kbdb` directory exists at the resolved\n * path\n */\nexport function resolveDbPath(targetDir?: string): string {\n const base = targetDir ? resolve(targetDir) : process.cwd();\n const dbPath = join(base, '.kbdb');\n if (!existsSync(dbPath)) {\n const msg = `database not found: ${dbPath}`;\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n return dbPath;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { computeSha256 } from '../../hash/functions/compute-sha256.ts';\n\n/**\n * Computes a short context identifier for an absolute path.\n *\n * Hashes the path with SHA-256 and returns the first 16 hex\n * characters. The result is stable for the same input and unique\n * enough to avoid accidental collisions across typical path sets.\n *\n * @param absolutePath - the absolute filesystem path to identify\n * @returns a 16-character lowercase hex string\n */\nexport async function computeContextId(\n absolutePath: string,\n): Promise<string> {\n const hash = await computeSha256(absolutePath);\n return hash.slice(0, 16);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { spawn } from 'node:child_process';\nimport type { Runtime } from '../../runtime/typings/runtime.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { buildDenoPermissions } from './build-deno-permissions.function.ts';\n\n/**\n * Spawns a detached worker daemon process for the given context.\n *\n * @param contextPath - absolute path to the context directory the\n * daemon should serve\n * @param runtime - the current JavaScript runtime environment\n * @param workerScript - absolute path to the worker daemon script,\n * resolved by `resolveSpawnScript`\n */\nexport function spawnDaemon(\n contextPath: string,\n runtime: Runtime,\n workerScript?: string,\n): void {\n if (!workerScript) {\n const msg =\n 'workerScript must be provided' + ' (resolve at entry point)';\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n const execPath = runtime === 'deno' ? 'deno' : process.execPath;\n\n const logLevelEnv = process.env['KBDB_LOG_LEVEL'];\n const logArgs = logLevelEnv ? ['--log-level', logLevelEnv] : [];\n\n const args =\n runtime === 'deno'\n ? [\n 'run',\n ...buildDenoPermissions(),\n workerScript,\n contextPath,\n ...logArgs,\n ]\n : [workerScript, contextPath, ...logArgs];\n\n log(\n 'spawning daemon: ' + execPath + ' ' + args.join(' '),\n LogLevel.DEBUG,\n );\n const child = spawn(execPath, args, {\n detached: true,\n stdio: 'ignore',\n });\n child.unref();\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Deno permission flags for the worker daemon.\n *\n * - read: WASM modules, DB files, config\n * - write: DB files, IPC socket, crash logs, exports\n * - env: KBDB_LOG_LEVEL, HOME, TMPDIR, XDG_RUNTIME_DIR\n * - run: not used by daemon itself (CLI needs it to\n * spawn the daemon, included for symmetry)\n * - sys: os.tmpdir(), os.hostname() via node:os compat\n */\nexport function buildDenoPermissions(): string[] {\n return [\n '--allow-read',\n '--allow-write',\n '--allow-env',\n '--allow-run',\n '--allow-sys',\n ];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** Default maximum wait time for the daemon PID file to appear. */\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\n/** Polling interval in milliseconds between existence checks. */\nconst POLL_INTERVAL_MS = 100;\n\n/**\n * Waits for the worker daemon's PID file to appear on disk.\n *\n * Polls every 100 ms until the PID file at\n * `<tmpdir>/kbdb-<contextId>.pid` exists or the timeout elapses.\n *\n * @param contextId - the 16-character context identifier\n * @param timeoutMs - maximum wait time in milliseconds; defaults\n * to 10 000 ms\n * @returns `true` if the PID file appeared before the timeout,\n * `false` otherwise\n */\nexport async function waitForDaemon(\n contextId: string,\n timeoutMs: number = DEFAULT_TIMEOUT_MS,\n): Promise<boolean> {\n log('waiting for daemon: contextId=' + contextId, LogLevel.DEBUG);\n const pidPath = join(tmpdir(), `kbdb-${contextId}.pid`);\n const start = Date.now();\n let iteration = 0;\n while (Date.now() - start < timeoutMs) {\n if (existsSync(pidPath)) {\n log('daemon PID file appeared', LogLevel.DEBUG);\n return true;\n }\n iteration++;\n if (iteration % 10 === 0) {\n const elapsed = Date.now() - start;\n log(\n 'still waiting for daemon: elapsed=' +\n elapsed.toString() +\n 'ms',\n LogLevel.DEBUG,\n );\n }\n await new Promise<void>((r) => setTimeout(r, POLL_INTERVAL_MS));\n }\n const elapsed = Date.now() - start;\n log(\n 'timed out waiting for daemon: elapsed=' +\n elapsed.toString() +\n 'ms',\n LogLevel.DEBUG,\n );\n return false;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync, readFileSync, unlinkSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\n\n/**\n * Reads and clears the crash log written by a worker daemon that\n * failed to start, returning a human-readable reason.\n *\n * @param contextId - the 16-char hex context ID for the daemon\n * @returns the recorded crash error, or a fallback message when no\n * usable crash log is found\n */\nexport function readCrashReason(contextId: string): string {\n const crashPath = join(tmpdir(), `kbdb-${contextId}.crash`);\n if (!existsSync(crashPath)) {\n return 'daemon failed to start (no details available)';\n }\n try {\n const raw = readFileSync(crashPath, 'utf-8');\n const crash = JSON.parse(raw) as { error?: string };\n unlinkSync(crashPath);\n return crash.error ?? 'unknown error (crash log empty)';\n } catch {\n return 'daemon failed to start (crash log unreadable)';\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { resolveWorkerScript } from '../../dir-resolver/index.ts';\n\nimport type { Runtime } from '../../runtime/typings/runtime.ts';\n\n/**\n * Resolves the worker daemon script path from within\n * the worker-client module.\n */\nexport function resolveSpawnScript(runtime: Runtime): string {\n return resolveWorkerScript(resolveScriptDir(runtime), runtime);\n}\n\nfunction resolveScriptDir(runtime: Runtime): string {\n if (typeof __dirname !== 'undefined') return __dirname;\n const thisDir = dirname(fileURLToPath(import.meta.url));\n if (runtime === 'deno') {\n return resolve(thisDir, '..', '..', '..');\n }\n return thisDir;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { WorkerClient } from '../classes/worker-client.class.ts';\nimport { resolveDbPath } from './resolve-db-path.function.ts';\nimport { computeContextId } from './compute-context-id.function.ts';\nimport { discoverDaemon } from './discover-daemon.function.ts';\nimport { spawnDaemon } from './spawn-daemon.function.ts';\nimport { waitForDaemon } from './wait-for-daemon.function.ts';\nimport { readCrashReason } from './read-crash-reason.function.ts';\nimport { detectRuntime } from '../../runtime/functions/detect-runtime.ts';\nimport { resolveSpawnScript } from './resolve-spawn-script.function.ts';\nimport { getIpcPath } from '../../platform/functions/get-ipc-path.function.ts';\nimport type { WorkerClientOptions } from '../typings/worker-client-options.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Creates and connects a `WorkerClient` to the worker daemon.\n *\n * Resolves the context path, derives a stable context identifier,\n * and checks whether a daemon is already running. If no daemon is\n * found and `autoSpawn` is not `false`, a new daemon process is\n * spawned and the factory waits for its PID file to appear before\n * connecting.\n *\n * @param options - optional configuration for path resolution,\n * auto-spawn behaviour, and connection timeout\n * @returns a connected `WorkerClient` ready to send requests\n * @throws {Error} if the `.kbdb` directory cannot be found\n * @throws {Error} if the socket connection cannot be established\n */\nexport async function createWorkerClient(\n options?: WorkerClientOptions,\n): Promise<WorkerClient> {\n const dbPath =\n options?.contextPath ?? resolveDbPath(options?.dbPath);\n const contextId = await computeContextId(dbPath);\n log('create-worker-client: contextId=' + contextId, LogLevel.DEBUG);\n const socketPath = getIpcPath(contextId);\n\n let daemon = discoverDaemon(contextId);\n\n if (daemon) {\n log('daemon found: pid=' + daemon.pid.toString(), LogLevel.DEBUG);\n } else {\n log('no daemon found', LogLevel.DEBUG);\n }\n\n if (!daemon && options?.autoSpawn !== false) {\n const runtime = detectRuntime();\n log('auto-spawning daemon', LogLevel.DEBUG);\n const workerScript = resolveSpawnScript(runtime);\n spawnDaemon(dbPath, runtime, workerScript);\n log('waiting for daemon after spawn', LogLevel.DEBUG);\n await waitForDaemon(contextId, options?.connectTimeoutMs);\n daemon = discoverDaemon(contextId);\n }\n\n if (!daemon) {\n const msg = `kbdb worker daemon did not start: ${readCrashReason(contextId)}`;\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n\n log('connecting to daemon', LogLevel.DEBUG);\n const client = new WorkerClient(\n socketPath,\n contextId,\n options?.requestTimeoutMs,\n );\n await client.connect();\n return client;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport {\n computeContextId,\n discoverDaemon,\n} from '../../worker-client/index.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Stops the worker daemon for the resolved database path.\n *\n * Discovers the daemon via its PID file and sends `SIGTERM`.\n * Returns success when the daemon was stopped or was not running.\n *\n * @param dbDir - absolute path to the `.kbdb` directory\n * @returns command result indicating success or failure\n */\nexport async function runWorkerStop(\n dbDir: string,\n): Promise<CommandResult> {\n log('running worker-stop', LogLevel.DEBUG);\n const contextId = await computeContextId(dbDir);\n const info = discoverDaemon(contextId);\n if (!info) {\n return { output: 'no daemon running', exitCode: 0 };\n }\n log('pid found: ' + info.pid.toString(), LogLevel.DEBUG);\n try {\n process.kill(info.pid, 'SIGTERM');\n log('sigterm sent to pid=' + info.pid.toString(), LogLevel.DEBUG);\n } catch {\n return {\n error: 'error: failed to stop daemon',\n exitCode: 1,\n };\n }\n\n const deadline = Date.now() + 5_000;\n let pollIteration = 0;\n while (Date.now() < deadline) {\n try {\n process.kill(info.pid, 0);\n } catch {\n log(\n 'process exited: pid=' + info.pid.toString(),\n LogLevel.DEBUG,\n );\n break;\n }\n pollIteration++;\n if (pollIteration % 5 === 0) {\n log(\n 'waiting for exit: pid=' +\n info.pid.toString() +\n ' poll=' +\n pollIteration.toString(),\n LogLevel.DEBUG,\n );\n }\n await new Promise<void>((r) => setTimeout(r, 100));\n }\n\n if (Date.now() >= deadline) {\n log(\n 'timed out waiting for exit: pid=' + info.pid.toString(),\n LogLevel.DEBUG,\n );\n }\n\n return {\n output: `stopped daemon (pid ${info.pid.toString()})`,\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { runWorkerStop } from './run-worker-stop.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Restarts the worker daemon by stopping any running instance.\n *\n * The daemon auto-spawns on the next CLI command, so restart\n * only needs to stop the current instance.\n *\n * @param dbDir - absolute path to the `.kbdb` directory\n * @returns command result indicating success or failure\n */\nexport async function runWorkerRestart(\n dbDir: string,\n): Promise<CommandResult> {\n log('running worker-restart', LogLevel.DEBUG);\n const stopResult = await runWorkerStop(dbDir);\n if (stopResult.exitCode !== 0) return stopResult;\n return {\n output: 'daemon will restart on next command',\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Retries an operation when the daemon responds with\n * a `REQUEST_TIMEOUT` error. Each retry disconnects\n * the current client, creates a fresh one (which\n * auto-spawns the daemon), and re-runs the operation.\n *\n * @param createClient - factory that returns a connected client\n * @param operation - the work to perform with the client\n * @param maxRetries - maximum retry attempts\n * @returns the final client and result\n */\nexport async function retryOnTimeout<\n TClient extends {\n disconnect(): void;\n killDaemon?: () => void;\n },\n TResult,\n>(\n createClient: () => Promise<TClient>,\n operation: (client: TClient) => Promise<TResult>,\n maxRetries: number,\n): Promise<{ client: TClient; result: TResult }> {\n let lastError: Error = new Error('retryOnTimeout exhausted');\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n log(\n 'retry-on-timeout: attempt=' +\n attempt.toString() +\n ' max=' +\n maxRetries.toString(),\n LogLevel.DEBUG,\n );\n const client = await createClient();\n try {\n const result = await operation(client);\n log(\n 'retry-on-timeout: success on attempt=' +\n attempt.toString(),\n LogLevel.DEBUG,\n );\n return { client, result };\n } catch (err: unknown) {\n const code = (err as Record<string, unknown>).code;\n if (code !== 'REQUEST_TIMEOUT' || attempt >= maxRetries) {\n log(\n 'retry-on-timeout: non-retriable error code=' +\n String(code),\n LogLevel.DEBUG,\n );\n client.disconnect();\n throw err;\n }\n lastError = err as Error;\n if (client.killDaemon) {\n log(\n 'retry ' +\n String(attempt + 1) +\n '/' +\n String(maxRetries) +\n ': killing daemon',\n LogLevel.WARNING,\n );\n client.killDaemon();\n } else {\n client.disconnect();\n }\n }\n }\n log(\n 'retry-on-timeout: all retries exhausted max=' +\n maxRetries.toString(),\n LogLevel.DEBUG,\n );\n throw lastError;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Default per-request timeout for daemon IPC calls (ms). */\nexport const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Default number of retries on request timeout. */\nexport const DEFAULT_RETRY_COUNT = 5;\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { VERSION } from '../../version/index.ts';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { InitResult } from './run-init.function.ts';\nimport type { VersionStatus } from '../../worker-client/typings/version-status.model.ts';\nimport type { MigrateResult } from '../../worker-client/typings/migrate-result.model.ts';\nimport { parseArgs } from './parse-args.function.ts';\nimport { errorToMessage } from './error-to-message.function.ts';\nimport { dispatchCommand } from './dispatch-command.function.ts';\nimport type { DispatchClient } from './dispatch-command.function.ts';\nimport {\n generateHelp,\n isKnownCommand,\n} from './generate-help.function.ts';\nimport { runDbPath } from './run-db-path.function.ts';\nimport { runWorkerStop } from './run-worker-stop.function.ts';\nimport { runWorkerRestart } from './run-worker-restart.function.ts';\nimport { resolveDbDir } from './resolve-db-dir.function.ts';\nimport { formatDbNotFound } from './format-db-not-found.function.ts';\nimport { retryOnTimeout } from '../../worker-client/functions/retry-on-timeout.function.ts';\nimport { DEFAULT_REQUEST_TIMEOUT_MS } from '../../worker-client/constants/request-timeout.constant.ts';\nimport { DEFAULT_RETRY_COUNT } from '../../worker-client/constants/retry-defaults.constant.ts';\nimport { resolveLogLevel } from '../../log/functions/resolve-log-level.function.ts';\nimport { configureLog } from '../../log/functions/configure-log.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\nexport interface DisconnectableClient extends DispatchClient {\n checkVersion(targetPath: string): Promise<VersionStatus>;\n migrateDatabase(targetPath: string): Promise<MigrateResult>;\n disconnect(): void;\n}\n\n/**\n * Injectable dependencies for the CLI orchestrator.\n *\n * Every external side-effect is injected so the function\n * is fully testable without touching process globals,\n * filesystem, or network.\n */\nexport interface CliDeps {\n isStdinTty: () => boolean;\n isStdoutTty: () => boolean;\n promptUser: (question: string) => Promise<string>;\n createWorkerClient: (opts: {\n contextPath: string;\n requestTimeoutMs?: number;\n }) => Promise<DisconnectableClient>;\n findDb: (basePath?: string) => string | null;\n runInit: (options: CliOptions) => InitResult;\n startMcpServer?: (\n contextPath: string,\n clientFactory?: () => Promise<DisconnectableClient>,\n maxRetries?: number,\n ) => Promise<void>;\n}\n\n/**\n * Full CLI orchestrator extracted from `src/cli.ts`.\n *\n * Parses arguments, routes to the appropriate sub-flow\n * (help, version, init, mcp, migrate, data commands), and\n * returns a `CommandResult` without touching process globals.\n *\n * @param argv - raw CLI arguments (typically `process.argv.slice(2)`)\n * @param deps - injectable dependencies\n */\nexport async function runCli(\n argv: string[],\n deps: CliDeps,\n): Promise<CommandResult> {\n const options = parseArgs(argv);\n\n const logLevel = resolveLogLevel(options.logLevel);\n configureLog({ level: logLevel });\n log('command: ' + options.command, LogLevel.DEBUG);\n\n if (options.command === 'init') {\n log('--init is deprecated, use \"kbdb db init\"', LogLevel.WARNING);\n }\n if (options.command === 'migrate') {\n log(\n '--migrate is deprecated, use \"kbdb db migrate\"',\n LogLevel.WARNING,\n );\n }\n\n const nonInteractive =\n options.nonInteractive ||\n process.env['KBDB_NON_INTERACTIVE'] === '1' ||\n process.env['KBDB_NON_INTERACTIVE'] === 'true';\n const effectiveDeps: CliDeps = nonInteractive\n ? { ...deps, isStdinTty: () => false }\n : deps;\n\n if (options.command === 'help' || !options.command) {\n const helpCommand = options.args[0];\n const helpSubcommand = options.args[1];\n const helpText = generateHelp(helpCommand, helpSubcommand);\n if (helpCommand && !isKnownCommand(helpCommand)) {\n return { output: helpText, exitCode: 1 };\n }\n return { output: helpText, exitCode: 0 };\n }\n\n if (options.command === 'version') {\n return { output: VERSION, exitCode: 0 };\n }\n\n if (options.command === 'init' || options.command === 'db-init') {\n return handleInit(options, effectiveDeps);\n }\n\n if (options.command === 'db-path') {\n return runDbPath(options, effectiveDeps.findDb);\n }\n\n if (options.command === 'mcp') {\n return handleMcp(options, effectiveDeps);\n }\n\n if (\n options.command === 'migrate' ||\n options.command === 'db-migrate'\n ) {\n return handleMigrate(options, effectiveDeps);\n }\n\n if (options.command === 'worker-stop') {\n return handleWorkerLifecycle(\n options,\n effectiveDeps,\n runWorkerStop,\n );\n }\n\n if (options.command === 'worker-restart') {\n return handleWorkerLifecycle(\n options,\n effectiveDeps,\n runWorkerRestart,\n );\n }\n\n return handleDataCommand(options, effectiveDeps);\n}\n\nfunction handleInit(options: CliOptions, deps: CliDeps): CommandResult {\n const result = deps.runInit(options);\n if (result.ok) {\n return {\n output: result.targetPath,\n exitCode: 0,\n };\n }\n return {\n error: `error: ${result.errorMessage ?? 'init failed'}`,\n exitCode: 1,\n };\n}\n\nfunction resolveTimeoutMs(options: CliOptions): number {\n return (\n options.timeoutMs ??\n (parseInt(process.env['KBDB_DAEMON_TIMEOUT'] ?? '', 10) ||\n DEFAULT_REQUEST_TIMEOUT_MS)\n );\n}\n\nfunction resolveRetryCount(options: CliOptions): number {\n return (\n options.retry ??\n (parseInt(process.env['KBDB_RETRY'] ?? '', 10) ||\n DEFAULT_RETRY_COUNT)\n );\n}\n\nasync function handleMcp(\n options: CliOptions,\n deps: CliDeps,\n): Promise<CommandResult> {\n const resolution = resolveDbDir(\n { dbPath: options.dbPath, skipTraversal: true },\n deps.findDb,\n );\n if (!resolution) {\n return {\n error: formatDbNotFound({\n dbPath: options.dbPath,\n skipTraversal: true,\n }),\n exitCode: 1,\n };\n }\n const dbDir = resolution.path;\n\n const timeoutMs = resolveTimeoutMs(options);\n const maxRetries = resolveRetryCount(options);\n let client: DisconnectableClient;\n try {\n client = await deps.createWorkerClient({\n contextPath: dbDir,\n requestTimeoutMs: timeoutMs,\n });\n } catch (err) {\n return {\n error: `error: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n\n try {\n const gateResult = await versionGate(client, dbDir);\n if (gateResult) return gateResult;\n\n if (deps.startMcpServer) {\n await deps.startMcpServer(\n dbDir,\n () =>\n deps.createWorkerClient({\n contextPath: dbDir,\n requestTimeoutMs: timeoutMs,\n }),\n maxRetries,\n );\n }\n return { exitCode: 0 };\n } catch (err) {\n return {\n error: `error: mcp failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n } finally {\n client.disconnect();\n }\n}\n\nasync function handleMigrate(\n options: CliOptions,\n deps: CliDeps,\n): Promise<CommandResult> {\n const resolution = resolveDbDir(\n { dbPath: options.dbPath },\n deps.findDb,\n );\n if (!resolution) {\n return {\n error: formatDbNotFound({ dbPath: options.dbPath }),\n exitCode: 1,\n };\n }\n const dbDir = resolution.path;\n\n let client: DisconnectableClient;\n try {\n client = await deps.createWorkerClient({\n contextPath: dbDir,\n });\n } catch (err) {\n return {\n error: `error: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n\n try {\n const versionStatus = await client.checkVersion(dbDir);\n\n if (versionStatus.status === 'too_new') {\n return {\n error:\n `error: database version` +\n ` ${versionStatus.currentVersion.toString()}` +\n ` is newer than kbdb version` +\n ` ${versionStatus.requiredVersion.toString()}` +\n ` -- upgrade kbdb`,\n exitCode: 1,\n };\n }\n\n if (versionStatus.status === 'needs_migration') {\n const migrateResult = await client.migrateDatabase(dbDir);\n return {\n output: JSON.stringify(migrateResult, null, 2),\n exitCode: 0,\n };\n }\n\n return { output: 'already up to date', exitCode: 0 };\n } catch (err) {\n return {\n error: `error: migrate failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n } finally {\n client.disconnect();\n }\n}\n\nasync function handleDataCommand(\n options: CliOptions,\n deps: CliDeps,\n): Promise<CommandResult> {\n const resolution = resolveDbDir(\n { dbPath: options.dbPath },\n deps.findDb,\n );\n let dbDir = resolution?.path ?? null;\n\n if (!dbDir) {\n const basePath = options.dbPath ?? process.cwd();\n\n if (!deps.isStdinTty()) {\n return {\n error: formatDbNotFound({\n dbPath: options.dbPath,\n }),\n exitCode: 1,\n };\n }\n\n const answer = await deps.promptUser(\n `No .kbdb database found. Create one in ${basePath}? [y/N] `,\n );\n\n if (answer.toLowerCase() !== 'y') {\n return {\n error: 'aborted: no database created',\n exitCode: 1,\n };\n }\n\n const initResult = deps.runInit(options);\n if (!initResult.ok) {\n return {\n error: `error: ${initResult.errorMessage ?? 'init failed'}`,\n exitCode: 1,\n };\n }\n dbDir = initResult.targetPath;\n }\n\n log('db path: ' + dbDir, LogLevel.DEBUG);\n const timeoutMs = resolveTimeoutMs(options);\n const maxRetries = resolveRetryCount(options);\n\n try {\n const { client, result } = await retryOnTimeout(\n () =>\n deps.createWorkerClient({\n contextPath: dbDir,\n requestTimeoutMs: timeoutMs,\n }),\n async (c) => {\n const gateResult = await versionGate(c, dbDir);\n if (gateResult) return gateResult;\n return dispatchCommand(c, options);\n },\n maxRetries,\n );\n client.disconnect();\n return result;\n } catch (err) {\n return {\n error: `error: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleWorkerLifecycle(\n options: CliOptions,\n deps: CliDeps,\n action: (dbDir: string) => Promise<CommandResult>,\n): Promise<CommandResult> {\n const resolution = resolveDbDir(\n { dbPath: options.dbPath },\n deps.findDb,\n );\n if (!resolution) {\n return {\n error: formatDbNotFound({ dbPath: options.dbPath }),\n exitCode: 1,\n };\n }\n const dbDir = resolution.path;\n return action(dbDir);\n}\n\nasync function versionGate(\n client: DisconnectableClient,\n dbDir: string,\n): Promise<CommandResult | null> {\n const versionStatus = await client.checkVersion(dbDir);\n\n if (versionStatus.status === 'needs_migration') {\n return {\n error:\n 'error: database needs migration' +\n ' -- run `kbdb --migrate`',\n exitCode: 1,\n };\n }\n\n if (versionStatus.status === 'too_new') {\n return {\n error:\n `error: database version` +\n ` ${versionStatus.currentVersion.toString()}` +\n ` is newer than kbdb version` +\n ` ${versionStatus.requiredVersion.toString()}` +\n ` -- upgrade kbdb`,\n exitCode: 1,\n };\n }\n\n return null;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { generateHelp } from '../functions/generate-help.function.ts';\n\n/** Global help text for the kbdb CLI. */\nexport const HELP_TEXT = generateHelp();\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { createInterface } from 'node:readline';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { createToolDefinitions } from '../functions/create-tool-definitions.function.ts';\nimport { createResourceTemplates } from '../functions/create-resource-templates.function.ts';\nimport { handleToolCall } from '../functions/handle-tool-call.function.ts';\nimport { handleResourceRead } from '../functions/handle-resource-read.function.ts';\nimport { createPromptDefinitions } from '../functions/create-prompt-definitions.function.ts';\nimport { handlePromptGet } from '../functions/handle-prompt-get.function.ts';\nimport { handleCompletion } from '../functions/handle-completion.function.ts';\nimport { handleRootsList } from '../functions/handle-roots-list.function.ts';\nimport { shouldEmitLog } from '../functions/should-emit-log.function.ts';\nimport { runAutoCapture } from '../functions/run-auto-capture.function.ts';\nimport { AutoCaptureController } from '../../auto-capture/classes/auto-capture-controller.class.ts';\nimport {\n PARSE_ERROR,\n METHOD_NOT_FOUND,\n RESOURCE_NOT_FOUND,\n} from '../constants/mcp-error-codes.constant.ts';\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type {\n McpRequest,\n McpResponse,\n} from '../typings/mcp-types.interface.ts';\nimport type { McpLogLevel } from '../typings/log-types.interface.ts';\nimport type {\n McpCompletionRef,\n McpCompletionArgument,\n} from '../functions/handle-completion.function.ts';\nimport type { AutoCaptureConfig } from '../../auto-capture/typings/auto-capture-config.interface.ts';\nimport { VERSION } from '../../version/index.ts';\nimport { DEFAULT_RETRY_COUNT } from '../../worker-client/constants/retry-defaults.constant.ts';\n\n/**\n * MCP server that speaks JSON-RPC 2.0 over stdio. Listens for\n * newline-delimited requests on `process.stdin`, dispatches each\n * to the appropriate knowledge-base operation via\n * `McpWorkerClient`, and writes JSON-RPC responses to\n * `process.stdout`.\n */\nexport class McpServer {\n private client: McpWorkerClient;\n private readonly contextPath: string;\n private readonly autoCaptureConfig: AutoCaptureConfig | null;\n private readonly clientFactory:\n | (() => Promise<McpWorkerClient>)\n | null;\n private readonly maxRetries: number;\n private autoCaptureController: AutoCaptureController | null = null;\n private initialized = false;\n private hostCapabilities: Record<string, unknown> | null = null;\n private logLevel: McpLogLevel | null = null;\n private readonly subscriptions = new Set<string>();\n private nextRequestId = 1;\n private readonly pendingRequests = new Map<\n number,\n {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n timer: ReturnType<typeof setTimeout>;\n }\n >();\n\n /**\n * @param client - worker client providing knowledge-base operations\n * @param contextPath - absolute path to the `.kbdb` directory\n * @param autoCaptureConfig - optional auto-capture configuration;\n * when provided the server activates auto-capture on connection\n * @param clientFactory - creates a fresh worker client (for retry)\n * @param maxRetries - max retries on REQUEST_TIMEOUT\n */\n constructor(\n client: McpWorkerClient,\n contextPath?: string,\n autoCaptureConfig?: AutoCaptureConfig,\n clientFactory?: (() => Promise<McpWorkerClient>) | null,\n maxRetries?: number,\n ) {\n this.client = client;\n this.contextPath = contextPath ?? '';\n this.autoCaptureConfig = autoCaptureConfig ?? null;\n this.clientFactory = clientFactory ?? null;\n this.maxRetries = maxRetries ?? DEFAULT_RETRY_COUNT;\n }\n\n private async reconnectClient(): Promise<void> {\n if (!this.clientFactory) {\n log('no client factory for reconnect', LogLevel.ERROR);\n throw new Error('no client factory for reconnect');\n }\n this.client.disconnect();\n this.client = await this.clientFactory();\n log('MCP client reconnected', LogLevel.DEBUG);\n }\n\n private async withRetry<T>(fn: () => Promise<T>): Promise<T> {\n for (let attempt = 0; ; attempt++) {\n try {\n return await fn();\n } catch (err: unknown) {\n const code = (err as Record<string, unknown>).code;\n if (\n code !== 'REQUEST_TIMEOUT' ||\n attempt >= this.maxRetries ||\n !this.clientFactory\n ) {\n throw err;\n }\n log(\n 'request timeout, reconnecting (attempt ' +\n (attempt + 1).toString() +\n '/' +\n this.maxRetries.toString() +\n ')',\n LogLevel.WARNING,\n );\n await this.reconnectClient();\n }\n }\n }\n\n async listen(): Promise<void> {\n const rl = createInterface({\n input: process.stdin,\n terminal: false,\n });\n log('MCP server listening on stdin', LogLevel.DEBUG);\n\n let pending = Promise.resolve();\n await new Promise<void>((resolve) => {\n rl.on('line', (line) => {\n pending = pending.then(() => this.dispatchLine(line));\n });\n\n rl.on('close', () => {\n void pending.then(() => {\n this.autoCaptureController?.reset();\n this.autoCaptureController = null;\n this.client.disconnect();\n log('MCP stdin closed', LogLevel.DEBUG);\n resolve();\n });\n });\n });\n }\n\n async handleLineForTest(line: string): Promise<McpResponse | null> {\n return this.processLine(line);\n }\n\n /**\n * Sends a JSON-RPC notification (no `id`, no response\n * expected) to stdout.\n */\n notify(method: string, params?: Record<string, unknown>): void {\n const notification: Record<string, unknown> = {\n jsonrpc: '2.0',\n method,\n };\n if (params !== undefined) {\n notification['params'] = params;\n }\n process.stdout.write(JSON.stringify(notification) + '\\n');\n }\n\n /**\n * Emits a log notification if the message severity meets or\n * exceeds the configured log level threshold.\n */\n log(level: McpLogLevel, message: unknown, logger?: string): void {\n if (this.logLevel === null) return;\n if (!shouldEmitLog(level, this.logLevel)) return;\n this.notify('notifications/message', {\n level,\n logger: logger ?? 'kbdb',\n data: message,\n });\n }\n\n /**\n * Sends a JSON-RPC request to the host (server-to-client)\n * and returns a Promise that resolves with the response\n * result. Times out after 30 seconds.\n */\n sendRequest(\n method: string,\n params: Record<string, unknown>,\n ): Promise<unknown> {\n const id = this.nextRequestId++;\n const request = { jsonrpc: '2.0', id, method, params };\n process.stdout.write(JSON.stringify(request) + '\\n');\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Request ${method} timed out`));\n }, 30000);\n this.pendingRequests.set(id, {\n resolve,\n reject,\n timer,\n });\n });\n }\n\n /**\n * Requests the host to generate text via the sampling\n * capability. Throws if the host did not advertise sampling\n * support during initialization.\n */\n async requestSampling(\n messages: {\n role: string;\n content: { type: string; text: string };\n }[],\n maxTokens: number,\n ): Promise<unknown> {\n if (!this.hostCapabilities?.['sampling']) {\n log('Host does not support sampling', LogLevel.ERROR);\n throw new Error('Host does not support sampling');\n }\n return this.sendRequest('sampling/createMessage', {\n messages,\n maxTokens,\n });\n }\n\n private async dispatchLine(line: string): Promise<void> {\n const response = await this.processLine(line);\n if (response !== null) {\n this.send(response);\n }\n }\n\n private async processLine(\n line: string,\n ): Promise<McpResponse | null> {\n if (!line.trim()) return null;\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(line) as Record<string, unknown>;\n } catch {\n return {\n jsonrpc: '2.0',\n id: 0,\n error: {\n code: PARSE_ERROR,\n message: 'Parse error',\n },\n };\n }\n\n // Incoming response to an outgoing request (sampling)\n if (\n parsed['id'] !== undefined &&\n typeof parsed['method'] !== 'string'\n ) {\n const responseId = parsed['id'] as number;\n const pending = this.pendingRequests.get(responseId);\n if (pending) {\n this.pendingRequests.delete(responseId);\n clearTimeout(pending.timer);\n if (parsed['error']) {\n const err = parsed['error'] as {\n message?: string;\n };\n pending.reject(\n new Error(err.message ?? 'Request failed'),\n );\n } else {\n pending.resolve(parsed['result']);\n }\n }\n return null;\n }\n\n const request = parsed as unknown as McpRequest;\n log('MCP request: ' + request.method, LogLevel.DEBUG);\n\n if (request.id === undefined) {\n if (\n request.method === 'notifications/initialized' ||\n request.method === 'notifications/cancelled'\n ) {\n if (\n request.method === 'notifications/initialized' &&\n !this.initialized\n ) {\n this.initialized = true;\n log('MCP initialized', LogLevel.INFO);\n if (this.autoCaptureConfig !== null) {\n this.autoCaptureController =\n new AutoCaptureController(this.autoCaptureConfig);\n }\n void this.runStartupHealthCheck();\n }\n }\n return null;\n }\n\n const id = request.id;\n\n if (\n !this.initialized &&\n request.method !== 'initialize' &&\n request.method !== 'ping'\n ) {\n return {\n jsonrpc: '2.0',\n id,\n error: {\n code: RESOURCE_NOT_FOUND,\n message: 'Server not initialized',\n },\n };\n }\n\n const response = await this.handleRequest(request);\n return response;\n }\n\n private async handleRequest(\n request: McpRequest,\n ): Promise<McpResponse> {\n const id = request.id as number | string;\n\n switch (request.method) {\n case 'initialize': {\n const params = request.params ?? {};\n const caps = params['capabilities'];\n this.hostCapabilities = caps\n ? (caps as Record<string, unknown>)\n : null;\n return {\n jsonrpc: '2.0',\n id,\n result: {\n protocolVersion: '2025-11-25',\n serverInfo: {\n name: 'kbdb',\n version: VERSION,\n },\n capabilities: {\n tools: {},\n resources: { subscribe: true },\n prompts: {},\n logging: {},\n completions: {},\n },\n },\n };\n }\n\n case 'ping':\n return { jsonrpc: '2.0', id, result: {} };\n\n case 'tools/list':\n return {\n jsonrpc: '2.0',\n id,\n result: {\n tools: createToolDefinitions(),\n },\n };\n\n case 'resources/list':\n return {\n jsonrpc: '2.0',\n id,\n result: { resources: [] },\n };\n\n case 'resources/templates/list':\n return {\n jsonrpc: '2.0',\n id,\n result: {\n resourceTemplates: createResourceTemplates(),\n },\n };\n\n case 'tools/call': {\n const params = request.params ?? {};\n const rawName = params['name'];\n const name = typeof rawName === 'string' ? rawName : '';\n const args = (params['arguments'] ?? {}) as Record<\n string,\n unknown\n >;\n const result = await this.withRetry(() =>\n handleToolCall(this.client, name, args),\n );\n this.afterToolCall();\n return { jsonrpc: '2.0', id, result };\n }\n\n case 'resources/read': {\n const params = request.params ?? {};\n const rawUri = params['uri'];\n const uri = typeof rawUri === 'string' ? rawUri : '';\n try {\n const result = await this.withRetry(() =>\n handleResourceRead(this.client, uri),\n );\n return { jsonrpc: '2.0', id, result };\n } catch (err) {\n return {\n jsonrpc: '2.0',\n id,\n error: {\n code: RESOURCE_NOT_FOUND,\n message:\n err instanceof Error\n ? err.message\n : String(err),\n },\n };\n }\n }\n\n case 'prompts/list': {\n const skills = await this.client.listByType('skill');\n const agents =\n await this.client.listDocumentsByType('agent');\n const prompts = createPromptDefinitions(skills, agents);\n return {\n jsonrpc: '2.0',\n id,\n result: { prompts },\n };\n }\n\n case 'prompts/get': {\n const params = request.params ?? {};\n const name =\n typeof params['name'] === 'string' ? params['name'] : '';\n const promptArgs = (params['arguments'] ?? {}) as Record<\n string,\n string\n >;\n try {\n const messages = await handlePromptGet(\n name,\n promptArgs,\n this.client,\n );\n return {\n jsonrpc: '2.0',\n id,\n result: { messages },\n };\n } catch (err) {\n return {\n jsonrpc: '2.0',\n id,\n error: {\n code: RESOURCE_NOT_FOUND,\n message:\n err instanceof Error\n ? err.message\n : String(err),\n },\n };\n }\n }\n\n case 'completion/complete': {\n const params = request.params ?? {};\n const ref = params['ref'] as McpCompletionRef;\n const argument = (params['argument'] ?? {\n name: '',\n value: '',\n }) as McpCompletionArgument;\n const result = await handleCompletion(\n ref,\n argument,\n this.client,\n );\n return { jsonrpc: '2.0', id, result };\n }\n\n case 'roots/list': {\n const roots = handleRootsList(this.contextPath);\n return {\n jsonrpc: '2.0',\n id,\n result: { roots },\n };\n }\n\n case 'logging/setLevel': {\n const params = request.params ?? {};\n const level = params['level'] as McpLogLevel | undefined;\n this.logLevel = level ?? null;\n return { jsonrpc: '2.0', id, result: {} };\n }\n\n case 'resources/subscribe': {\n const params = request.params ?? {};\n const uri =\n typeof params['uri'] === 'string' ? params['uri'] : '';\n this.subscriptions.add(uri);\n return { jsonrpc: '2.0', id, result: {} };\n }\n\n case 'resources/unsubscribe': {\n const params = request.params ?? {};\n const uri =\n typeof params['uri'] === 'string' ? params['uri'] : '';\n this.subscriptions.delete(uri);\n return { jsonrpc: '2.0', id, result: {} };\n }\n\n default:\n return {\n jsonrpc: '2.0',\n id,\n error: {\n code: METHOD_NOT_FOUND,\n message: `Method not found: ` + request.method,\n },\n };\n }\n }\n\n private send(response: McpResponse): void {\n const json = JSON.stringify(response);\n process.stdout.write(json + '\\n');\n }\n\n /**\n * Records a tool call in the auto-capture controller and fires\n * a capture when the trigger condition is met.\n */\n private afterToolCall(): void {\n const ctrl = this.autoCaptureController;\n const cfg = this.autoCaptureConfig;\n if (ctrl === null || cfg === null) return;\n ctrl.recordToolCall();\n void runAutoCapture(\n ctrl,\n cfg,\n this.client,\n this.hostCapabilities,\n (messages, maxTokens) =>\n this.requestSampling(messages, maxTokens),\n );\n }\n\n /**\n * Runs an integrity check immediately after the MCP handshake\n * completes. Emits a `notifications/message` warning when the\n * check detects issues so the connected agent is aware before\n * making requests. The server continues operating regardless of\n * the result.\n */\n private async runStartupHealthCheck(): Promise<void> {\n try {\n const report = await this.client.integrityCheck();\n if (!report.ok) {\n const summary = report.errors\n .map((e) => `${e.type}: ${e.entity} -- ${e.detail}`)\n .join('; ');\n this.notify('notifications/message', {\n level: 'warning',\n logger: 'kbdb',\n data: `Database integrity issues detected: ${summary}`,\n });\n }\n } catch {\n // Health check failure is non-fatal -- server continues\n }\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpToolDefinition } from '../typings/mcp-types.interface.ts';\n\n/**\n * Returns the full list of MCP tool definitions exposed by the\n * knowledge-base server. Each definition includes the tool name,\n * a human-readable description, and a JSON Schema for its inputs.\n */\nexport function createToolDefinitions(): McpToolDefinition[] {\n return [\n {\n name: 'search',\n description:\n 'Query the knowledge base by keywords.' +\n ' Returns ranked results with heading,' +\n ' snippet, and matched terms. Use multiple' +\n ' short keyword queries for best coverage.' +\n ' Use recall to get full content.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Search query text',\n },\n mode: {\n type: 'string',\n enum: ['sections', 'documents', 'stats'],\n description: 'Search mode (default: sections)',\n },\n limit: {\n type: 'number',\n description: 'Maximum results (default: 20)',\n },\n offset: {\n type: 'number',\n description:\n 'Number of results to skip for' +\n ' pagination (default: 0)',\n },\n algo: {\n type: 'string',\n enum: ['lexical', 'vector', 'hybrid'],\n description: 'Search algorithm (default: lexical)',\n },\n relaxed: {\n type: 'boolean',\n description:\n 'Use relaxed (OR) matching when the' +\n ' strict query returns no results',\n },\n },\n required: ['query'],\n },\n annotations: {\n title: 'Search KB',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'learn',\n description:\n 'Import content into the knowledge base.' +\n ' Use for durable facts, decisions, and' +\n ' corrections. Use replace when updating' +\n ' existing knowledge. Attach tags for scoping.',\n inputSchema: {\n type: 'object',\n properties: {\n content: {\n type: 'string',\n description: 'Text content to add',\n },\n type: {\n type: 'string',\n description:\n 'MIME type (default: text/markdown).' +\n ' Use image/* for images.',\n },\n title: {\n type: 'string',\n description:\n 'Section title.' + ' Required for image/* types.',\n },\n description: {\n type: 'string',\n description: 'Optional section description',\n },\n docid: {\n type: 'string',\n description: 'Document ID to group under',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Tags for scoping and filtering',\n },\n replace: {\n type: 'boolean',\n description:\n 'Replace existing section with same' +\n ' source key (supersession)',\n },\n },\n required: ['content'],\n },\n annotations: {\n title: 'Import Content',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'unlearn',\n description:\n 'Remove a section from the knowledge base' +\n ' by its kb-id.',\n inputSchema: {\n type: 'object',\n properties: {\n kbid: {\n type: 'string',\n description: 'Knowledge base ID of the section',\n },\n },\n required: ['kbid'],\n },\n annotations: {\n title: 'Remove Section',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'retrieve',\n description:\n 'Low-level fetch of a section or document' +\n ' by identifier. For AI agent workflows,' +\n ' prefer `recall` which includes metadata,' +\n ' context, and back-references.',\n inputSchema: {\n type: 'object',\n properties: {\n kbid: {\n type: 'string',\n description: 'Section kb-id',\n },\n docid: {\n type: 'string',\n description: 'Document ID',\n },\n },\n },\n annotations: {\n title: 'Fetch Content',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'recall',\n description:\n 'Retrieve full content and context for sections' +\n ' by identifier. Use after search to read relevant' +\n ' results. Returns section text, metadata,' +\n ' references, and back-references.',\n inputSchema: {\n type: 'object',\n properties: {\n kbid: {\n type: 'string',\n description: 'Single section identifier',\n },\n kbids: {\n type: 'array',\n items: { type: 'string' },\n description: 'Batch section identifiers',\n },\n depth: {\n type: 'number',\n description: 'Expansion depth (0-3, default: 0)',\n },\n },\n },\n annotations: {\n title: 'Recall Context',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'status',\n description:\n 'Get database metadata including document count,' +\n ' section count, index size, and cache statistics.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'DB Status',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'content',\n description:\n 'Compose a rendered Markdown document from one or' +\n ' more kbid or docid identifiers.',\n inputSchema: {\n type: 'object',\n properties: {\n ids: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'One or more kbid or docid identifiers' +\n ' (may be mixed)',\n },\n },\n required: ['ids'],\n },\n annotations: {\n title: 'Compose Content',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'check',\n description:\n 'Verify the integrity of the knowledge base.' +\n ' Reports checksum mismatches, orphan sections,' +\n ' broken references, and circular reference chains.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'Integrity Check',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'gc',\n description:\n 'Remove unreferenced sections from the knowledge' +\n ' base. A section is eligible when no document' +\n ' manifest references it.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'Garbage Collect',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n {\n name: 'rebuild',\n description:\n 'Reconstruct all index files from section files' +\n ' and document manifests on disk. Use this to' +\n ' recover from index corruption.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'Rebuild Indexes',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n {\n name: 'export',\n description:\n 'Export the database as a self-contained' +\n ' directory snapshot (sections, documents,' +\n ' catalog -- no indexes).',\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description:\n 'Export destination path' +\n ' (default: ./kbdb-export/)',\n },\n },\n },\n annotations: {\n title: 'Export Snapshot',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'skill-learn',\n description:\n 'Create or update a skill definition.' +\n ' Skills are reusable AI agent capabilities' +\n ' with template placeholders.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Skill name',\n },\n description: {\n type: 'string',\n description: 'Skill description',\n },\n body: {\n type: 'string',\n description:\n 'Skill body template.' +\n ' Use {{argName}} for placeholders.',\n },\n },\n required: ['name', 'body'],\n },\n annotations: {\n title: 'Create Skill',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'skill-list',\n description: 'List all skills in the knowledge base.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'List Skills',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'skill-get',\n description: 'Get a skill definition by name or kbid.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Skill name',\n },\n kbid: {\n type: 'string',\n description: 'Knowledge base ID',\n },\n },\n },\n annotations: {\n title: 'Get Skill',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'skill-delete',\n description: 'Delete a skill by its kbid.',\n inputSchema: {\n type: 'object',\n properties: {\n kbid: {\n type: 'string',\n description: 'Knowledge base ID',\n },\n },\n required: ['kbid'],\n },\n annotations: {\n title: 'Delete Skill',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'agent-create',\n description:\n 'Create an AI agent with a persona and' +\n ' optional skill references.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Agent name',\n },\n description: {\n type: 'string',\n description: 'Agent description',\n },\n persona: {\n type: 'string',\n description: 'Agent persona prompt',\n },\n skills: {\n type: 'array',\n items: { type: 'string' },\n description: 'Skill kbid references to attach',\n },\n },\n required: ['name', 'persona'],\n },\n annotations: {\n title: 'Create Agent',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'agent-list',\n description: 'List all agents in the knowledge base.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'List Agents',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'agent-get',\n description: 'Get an agent definition by document ID.',\n inputSchema: {\n type: 'object',\n properties: {\n docid: {\n type: 'string',\n description: 'Document ID of the agent',\n },\n },\n required: ['docid'],\n },\n annotations: {\n title: 'Get Agent',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'agent-delete',\n description:\n 'Delete an agent by its document ID.' +\n ' Skill sections are not removed.',\n inputSchema: {\n type: 'object',\n properties: {\n docid: {\n type: 'string',\n description: 'Document ID of the agent',\n },\n },\n required: ['docid'],\n },\n annotations: {\n title: 'Delete Agent',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'auto-capture-review',\n description:\n 'Review and approve pending auto-captured' +\n ' knowledge before storage.',\n inputSchema: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'approve', 'reject'],\n description: 'Action to perform on pending captures',\n },\n },\n },\n annotations: {\n title: 'Auto-Capture Review',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n ];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpResourceTemplate } from '../typings/mcp-types.interface.ts';\n\n/**\n * Returns the list of MCP resource URI templates served by the\n * knowledge-base server. Each template describes the URI pattern,\n * human-readable metadata, and the MIME type of the resource body.\n */\nexport function createResourceTemplates(): McpResourceTemplate[] {\n return [\n {\n uriTemplate: 'kbdb://section/{kb_id}',\n name: 'Section',\n description: 'A knowledge base section by its kb-id.',\n mimeType: 'text/plain',\n },\n {\n uriTemplate: 'kbdb://document/{doc_id}',\n name: 'Document',\n description: 'A document with its ordered sections.',\n mimeType: 'application/json',\n },\n ];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically `'text'`. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by the agent-create tool handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/**\n * Narrows an `unknown` value to a string, returning the fallback\n * when the value is not already a string.\n */\nfunction asString(value: unknown, fallback: string): string {\n return typeof value === 'string' ? value : fallback;\n}\n\n/**\n * Narrows an `unknown` value to a `string[]`, returning an empty\n * array when the value is not an array of strings.\n */\nfunction asStringArray(value: unknown): string[] {\n if (\n Array.isArray(value) &&\n value.every((item) => typeof item === 'string')\n ) {\n return value;\n }\n return [];\n}\n\n/**\n * Handles the `agent:create` MCP tool call.\n *\n * Validates required arguments, verifies that referenced skill kbids\n * exist, stores agent metadata as a JSON section, groups all sections\n * into a single document, and returns the resulting document\n * identifier.\n *\n * @param client - the worker client used to execute operations\n * @param args - tool arguments from the MCP request\n * @returns content items with optional `isError` flag\n */\nexport async function handleAgentCreate(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const name = asString(args['name'], '');\n const description = asString(args['description'], '');\n const persona = asString(args['persona'], '');\n const skills = asStringArray(args['skills']);\n\n if (!name) {\n return {\n content: [{ type: 'text', text: 'name is required' }],\n isError: true,\n };\n }\n if (!persona) {\n return {\n content: [{ type: 'text', text: 'persona is required' }],\n isError: true,\n };\n }\n\n if (skills.length > 0) {\n const sections = await client.readSections(skills);\n const found = new Set(sections.map((s) => s.kbid));\n const missing = skills.filter((k) => !found.has(k));\n if (missing.length > 0) {\n return {\n content: [\n {\n type: 'text',\n text: `skill not found: ${missing.join(', ')}`,\n },\n ],\n isError: true,\n };\n }\n }\n\n const metadata = JSON.stringify({ name, description, persona });\n\n const metaResult = await client.addSection({\n sectionType: 'text',\n content: metadata,\n title: name,\n description,\n });\n\n const allKbids = [metaResult.kbid, ...skills];\n const docid = await client.groupSections(name, allKbids, 'agent');\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n docid,\n name,\n skillCount: skills.length,\n }),\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically `'text'`. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by the agent-list tool handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/**\n * Handles the `agent:list` MCP tool call.\n *\n * Retrieves all documents with `doc_type: 'agent'` and returns a\n * summary list containing each agent's document identifier, name,\n * and skill count.\n *\n * The `skillCount` is `Math.max(0, sections.length - 1)` because\n * the first section of an agent document always holds the metadata\n * JSON and does not count as a skill reference.\n *\n * @param client - the worker client used to execute operations\n * @returns content items with the serialised agent list\n */\nexport async function handleAgentList(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const docs = await client.listDocumentsByType('agent');\n const items = docs.map((d) => ({\n docid: d.docid,\n name: d.title,\n skillCount: Math.max(0, d.sections.length - 1),\n }));\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(items, null, 2),\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type { AgentDefinition } from '../typings/agent-types.interface.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically `'text'`. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by the agent-get tool handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/** Parsed shape of an agent document section list entry. */\ninterface DocumentSection {\n /** Knowledge-base identifier of the section. */\n readonly kbid: string;\n /** Zero-based position of the section within the document. */\n readonly position: number;\n}\n\n/** Parsed shape of a retrieved agent document. */\ninterface AgentDocument {\n /** Document identifier. */\n readonly docid: string;\n /** Document title used as agent name fallback. */\n readonly title: string;\n /** Ordered list of sections in the document. */\n readonly sections: DocumentSection[];\n}\n\n/**\n * Reads the metadata JSON stored in the first section of an agent\n * document and extracts `name`, `description`, and `persona`.\n */\nasync function readAgentMeta(\n client: McpWorkerClient,\n metaKbid: string,\n fallbackName: string,\n): Promise<{ name: string; description: string; persona: string }> {\n const metaSections = await client.readSections([metaKbid]);\n const first = metaSections.at(0);\n if (!first) {\n return { name: fallbackName, description: '', persona: '' };\n }\n try {\n const meta = JSON.parse(first.content) as Record<string, unknown>;\n return {\n name:\n typeof meta['name'] === 'string'\n ? meta['name']\n : fallbackName,\n description:\n typeof meta['description'] === 'string'\n ? meta['description']\n : '',\n persona:\n typeof meta['persona'] === 'string' ? meta['persona'] : '',\n };\n } catch {\n return { name: fallbackName, description: '', persona: '' };\n }\n}\n\n/**\n * Resolves skill names for a list of section references by reading\n * each section's JSON content and extracting the `name` field.\n * Returns `null` for skill references where the section no longer\n * exists (dangling references).\n */\nasync function resolveSkillRefs(\n client: McpWorkerClient,\n skillRefs: DocumentSection[],\n): Promise<{ kbid: string; name: string | null; position: number }[]> {\n if (skillRefs.length === 0) {\n return [];\n }\n const skillKbids = skillRefs.map((s) => s.kbid);\n const skillSections = await client.readSections(skillKbids);\n const sectionMap = new Map(skillSections.map((s) => [s.kbid, s]));\n return skillRefs.map((ref) => {\n const sec = sectionMap.get(ref.kbid);\n if (!sec) {\n return { kbid: ref.kbid, name: null, position: ref.position };\n }\n try {\n const parsed = JSON.parse(sec.content) as Record<\n string,\n unknown\n >;\n const skillName =\n typeof parsed['name'] === 'string' ? parsed['name'] : null;\n return {\n kbid: ref.kbid,\n name: skillName,\n position: ref.position,\n };\n } catch {\n return { kbid: ref.kbid, name: null, position: ref.position };\n }\n });\n}\n\n/**\n * Handles the `agent:get` MCP tool call.\n *\n * Retrieves an agent document by its `docid`, reads the metadata\n * section and skill references, and returns a full `AgentDefinition`.\n * Dangling skill references (sections that no longer exist) appear\n * with `name: null` in the skills list.\n *\n * @param client - the worker client used to execute operations\n * @param args - tool arguments; must include a `docid` string\n * @returns content items containing the serialised `AgentDefinition`\n */\nexport async function handleAgentGet(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const docid = typeof args['docid'] === 'string' ? args['docid'] : '';\n if (!docid) {\n return {\n content: [{ type: 'text', text: 'docid is required' }],\n isError: true,\n };\n }\n\n const doc = (await client.retrieveDocument(docid)) as AgentDocument;\n const metaKbid = doc.sections[0]?.kbid;\n const skillRefs = doc.sections.slice(1);\n\n const { name, description, persona } = metaKbid\n ? await readAgentMeta(client, metaKbid, doc.title)\n : { name: doc.title, description: '', persona: '' };\n\n const skills = await resolveSkillRefs(client, skillRefs);\n\n const agent: AgentDefinition = {\n docid,\n name,\n description,\n persona,\n skills,\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(agent, null, 2),\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically `'text'`. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by the agent-delete tool handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/**\n * Handles the `agent:delete` MCP tool call.\n *\n * Removes the document grouping identified by `docid`. The skill\n * sections referenced by the agent are not deleted; only the grouping\n * record is removed.\n *\n * @param client - the worker client used to execute operations\n * @param args - tool arguments; must include a `docid` string\n * @returns content items confirming removal, or an error item\n */\nexport async function handleAgentDelete(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const docid = typeof args['docid'] === 'string' ? args['docid'] : '';\n if (!docid) {\n return {\n content: [{ type: 'text', text: 'docid is required' }],\n isError: true,\n };\n }\n await client.removeGrouping(docid);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ docid, removed: true }),\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically `'text'`. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by a tool call handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/**\n * Handles the MCP `recall` tool call.\n *\n * Retrieves full content and context for one or more knowledge-base\n * sections by identifier. At least one of `kbid` or `kbids` must be\n * present in `args`; omitting both returns an error result.\n *\n * @param client - the worker client used to execute the operation\n * @param args - tool arguments from the MCP request\n * @returns content with JSON-stringified recall result, or an error\n * content item when required arguments are missing\n */\nexport async function handleRecall(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const kbid =\n typeof args['kbid'] === 'string' ? args['kbid'] : undefined;\n const kbids =\n Array.isArray(args['kbids']) &&\n args['kbids'].every((item: unknown) => typeof item === 'string')\n ? args['kbids']\n : undefined;\n\n if (!kbid && !kbids) {\n return {\n content: [\n {\n type: 'text',\n text: 'Provide kbid or kbids',\n },\n ],\n isError: true,\n };\n }\n\n const depth = typeof args['depth'] === 'number' ? args['depth'] : 0;\n\n const result = await client.recall({ kbid, kbids, depth });\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result, null, 2),\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { extractSkillArguments } from './extract-skill-arguments.function.ts';\nimport { parseSkillContent } from './parse-skill-content.function.ts';\nimport { serializeSkillContent } from './serialize-skill-content.function.ts';\nimport { handleAgentCreate } from './handle-agent-create.function.ts';\nimport { handleAgentList } from './handle-agent-list.function.ts';\nimport { handleAgentGet } from './handle-agent-get.function.ts';\nimport { handleAgentDelete } from './handle-agent-delete.function.ts';\nimport { handleRecall } from './handle-recall.function.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically 'text'. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by a tool call handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/**\n * Narrows an `unknown` value to a string, returning the fallback\n * when the value is not already a string.\n */\nfunction asString(value: unknown, fallback: string): string {\n return typeof value === 'string' ? value : fallback;\n}\n\n/**\n * Narrows an `unknown` value to a boolean, returning `undefined`\n * when the value is not a boolean.\n */\nfunction asBooleanOrUndefined(value: unknown): boolean | undefined {\n return typeof value === 'boolean' ? value : undefined;\n}\n\n/**\n * Narrows an `unknown` value to a `string[]`, returning `undefined`\n * when the value is not an array of strings.\n */\nfunction asStringArrayOrUndefined(\n value: unknown,\n): string[] | undefined {\n if (\n Array.isArray(value) &&\n value.every((item) => typeof item === 'string')\n ) {\n return value;\n }\n return undefined;\n}\n\n/**\n * Narrows an `unknown` value to a `string[]`, returning an empty\n * array when the value is not an array of strings.\n */\nfunction asStringArray(value: unknown): string[] {\n if (\n Array.isArray(value) &&\n value.every((item) => typeof item === 'string')\n ) {\n return value;\n }\n return [];\n}\n\n/**\n * Dispatches an MCP tool call to the appropriate knowledge-base\n * operation and returns the result formatted as MCP content.\n *\n * @param client - the worker client used to execute operations\n * @param name - the tool name to invoke\n * @param args - tool arguments from the MCP request\n * @returns content items with optional isError flag\n */\nexport async function handleToolCall(\n client: McpWorkerClient,\n name: string,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n log('tool call: ' + name, LogLevel.DEBUG);\n try {\n switch (name) {\n case 'search':\n return await handleSearch(client, args);\n case 'learn':\n return await handleLearn(client, args);\n case 'unlearn':\n return await handleUnlearn(client, args);\n case 'retrieve':\n return await handleRetrieve(client, args);\n case 'recall':\n return await handleRecall(client, args);\n case 'status':\n return await handleStatus(client);\n case 'content':\n return await handleContent(client, args);\n case 'check':\n return await handleCheck(client);\n case 'gc':\n return await handleGc(client);\n case 'rebuild':\n return await handleRebuild(client);\n case 'export':\n return await handleExport(client, args);\n case 'skill-learn':\n return await handleSkillLearn(client, args);\n case 'skill-list':\n return await handleSkillList(client);\n case 'skill-get':\n return await handleSkillGet(client, args);\n case 'skill-delete':\n return await handleSkillDelete(client, args);\n case 'agent-create':\n return await handleAgentCreate(client, args);\n case 'agent-list':\n return await handleAgentList(client);\n case 'agent-get':\n return await handleAgentGet(client, args);\n case 'agent-delete':\n return await handleAgentDelete(client, args);\n case 'auto-capture-review':\n return handleAutoCaptureReview();\n default:\n log('unknown tool: ' + name, LogLevel.WARNING);\n return {\n content: [\n {\n type: 'text',\n text: `Unknown tool: ${name}`,\n },\n ],\n isError: true,\n };\n }\n } catch (err) {\n log(\n 'tool call failed: ' +\n name +\n ': ' +\n (err instanceof Error ? err.message : String(err)),\n LogLevel.ERROR,\n );\n return {\n content: [\n {\n type: 'text',\n text: err instanceof Error ? err.message : String(err),\n },\n ],\n isError: true,\n };\n }\n}\n\nasync function handleSearch(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const results = await client.search({\n query: asString(args['query'], ''),\n mode: args['mode'] as string | undefined,\n limit: args['limit'] as number | undefined,\n offset: args['offset'] as number | undefined,\n algo: args['algo'] as string | undefined,\n relaxed: args['relaxed'] as boolean | undefined,\n });\n\n const stripped = {\n ...results,\n items: results.items.map(\n ({\n score: _score,\n confidence: _confidence,\n ...rest\n }: (typeof results.items)[number] & {\n confidence?: number;\n }) => rest,\n ),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(stripped, null, 2),\n },\n ],\n };\n}\n\nasync function handleLearn(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const sectionType = asString(args['type'], 'text/markdown');\n const title =\n typeof args['title'] === 'string' ? args['title'] : undefined;\n const description =\n typeof args['description'] === 'string'\n ? args['description']\n : undefined;\n const docid =\n typeof args['docid'] === 'string' ? args['docid'] : undefined;\n const tags = asStringArrayOrUndefined(args['tags']);\n const replace = asBooleanOrUndefined(args['replace']);\n if (sectionType.startsWith('image/') && !title) {\n return {\n content: [\n {\n type: 'text',\n text: 'title is required for image/* types',\n },\n ],\n isError: true,\n };\n }\n const result = await client.addSection({\n sectionType,\n content: asString(args['content'], ''),\n title,\n description,\n docid,\n tags,\n replace,\n });\n const normalized = {\n kbid: result.kbid,\n indexed_terms_count: result.indexed_terms_count ?? 0,\n elapsed_ms: result.elapsed_ms ?? 0,\n superseded: result.superseded ?? null,\n warnings: result.warnings ?? [],\n near_duplicates: (result.near_duplicates ?? []).map((d) => ({\n kbid: d.kbid,\n similarity: d.similarity,\n ...(d.method !== undefined ? { method: d.method } : {}),\n })),\n };\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(normalized),\n },\n ],\n };\n}\n\nasync function handleUnlearn(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const result = await client.removeSection(\n asString(args['kbid'], ''),\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result),\n },\n ],\n };\n}\n\nasync function handleRetrieve(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n if (typeof args['kbid'] === 'string') {\n const sections = await client.readSections([args['kbid']]);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(sections, null, 2),\n },\n ],\n };\n }\n if (typeof args['docid'] === 'string') {\n const doc = await client.retrieveDocument(args['docid']);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(doc, null, 2),\n },\n ],\n };\n }\n return {\n content: [\n {\n type: 'text',\n text: 'Provide kbid or docid',\n },\n ],\n isError: true,\n };\n}\n\nasync function handleStatus(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const status = await client.dbStatus();\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(status, null, 2),\n },\n ],\n };\n}\n\nasync function handleContent(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const ids = asStringArray(args['ids']);\n const result = await client.content(ids);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result),\n },\n ],\n };\n}\n\nasync function handleCheck(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const report = await client.integrityCheck();\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(report, null, 2),\n },\n ],\n };\n}\n\nasync function handleGc(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const report = await client.gc();\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(report, null, 2),\n },\n ],\n };\n}\n\nasync function handleRebuild(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const report = await client.rebuildIndexes();\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(report, null, 2),\n },\n ],\n };\n}\n\nasync function handleSkillLearn(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const name = asString(args['name'], '');\n if (!name) {\n return {\n content: [{ type: 'text', text: 'name is required' }],\n isError: true,\n };\n }\n const body = asString(args['body'], '');\n if (!body) {\n return {\n content: [{ type: 'text', text: 'body is required' }],\n isError: true,\n };\n }\n const description =\n typeof args['description'] === 'string'\n ? args['description']\n : undefined;\n const skillArgs = extractSkillArguments(body);\n const skill = {\n name,\n description,\n arguments: skillArgs.length > 0 ? skillArgs : undefined,\n body,\n };\n const json = serializeSkillContent(skill);\n const result = await client.addSection({\n sectionType: 'skill',\n content: json,\n title: name,\n description,\n });\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ kbid: result.kbid, name }),\n },\n ],\n };\n}\n\nasync function handleSkillList(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const records = await client.listByType('skill');\n const items = records.map((r) => {\n let argumentCount = 0;\n try {\n const parsed = JSON.parse(r.content) as Record<\n string,\n unknown\n >;\n if (Array.isArray(parsed['arguments'])) {\n argumentCount = parsed['arguments'].length;\n }\n } catch {\n // ignore parse errors\n }\n return {\n kbid: r.kbid,\n name: r.title,\n description: r.description,\n argumentCount,\n };\n });\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(items, null, 2),\n },\n ],\n };\n}\n\nasync function handleSkillGet(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const kbid =\n typeof args['kbid'] === 'string' ? args['kbid'] : undefined;\n const name =\n typeof args['name'] === 'string' ? args['name'] : undefined;\n if (!kbid && !name) {\n return {\n content: [\n {\n type: 'text',\n text: 'name or kbid is required',\n },\n ],\n isError: true,\n };\n }\n let content: string | undefined;\n if (kbid) {\n const sections = await client.readSections([kbid]);\n if (sections.length > 0) {\n content = sections[0]?.content;\n }\n }\n if (content === undefined && name) {\n const records = await client.listByType('skill');\n const match = records.filter((r) => r.title === name).pop();\n if (match) {\n content = match.content;\n }\n }\n if (content === undefined) {\n const identifier = kbid ?? name ?? '';\n return {\n content: [\n {\n type: 'text',\n text: `skill not found: ${identifier}`,\n },\n ],\n isError: true,\n };\n }\n const skill = parseSkillContent(content);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(skill, null, 2),\n },\n ],\n };\n}\n\nasync function handleSkillDelete(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const kbid = asString(args['kbid'], '');\n if (!kbid) {\n return {\n content: [{ type: 'text', text: 'kbid is required' }],\n isError: true,\n };\n }\n const result = await client.removeSection(kbid);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({ kbid, removed: result.removed }),\n },\n ],\n };\n}\n\nfunction handleAutoCaptureReview(): ToolCallResult {\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n pending: [],\n message: 'No pending auto-captured knowledge entries.',\n }),\n },\n ],\n };\n}\n\nasync function handleExport(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const path =\n typeof args['path'] === 'string' ? args['path'] : undefined;\n const result = await client.export(\n path !== undefined ? { path } : {},\n );\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(result),\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** A single content item in an MCP resource read response. */\ninterface ResourceContent {\n /** The resource URI that was read. */\n readonly uri: string;\n /** MIME type of the content body. */\n readonly mimeType: string;\n /** Text body of the resource. */\n readonly text: string;\n}\n\n/** Result returned by a resource read operation. */\ninterface ResourceReadResult {\n /** One or more content items for the requested URI. */\n readonly contents: ResourceContent[];\n}\n\n/**\n * Handles an MCP `resources/read` request by dispatching to the\n * appropriate knowledge-base operation based on the resource URI.\n *\n * @param client - the worker client used to fetch the resource\n * @param uri - the resource URI from the MCP request\n * @returns contents array for the MCP response\n * @throws {Error} when the URI does not match any known pattern\n */\nexport async function handleResourceRead(\n client: McpWorkerClient,\n uri: string,\n): Promise<ResourceReadResult> {\n const sectionMatch = uri.match(/^kbdb:\\/\\/section\\/(.+)$/);\n if (sectionMatch) {\n const sections = await client.readSections([sectionMatch[1]]);\n const text = sections.length > 0 ? sections[0].content : '';\n return {\n contents: [{ uri, mimeType: 'text/plain', text }],\n };\n }\n\n const docMatch = uri.match(/^kbdb:\\/\\/document\\/(.+)$/);\n if (docMatch) {\n const doc = await client.retrieveDocument(docMatch[1]);\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(doc, null, 2),\n },\n ],\n };\n }\n\n log(`Unknown resource URI: ${uri}`, LogLevel.ERROR);\n throw new Error(`Unknown resource URI: ${uri}`);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpPrompt } from '../typings/prompt-types.interface.ts';\nimport type { McpPromptArgument } from '../typings/prompt-types.interface.ts';\n\n/** Minimal skill section record shape required by this function. */\ninterface SkillSectionRecord {\n /** Knowledge-base identifier of the section. */\n readonly kbid: string;\n /** Human-readable section title used as the prompt name. */\n readonly title: string | null;\n /** JSON-encoded skill definition content. */\n readonly content: string;\n /** Optional human-readable section description. */\n readonly description?: string | null;\n}\n\n/** Minimal document manifest shape required by this function. */\ninterface AgentDocumentRecord {\n /** Unique document identifier. */\n readonly docid: string;\n /** Human-readable document title used in the prompt name. */\n readonly title: string;\n /** Ordered section references belonging to the document. */\n readonly sections: readonly {\n readonly kbid: string;\n readonly position: number;\n }[];\n}\n\n/**\n * Parses the `arguments` field from a skill's JSON content string.\n *\n * Returns the array of prompt argument definitions when the content\n * is valid JSON with an `arguments` array, or `undefined` when JSON\n * parsing fails or the field is absent.\n */\nfunction parseSkillArguments(\n content: string,\n): readonly McpPromptArgument[] | undefined {\n try {\n const parsed = JSON.parse(content) as Record<string, unknown>;\n if (!Array.isArray(parsed['arguments'])) {\n return undefined;\n }\n return (parsed['arguments'] as Record<string, unknown>[]).map(\n (arg) => ({\n name: typeof arg['name'] === 'string' ? arg['name'] : '',\n description:\n typeof arg['description'] === 'string'\n ? arg['description']\n : undefined,\n required:\n typeof arg['required'] === 'boolean'\n ? arg['required']\n : undefined,\n }),\n );\n } catch {\n return undefined;\n }\n}\n\n/**\n * Builds the list of MCP prompt definitions from skill sections and\n * agent document manifests stored in the knowledge base.\n *\n * Skills are mapped first (in input order), followed by agents.\n * Each skill becomes a prompt whose name is the section title and\n * whose arguments are extracted from the JSON content. Each agent\n * becomes a prompt prefixed with `\"agent:\"` and carries an empty\n * arguments array.\n *\n * @param skills - skill section records from `listByType('skill')`\n * @param agents - agent document manifests from\n * `listDocumentsByType('agent')`\n * @returns ordered list of MCP prompt definitions\n */\nexport function createPromptDefinitions(\n skills: readonly SkillSectionRecord[],\n agents: readonly AgentDocumentRecord[],\n): McpPrompt[] {\n const skillPrompts: McpPrompt[] = skills\n .filter(\n (r): r is SkillSectionRecord & { title: string } =>\n r.title !== null,\n )\n .map((record) => {\n const args = parseSkillArguments(record.content);\n const prompt: McpPrompt = {\n name: record.title,\n description: record.description ?? undefined,\n arguments: args,\n };\n return prompt;\n });\n\n const agentPrompts: McpPrompt[] = agents.map((doc) => ({\n name: `agent:${doc.title}`,\n arguments: [],\n }));\n\n return [...skillPrompts, ...agentPrompts];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type { McpPromptMessage } from '../typings/prompt-types.interface.ts';\n\n/** Parsed shape of an agent metadata section. */\ninterface AgentMeta {\n /** Agent persona text. */\n readonly persona: string;\n}\n\n/** Minimal section shape returned by readSections. */\ninterface ReadSection {\n /** Knowledge-base identifier. */\n readonly kbid: string;\n /** Raw text content. */\n readonly content: string;\n}\n\n/** Minimal agent document shape from listDocumentsByType. */\ninterface AgentDocument {\n /** Document title. */\n readonly title: string;\n /** Ordered section references. */\n readonly sections: readonly {\n readonly kbid: string;\n readonly position: number;\n }[];\n}\n\n/**\n * Parses agent metadata from a raw JSON content string.\n *\n * Returns default values when parsing fails or required fields are\n * absent.\n */\nfunction parseAgentMeta(content: string): AgentMeta {\n try {\n const parsed = JSON.parse(content) as Record<string, unknown>;\n return {\n persona:\n typeof parsed['persona'] === 'string'\n ? parsed['persona']\n : '',\n };\n } catch {\n return { persona: '' };\n }\n}\n\n/**\n * Builds the skills listing user message text from an array of\n * skill section content strings. Sections whose JSON is not parseable\n * or whose name cannot be determined are omitted silently.\n *\n * Returns `null` when no valid skills remain after filtering.\n */\nfunction buildSkillsText(skillSections: ReadSection[]): string | null {\n const lines: string[] = [];\n for (const sec of skillSections) {\n try {\n const parsed = JSON.parse(sec.content) as Record<\n string,\n unknown\n >;\n const name =\n typeof parsed['name'] === 'string' ? parsed['name'] : null;\n if (name === null) {\n continue;\n }\n const description =\n typeof parsed['description'] === 'string'\n ? parsed['description']\n : '';\n lines.push(`- ${name}: ${description}`);\n } catch {\n // skip unparseable sections\n }\n }\n if (lines.length === 0) {\n return null;\n }\n return `Available skills:\\n${lines.join('\\n')}`;\n}\n\n/**\n * Handles an MCP `prompts/get` request for an agent prompt.\n *\n * Looks up the agent by title via `listDocumentsByType('agent')`,\n * extracts its persona from the metadata section, then reads all\n * skill sections and composes the response. Returns an assistant\n * message with the persona and, when skills exist, a user message\n * listing them.\n */\nasync function handleAgentPrompt(\n name: string,\n client: McpWorkerClient,\n): Promise<McpPromptMessage[]> {\n const agentName = name.slice(6);\n const agents = await client.listDocumentsByType('agent');\n const doc = agents.find((a) => a.title === agentName) as\n | AgentDocument\n | undefined;\n if (!doc) {\n log('agent not found: ' + agentName, LogLevel.ERROR);\n throw new Error('agent not found: ' + agentName);\n }\n const sections = doc.sections;\n\n const metaSection = sections.at(0);\n const skillRefs = sections.slice(1);\n\n let persona = '';\n if (metaSection !== undefined) {\n const metaSections = await client.readSections([\n metaSection.kbid,\n ]);\n const metaContent = metaSections.at(0);\n if (metaContent !== undefined) {\n persona = parseAgentMeta(metaContent.content).persona;\n }\n }\n\n const messages: McpPromptMessage[] = [\n {\n role: 'assistant',\n content: { type: 'text', text: persona },\n },\n ];\n\n if (skillRefs.length === 0) {\n return messages;\n }\n\n const skillKbids = skillRefs.map((s) => s.kbid);\n const skillSections = await client.readSections(skillKbids);\n const skillsText = buildSkillsText(skillSections);\n\n if (skillsText !== null) {\n messages.push({\n role: 'user',\n content: { type: 'text', text: skillsText },\n });\n }\n\n return messages;\n}\n\n/**\n * Handles an MCP `prompts/get` request for a skill prompt.\n *\n * Looks up the skill by name in the `listByType('skill')` results,\n * picks the most recent match (last occurrence), parses its body,\n * and substitutes `{{argName}}` placeholders from `promptArgs`.\n * Unresolved placeholders are left as-is.\n *\n * @throws {Error} when no skill with the given name is found\n */\nasync function handleSkillPrompt(\n name: string,\n promptArgs: Record<string, string>,\n client: McpWorkerClient,\n): Promise<McpPromptMessage[]> {\n const sections = await client.listByType('skill');\n let matchContent: string | undefined;\n for (const sec of sections) {\n if (sec.title === name) {\n matchContent = sec.content;\n }\n }\n if (matchContent === undefined) {\n log(`Prompt not found: ${name}`, LogLevel.ERROR);\n throw new Error(`Prompt not found: ${name}`);\n }\n\n const parsed = JSON.parse(matchContent) as Record<string, unknown>;\n const body =\n typeof parsed['body'] === 'string' ? parsed['body'] : '';\n\n const rendered = body.replace(\n /\\{\\{(\\w+)\\}\\}/g,\n (_match, key: string) =>\n key in promptArgs ? (promptArgs[key] ?? _match) : _match,\n );\n\n return [\n {\n role: 'user',\n content: { type: 'text', text: rendered },\n },\n ];\n}\n\n/**\n * Handles an MCP `prompts/get` request.\n *\n * Dispatches to the agent handler when `name` starts with `\"agent:\"`,\n * otherwise treats the name as a skill prompt.\n *\n * For skill prompts: looks up by title using `listByType('skill')`,\n * substitutes `{{argName}}` placeholders in the body, and returns a\n * single user message.\n *\n * For agent prompts: looks up the agent by title via\n * `listDocumentsByType('agent')`, builds an assistant message from\n * the persona section, and (when skills exist) a user message\n * listing their names and descriptions.\n *\n * @param name - prompt name from the MCP request\n * @param promptArgs - argument key-value map from the MCP request\n * @param client - worker client used to access the knowledge base\n * @returns ordered list of prompt messages to return to the caller\n * @throws {Error} when a skill prompt name is not found in the store\n */\nexport async function handlePromptGet(\n name: string,\n promptArgs: Record<string, string>,\n client: McpWorkerClient,\n): Promise<McpPromptMessage[]> {\n if (name.startsWith('agent:')) {\n return handleAgentPrompt(name, client);\n }\n return handleSkillPrompt(name, promptArgs, client);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/**\n * Discriminated reference used in MCP completion requests.\n * Identifies whether the completion target is a prompt or a resource.\n */\nexport interface McpCompletionRef {\n /**\n * The reference type: `'ref/prompt'` for named prompts (skills\n * and agents) or `'ref/resource'` for resource URIs.\n */\n readonly type: 'ref/prompt' | 'ref/resource';\n /** Prompt name, present when `type` is `'ref/prompt'`. */\n readonly name?: string;\n /** Resource URI, present when `type` is `'ref/resource'`. */\n readonly uri?: string;\n}\n\n/**\n * Completion argument supplied by the client, describing which\n * argument is being completed and the current partial value.\n */\nexport interface McpCompletionArgument {\n /** The argument name being completed. */\n readonly name: string;\n /** The partial value typed so far; used for prefix filtering. */\n readonly value: string;\n}\n\n/**\n * Result returned by `handleCompletion`, containing the list of\n * matching completion values and pagination metadata.\n */\nexport interface McpCompletionResult {\n /** Completion payload. */\n readonly completion: {\n /** Matching completion strings for the given prefix. */\n readonly values: string[];\n /**\n * Whether more results are available beyond what is returned.\n * Always `false` in this implementation.\n */\n readonly hasMore: boolean;\n /** Total number of values returned. */\n readonly total: number;\n };\n}\n\n/**\n * Handles an MCP `completion/complete` request.\n *\n * For `ref/prompt` references, builds a list of all skill titles and\n * agent titles (prefixed with `agent:`) and filters by the supplied\n * argument value prefix. For `ref/resource` references, returns an\n * empty result \u2014 resource completion is not implemented.\n *\n * @param ref - discriminated reference identifying the completion target\n * @param argument - current argument name and partial value\n * @param client - worker client used to fetch skills and agents\n * @returns matching completion values with pagination metadata\n */\nexport async function handleCompletion(\n ref: McpCompletionRef,\n argument: McpCompletionArgument,\n client: McpWorkerClient,\n): Promise<McpCompletionResult> {\n if (ref.type !== 'ref/prompt') {\n return { completion: { values: [], hasMore: false, total: 0 } };\n }\n\n const [skills, agents] = await Promise.all([\n client.listByType('skill'),\n client.listDocumentsByType('agent'),\n ]);\n\n const names: string[] = [];\n\n for (const skill of skills) {\n if (skill.title !== null) {\n names.push(skill.title);\n }\n }\n\n for (const agent of agents) {\n names.push(`agent:${agent.title}`);\n }\n\n const prefix = argument.value;\n\n function matchesPrefix(candidate: string): boolean {\n if (prefix.length === 0) {\n return true;\n }\n if (candidate.startsWith(prefix)) {\n return true;\n }\n // For agent-prefixed names, also match against the title portion.\n const AGENT_PREFIX = 'agent:';\n if (candidate.startsWith(AGENT_PREFIX)) {\n return candidate.slice(AGENT_PREFIX.length).startsWith(prefix);\n }\n return false;\n }\n\n const values = names.filter(matchesPrefix);\n\n return {\n completion: {\n values,\n hasMore: false,\n total: values.length,\n },\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Represents a single file-system root entry advertised to MCP\n * clients via the `roots/list` response.\n */\nexport interface McpRoot {\n /** Absolute file URI for the root directory. */\n readonly uri: string;\n /** Human-readable label for the root. */\n readonly name: string;\n}\n\n/**\n * Returns the list of MCP roots for the given database context path.\n *\n * Produces a single root entry whose URI is `file://` concatenated\n * with the supplied `contextPath`. This tells MCP clients which\n * file-system directory the server is authoritative for.\n *\n * @param contextPath - absolute path to the kbdb database directory\n * @returns array containing a single root for the context path\n */\nexport function handleRootsList(contextPath: string): McpRoot[] {\n return [\n {\n uri: `file://${contextPath}`,\n name: 'kbdb database',\n },\n ];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpLogLevel } from '../typings/log-types.interface.ts';\n\n/**\n * Ordered list of MCP log severity levels, from least severe\n * (`debug`) to most severe (`emergency`). Used to compare levels\n * when filtering log output.\n */\nexport const LOG_LEVEL_ORDER: McpLogLevel[] = [\n 'debug',\n 'info',\n 'notice',\n 'warning',\n 'error',\n 'critical',\n 'alert',\n 'emergency',\n];\n\n/**\n * Determines whether a log message at `messageLevel` should be\n * emitted when the server's log threshold is `threshold`.\n *\n * Returns `true` when `messageLevel` is at the same severity as\n * `threshold` or higher. Returns `false` when the message level is\n * below the threshold.\n *\n * @param messageLevel - severity of the log message to evaluate\n * @param threshold - minimum severity level required to emit\n * @returns `true` if the message meets or exceeds the threshold\n */\nexport function shouldEmitLog(\n messageLevel: McpLogLevel,\n threshold: McpLogLevel,\n): boolean {\n const messageIndex = LOG_LEVEL_ORDER.indexOf(messageLevel);\n const thresholdIndex = LOG_LEVEL_ORDER.indexOf(threshold);\n return messageIndex >= thresholdIndex;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Builds the MCP sampling prompt for knowledge extraction.\n *\n * Instructs the host LLM to identify durable factual knowledge\n * from the recent conversation context, filter out ephemeral or\n * task-specific information, and format the result for storage\n * following memory-protocol criteria.\n *\n * @param recentContext - the conversation excerpt to analyse\n */\nexport function buildCapturePrompt(recentContext: string): string {\n return (\n 'Review the following conversation context and identify' +\n ' factual knowledge worth storing in the knowledge base.\\n\\n' +\n 'Rules:\\n' +\n '- Include durable facts, decisions, preferences, and' +\n ' corrections that would be useful in future sessions.\\n' +\n '- Exclude ephemeral, task-specific, or temporary information' +\n ' that has no lasting value.\\n' +\n '- Format each piece of extracted knowledge as a concise' +\n ' statement suitable for direct storage.\\n' +\n '- If no durable knowledge is found, respond with an empty' +\n ' list.\\n\\n' +\n 'Conversation context:\\n' +\n recentContext\n );\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Returns `true` when the host advertised the `sampling` capability\n * during MCP initialization.\n *\n * @param hostCapabilities - capabilities object from the MCP\n * `initialize` request, or `null` when not yet set\n */\nexport function hasSamplingCapability(\n hostCapabilities: Record<string, unknown> | null,\n): boolean {\n if (hostCapabilities === null) return false;\n return Boolean(hostCapabilities['sampling']);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { AutoCaptureController } from '../../auto-capture/classes/auto-capture-controller.class.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport type { AutoCaptureConfig } from '../../auto-capture/typings/auto-capture-config.interface.ts';\nimport { buildCapturePrompt } from '../../auto-capture/functions/build-capture-prompt.function.ts';\nimport { hasSamplingCapability } from './has-sampling-capability.function.ts';\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** Sampling request callback matching McpServer.sendRequest. */\ntype RequestSampling = (\n messages: {\n role: string;\n content: { type: string; text: string };\n }[],\n maxTokens: number,\n) => Promise<unknown>;\n\n/** Shape of a successful sampling response. */\ninterface SamplingResponse {\n readonly content: { readonly type: string; readonly text: string };\n}\n\nfunction isSamplingResponse(v: unknown): v is SamplingResponse {\n if (typeof v !== 'object' || v === null) return false;\n const obj = v as Record<string, unknown>;\n const content = obj['content'];\n if (typeof content !== 'object' || content === null) return false;\n return (\n typeof (content as Record<string, unknown>)['text'] === 'string'\n );\n}\n\n/**\n * Evaluates the auto-capture trigger and, when it fires, sends an\n * MCP sampling request to the host and stores any returned knowledge.\n *\n * Silently ignores all errors so a capture failure never disrupts\n * the MCP server's normal operation.\n *\n * @param controller - tracks session state and evaluates the trigger\n * @param config - auto-capture configuration (provides dryRun flag)\n * @param client - worker client used to persist captured knowledge\n * @param hostCapabilities - capabilities from the MCP host\n * @param requestSampling - sends a sampling request to the host\n */\nexport async function runAutoCapture(\n controller: AutoCaptureController,\n config: AutoCaptureConfig,\n client: McpWorkerClient,\n hostCapabilities: Record<string, unknown> | null,\n requestSampling: RequestSampling,\n): Promise<void> {\n try {\n const trigger = controller.evaluate();\n log('auto-capture trigger evaluated', LogLevel.DEBUG);\n if (!trigger.shouldCapture) return;\n if (!hasSamplingCapability(hostCapabilities)) return;\n\n const prompt = buildCapturePrompt('recent conversation context');\n const messages = [\n { role: 'user', content: { type: 'text', text: prompt } },\n ];\n const raw = await requestSampling(messages, 1024);\n\n if (!isSamplingResponse(raw)) return;\n const text = raw.content.text.trim();\n if (!text) return;\n if (config.dryRun) return;\n\n log('auto-capture storing knowledge', LogLevel.DEBUG);\n await client.addSection({\n sectionType: 'text/markdown',\n content: text,\n title: 'Auto-captured knowledge',\n });\n } catch {\n log('auto-capture error (non-fatal)', LogLevel.DEBUG);\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { AutoCaptureConfig } from '../typings/auto-capture-config.interface.ts';\nimport type { AutoCaptureState } from '../typings/auto-capture-state.interface.ts';\nimport type { AutoCaptureTrigger } from '../typings/auto-capture-trigger.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Evaluates whether auto-capture should fire given the current\n * configuration and runtime state.\n *\n * Checks (in order): feature flag, session cap, rate limit,\n * and tool-call count threshold. Returns the first failing\n * condition as the reason.\n */\nexport function evaluateTrigger(\n config: AutoCaptureConfig,\n state: AutoCaptureState,\n): AutoCaptureTrigger {\n log('evaluating auto-capture trigger conditions', LogLevel.DEBUG);\n if (!config.enabled) {\n return {\n shouldCapture: false,\n reason: 'auto-capture is disabled',\n };\n }\n\n if (state.totalCapturesThisSession >= config.maxCapturesPerSession) {\n return {\n shouldCapture: false,\n reason: 'session capture limit reached',\n };\n }\n\n const elapsed = state.lastCaptureTimestamp\n ? Date.now() - state.lastCaptureTimestamp\n : Infinity;\n\n if (elapsed < config.minIntervalMs) {\n return {\n shouldCapture: false,\n reason: 'within minimum interval',\n };\n }\n\n if (state.toolCallsSinceLastCapture < config.triggerAfterToolCalls) {\n return {\n shouldCapture: false,\n reason: 'tool call threshold not yet reached',\n };\n }\n\n return { shouldCapture: true, reason: 'trigger threshold met' };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { AutoCaptureConfig } from '../typings/auto-capture-config.interface.ts';\nimport type { AutoCaptureState } from '../typings/auto-capture-state.interface.ts';\nimport type { AutoCaptureTrigger } from '../typings/auto-capture-trigger.interface.ts';\nimport { evaluateTrigger } from '../functions/evaluate-trigger.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Controls the auto-capture lifecycle.\n *\n * Tracks tool call counts, evaluates trigger conditions, and\n * advances session state when a capture fires. Reset state on\n * disconnect or session end via `reset()`.\n */\nexport class AutoCaptureController {\n private toolCallsSinceLastCapture = 0;\n private lastCaptureTimestamp = 0;\n private totalCapturesThisSession = 0;\n private readonly config: AutoCaptureConfig;\n\n /** @param config - the auto-capture configuration to use */\n constructor(config: AutoCaptureConfig) {\n this.config = config;\n }\n\n /** Record one tool call for trigger counting. */\n recordToolCall(): void {\n this.toolCallsSinceLastCapture += 1;\n }\n\n /**\n * Evaluates the current state against the trigger criteria.\n *\n * When the trigger fires, advances the session counters so the\n * next evaluation respects rate limiting and the session cap.\n *\n * @returns the trigger decision with a human-readable reason\n */\n evaluate(): AutoCaptureTrigger {\n log('evaluating auto-capture trigger', LogLevel.DEBUG);\n const trigger = evaluateTrigger(this.config, this.state());\n if (trigger.shouldCapture) {\n this.totalCapturesThisSession += 1;\n this.lastCaptureTimestamp = Date.now();\n this.toolCallsSinceLastCapture = 0;\n }\n return trigger;\n }\n\n /** Reset all counters, e.g. on client disconnect. */\n reset(): void {\n log('resetting auto-capture controller', LogLevel.DEBUG);\n this.toolCallsSinceLastCapture = 0;\n this.lastCaptureTimestamp = 0;\n this.totalCapturesThisSession = 0;\n }\n\n /** Returns a snapshot of the current controller state. */\n state(): AutoCaptureState {\n return {\n toolCallsSinceLastCapture: this.toolCallsSinceLastCapture,\n lastCaptureTimestamp: this.lastCaptureTimestamp,\n totalCapturesThisSession: this.totalCapturesThisSession,\n };\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * JSON-RPC 2.0 parse error code. Returned when the\n * server receives malformed JSON.\n */\nexport const PARSE_ERROR = -32700;\n\n/**\n * JSON-RPC 2.0 method not found error code. Returned\n * when the requested method does not exist.\n */\nexport const METHOD_NOT_FOUND = -32601;\n\n/**\n * JSON-RPC 2.0 invalid params error code. Returned\n * when method parameters are invalid or missing.\n */\nexport const INVALID_PARAMS = -32602;\n\n/**\n * JSON-RPC 2.0 internal error code. Returned when an\n * unexpected server-side error occurs.\n */\nexport const INTERNAL_ERROR = -32603;\n\n/**\n * MCP-specific resource not found error code. Returned\n * when a well-formed URI does not match any resource\n * in the knowledge base.\n */\nexport const RESOURCE_NOT_FOUND = -32002;\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { McpServer } from '../classes/mcp-server.class.ts';\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type { AutoCaptureConfig } from '../../auto-capture/typings/auto-capture-config.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Factory that constructs a new `McpServer` bound to the given\n * worker client. Call `server.listen()` on the returned instance\n * to start processing stdio input.\n *\n * @param client - worker client providing knowledge-base operations\n * @param contextPath - absolute path to the `.kbdb` directory\n * @param autoCaptureConfig - optional auto-capture configuration;\n * when provided, the server activates auto-capture on client\n * connection and stops it on disconnect\n * @returns a configured `McpServer` ready to listen\n */\nexport function createMcpServer(\n client: McpWorkerClient,\n contextPath?: string,\n autoCaptureConfig?: AutoCaptureConfig,\n clientFactory?: (() => Promise<McpWorkerClient>) | null,\n maxRetries?: number,\n): McpServer {\n log('creating MCP server', LogLevel.DEBUG);\n return new McpServer(\n client,\n contextPath,\n autoCaptureConfig,\n clientFactory,\n maxRetries,\n );\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
3
|
+
"sources": ["../src/cli.ts", "../src/shared/cli/constants/defaults.constant.ts", "../src/shared/cli/functions/parse-args.function.ts", "../src/shared/cli/functions/format-text-output.function.ts", "../src/shared/cli/functions/format-mcp-output.function.ts", "../src/shared/cli/functions/resolve-recfile-key.function.ts", "../src/shared/cli/functions/render-recfile-value.function.ts", "../src/shared/cli/functions/format-recfile-output.function.ts", "../src/shared/cli/constants/recfile-field-maps.constant.ts", "../src/shared/cli/functions/format-output.function.ts", "../src/shared/cli/constants/recfile-command-field-map.constant.ts", "../src/shared/cli/functions/format-command-text.function.ts", "../src/shared/cli/functions/wrap-mcp-envelope.function.ts", "../src/shared/cli/functions/format-command-output.function.ts", "../src/shared/cli/functions/run-search.function.ts", "../src/shared/cli/functions/resolve-kbid-prefix.function.ts", "../src/shared/cli/functions/run-recall.function.ts", "../src/shared/cli/functions/run-export.function.ts", "../src/shared/cli/functions/run-learn.function.ts", "../src/shared/cli/functions/collect-files.function.ts", "../src/shared/cli/functions/compute-directory-level.function.ts", "../src/shared/cli/functions/run-unlearn.function.ts", "../src/shared/cli/functions/run-content.function.ts", "../src/shared/cli/functions/run-check.function.ts", "../src/shared/cli/functions/run-gc.function.ts", "../src/shared/cli/functions/run-rebuild.function.ts", "../src/shared/cli/functions/find-db.function.ts", "../src/shared/cli/functions/run-init.function.ts", "../src/shared/cli/functions/install-default-skills.function.ts", "../src/shared/cli/functions/error-to-message.function.ts", "../src/shared/cli/functions/is-stdin-tty.function.ts", "../src/shared/cli/functions/prompt-user.function.ts", "../src/shared/cli/functions/run-status.function.ts", "../src/shared/cli/functions/run-db-init.function.ts", "../src/shared/cli/functions/run-db-migrate.function.ts", "../src/shared/mcp/functions/extract-skill-arguments.function.ts", "../src/shared/mcp/functions/serialize-skill-content.function.ts", "../src/shared/cli/functions/run-skill-learn.function.ts", "../src/shared/cli/functions/run-skill-list.function.ts", "../src/shared/mcp/functions/parse-skill-content.function.ts", "../src/shared/cli/functions/run-skill-get.function.ts", "../src/shared/cli/functions/run-skill-delete.function.ts", "../src/shared/cli/functions/run-agent-create.function.ts", "../src/shared/cli/functions/run-agent-list.function.ts", "../src/shared/cli/functions/run-agent-get.function.ts", "../src/shared/cli/functions/run-agent-delete.function.ts", "../src/shared/cli/functions/run-skill-search.function.ts", "../src/shared/cli/functions/run-agent-search.function.ts", "../src/shared/cli/functions/run-import.function.ts", "../src/shared/cli/functions/hydrate-search-previews.function.ts", "../src/shared/cli/functions/dispatch-command.function.ts", "../src/shared/version/constants/version.constant.ts", "../src/shared/cli/functions/generate-help.function.ts", "../src/shared/cli/functions/resolve-db-dir.function.ts", "../src/shared/cli/functions/format-db-not-found.function.ts", "../src/shared/cli/functions/run-db-path.function.ts", "../src/shared/worker-client/classes/worker-client.class.ts", "../src/shared/worker-client/functions/discover-daemon.function.ts", "../src/shared/platform/functions/is-process-alive.function.ts", "../src/shared/worker-client/functions/resolve-db-path.function.ts", "../src/shared/worker-client/functions/compute-context-id.function.ts", "../src/shared/worker-client/functions/spawn-daemon.function.ts", "../src/shared/worker-client/functions/build-deno-permissions.function.ts", "../src/shared/worker-client/functions/wait-for-daemon.function.ts", "../src/shared/worker-client/functions/read-crash-reason.function.ts", "../src/shared/worker-client/functions/resolve-spawn-script.function.ts", "../src/shared/worker-client/functions/create-worker-client.function.ts", "../src/shared/cli/functions/run-worker-stop.function.ts", "../src/shared/cli/functions/run-worker-restart.function.ts", "../src/shared/worker-client/functions/retry-on-timeout.function.ts", "../src/shared/worker-client/constants/request-timeout.constant.ts", "../src/shared/worker-client/constants/retry-defaults.constant.ts", "../src/shared/cli/functions/run-cli.function.ts", "../src/shared/cli/constants/help-text.constant.ts", "../src/shared/mcp/classes/mcp-server.class.ts", "../src/shared/mcp/functions/create-tool-definitions.function.ts", "../src/shared/mcp/functions/create-resource-templates.function.ts", "../src/shared/mcp/functions/format-search-results.function.ts", "../src/shared/mcp/functions/handle-agent-create.function.ts", "../src/shared/mcp/functions/handle-agent-list.function.ts", "../src/shared/mcp/functions/handle-agent-get.function.ts", "../src/shared/mcp/functions/handle-agent-delete.function.ts", "../src/shared/mcp/functions/handle-recall.function.ts", "../src/shared/mcp/functions/handle-skill-search.function.ts", "../src/shared/mcp/functions/handle-agent-search.function.ts", "../src/shared/mcp/functions/handle-tool-call.function.ts", "../src/shared/mcp/functions/handle-resource-read.function.ts", "../src/shared/mcp/functions/create-prompt-definitions.function.ts", "../src/shared/mcp/functions/handle-prompt-get.function.ts", "../src/shared/mcp/functions/handle-completion.function.ts", "../src/shared/mcp/functions/handle-roots-list.function.ts", "../src/shared/mcp/functions/should-emit-log.function.ts", "../src/shared/auto-capture/functions/build-capture-prompt.function.ts", "../src/shared/mcp/functions/has-sampling-capability.function.ts", "../src/shared/mcp/functions/run-auto-capture.function.ts", "../src/shared/auto-capture/functions/evaluate-trigger.function.ts", "../src/shared/auto-capture/classes/auto-capture-controller.class.ts", "../src/shared/mcp/constants/mcp-error-codes.constant.ts", "../src/shared/mcp/functions/create-mcp-server.function.ts"],
|
|
4
|
+
"sourcesContent": ["// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * @module\n *\n * CLI and MCP server executable for kbdb. Provides the\n * `kbdb` command with 18 subcommands for managing a\n * file-based knowledge base, and an MCP server mode\n * for AI agent integration.\n */\n\nimport { readFileSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { getArgs } from './shared/runtime/index.ts';\nimport {\n runCli,\n isStdinTty,\n promptUser,\n findDb,\n runInit,\n} from './shared/cli/index.ts';\nimport type { CliDeps } from './shared/cli/index.ts';\nimport { createWorkerClient } from './shared/worker-client/index.ts';\nimport { createMcpServer } from './shared/mcp/index.ts';\nimport type { McpWorkerClient } from './shared/mcp/typings/mcp-client.interface.ts';\nimport { parseWorkerToml } from './shared/worker-daemon/functions/parse-worker-toml.function.ts';\nimport { log } from './shared/log/functions/log.function.ts';\nimport { LogLevel } from './shared/log/typings/log-level.type.ts';\n\nconst deps: CliDeps = {\n isStdinTty,\n isStdoutTty: () => process.stdout.isTTY,\n promptUser,\n createWorkerClient: (opts) => createWorkerClient(opts),\n findDb,\n runInit,\n startMcpServer: async (contextPath, clientFactory, maxRetries) => {\n log('starting MCP server', LogLevel.INFO);\n const client = await createWorkerClient({ contextPath });\n try {\n const tomlPath = join(contextPath, 'worker.toml');\n let autoCaptureConfig;\n try {\n const tomlText = readFileSync(tomlPath, 'utf-8');\n const daemonConfig = parseWorkerToml(tomlText, contextPath);\n autoCaptureConfig = daemonConfig.autoCapture;\n } catch {\n // worker.toml absent or unreadable\n }\n const server = createMcpServer(\n client,\n contextPath,\n autoCaptureConfig,\n clientFactory as\n | (() => Promise<McpWorkerClient>)\n | undefined,\n maxRetries,\n );\n log('MCP server listening on stdio', LogLevel.DEBUG);\n await server.listen();\n log('MCP server closed', LogLevel.INFO);\n } finally {\n client.disconnect();\n }\n },\n};\n\nasync function main(): Promise<void> {\n const result = await runCli(getArgs(), deps);\n if (result.output) {\n // eslint-disable-next-line no-console\n console.log(result.output);\n }\n if (result.error) {\n log(result.error, LogLevel.ERROR);\n }\n if (result.exitCode !== 0) {\n process.exitCode = result.exitCode;\n }\n}\n\nmain().catch((err: unknown) => {\n const msg = err instanceof Error ? err.message : String(err);\n log('error: ' + msg, LogLevel.ERROR);\n process.exitCode = 1;\n});\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Default maximum number of search results returned per query. */\nexport const DEFAULT_LIMIT = 20;\n\n/** Default output format when `--format` is not specified. */\nexport const DEFAULT_FORMAT = 'rec' as const;\n\n/** Default search mode when `--mode` is not specified. */\nexport const DEFAULT_MODE = 'sections' as const;\n\n/**\n * File extensions recognised as importable documents by the learn\n * command. Extensions are lowercase and include the leading dot.\n */\nexport const SUPPORTED_EXTENSIONS = [\n '.md',\n '.txt',\n '.rst',\n '.adoc',\n] as const;\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport {\n DEFAULT_FORMAT,\n DEFAULT_LIMIT,\n DEFAULT_MODE,\n} from '../constants/defaults.constant.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { parseLogLevel } from '../../log/functions/parse-log-level.function.ts';\n\n/**\n * Parses a raw argument vector into a structured `CliOptions` object.\n *\n * Recognises `--help` / `-h` and `--version` / `-v` as early-exit\n * flags that set the command and return immediately. All other flags\n * consume the next token as their value. The first non-flag token\n * becomes the command; subsequent non-flag tokens become `args`.\n *\n * Compound commands are supported: when the first positional token is\n * a group name (`db`, `skill`, `agent`, or `worker`), the next\n * positional token is joined with a hyphen to form the compound\n * command (e.g. `db init` \u2192 `'db-init'`,\n * `worker stop` \u2192 `'worker-stop'`).\n *\n * Context-aware `--help`: when `--help` or `-h` appears after a\n * command has been set, the existing command is moved to `args[0]`\n * and the command is set to `'help'`, enabling per-command help.\n *\n * Deprecated flags `--init` and `--migrate` emit a warning to stderr\n * before setting the corresponding command.\n *\n * @param argv - argument strings (typically `process.argv.slice(2)`)\n * @returns fully populated `CliOptions` with defaults applied\n */\nexport function parseArgs(argv: string[]): CliOptions {\n const options: CliOptions = {\n command: '',\n format: DEFAULT_FORMAT,\n mode: DEFAULT_MODE,\n limit: DEFAULT_LIMIT,\n args: [],\n };\n\n let i = 0;\n while (i < argv.length) {\n const arg = argv[i];\n switch (arg) {\n case '--help':\n case '-h':\n if (options.command) {\n options.args.unshift(options.command);\n options.command = 'help';\n } else {\n options.command = 'help';\n }\n return options;\n case '--version':\n options.command = 'version';\n return options;\n case '-v':\n case '--verbose': {\n const next = argv[i + 1];\n if (next && !next.startsWith('-')) {\n options.logLevel = parseLogLevel(next);\n i++;\n } else {\n options.logLevel = LogLevel.WARNING;\n }\n break;\n }\n case '-vv':\n case '--verbose-info':\n options.logLevel = LogLevel.INFO;\n break;\n case '-vvv':\n case '--verbose-debug':\n options.logLevel = LogLevel.DEBUG;\n break;\n case '--init':\n options.command = 'init';\n break;\n case '--migrate':\n options.command = 'migrate';\n break;\n case '--db':\n options.dbPath = argv[++i];\n break;\n case '--format':\n case '-f':\n options.format = (argv[++i] ??\n DEFAULT_FORMAT) as CliOptions['format'];\n options.formatExplicit = true;\n break;\n case '--mode':\n case '-m':\n options.mode = (argv[++i] ??\n DEFAULT_MODE) as CliOptions['mode'];\n break;\n case '--limit':\n case '-l':\n options.limit =\n parseInt(argv[++i] ?? '', 10) || DEFAULT_LIMIT;\n break;\n case '--offset':\n case '-o':\n options.offset = Math.max(\n 0,\n parseInt(argv[++i] ?? '', 10) || 0,\n );\n break;\n case '--algo':\n options.algo = argv[++i];\n break;\n case '--title':\n options.title = argv[++i];\n break;\n case '--description':\n options.description = argv[++i];\n break;\n case '--docid':\n options.docid = argv[++i];\n break;\n case '--name':\n options.name = argv[++i];\n break;\n case '--persona':\n options.persona = argv[++i];\n break;\n case '--body':\n options.body = argv[++i];\n break;\n case '--skills':\n options.skills = (argv[++i] ?? '').split(',');\n break;\n case '--tags':\n options.tags = (argv[++i] ?? '').split(',');\n break;\n case '--replace':\n options.replace = true;\n break;\n case '--level':\n case '--weight': {\n const raw = argv[++i];\n const n = Number(raw);\n if (!Number.isInteger(n) || n < 1 || n > 6) {\n throw new Error(\n `Invalid level \"${raw}\": must be integer 1-6`,\n );\n }\n options.level = n;\n break;\n }\n case '--depth':\n case '-d':\n options.depth = Math.min(\n 3,\n Math.max(0, parseInt(argv[++i] ?? '', 10) || 0),\n );\n break;\n case '--content':\n case '-c':\n options.content = true;\n break;\n case '--search':\n case '-s':\n options.search = true;\n break;\n case '--relaxed':\n options.relaxed = true;\n break;\n case '--from':\n options.from = argv[++i];\n break;\n case '--dry-run':\n options.dryRun = true;\n break;\n case '--export-format':\n options.exportFormat = (argv[++i] ??\n 'git') as CliOptions['exportFormat'];\n break;\n case '--timeout-ms':\n options.timeoutMs =\n parseInt(argv[++i] ?? '', 10) || undefined;\n break;\n case '--retry':\n options.retry = parseInt(argv[++i] ?? '', 10) || undefined;\n break;\n case '--non-interactive':\n options.nonInteractive = true;\n break;\n default:\n if (!options.command) {\n options.command = arg;\n } else if (\n !options.args.length &&\n (options.command === 'db' ||\n options.command === 'skill' ||\n options.command === 'agent' ||\n options.command === 'worker')\n ) {\n options.command = `${options.command}-${arg}`;\n } else {\n options.args.push(arg);\n }\n }\n i++;\n }\n\n return options;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\n\n/**\n * Formats a paged search result as a numbered human-readable\n * text list with a paging footer and optional \"more\" hint.\n *\n * @param paged - paginated search results to render\n * @param content - when true, show full content (preview)\n * instead of snippet\n */\nexport function formatTextOutput(\n paged: PagedSearchDisplay,\n content?: boolean,\n): string {\n if (paged.items.length === 0) return 'No results found.';\n const start = paged.offset + 1;\n const end = paged.offset + paged.items.length;\n\n const lines = paged.items\n .map((r, i) => {\n const num = paged.offset + i + 1;\n const heading = r.heading || '(untitled)';\n const terms = r.matched_terms.join(', ');\n const fields = r.matched_fields.join(', ');\n const confidencePct = (r.confidence * 100).toFixed(0);\n const body = content\n ? r.preview || '(no content)'\n : r.snippet || r.preview || '(no snippet)';\n return (\n `${String(num)}. [${r.kbid}] ${heading}` +\n ` (score: ${r.score.toFixed(4)},` +\n ` confidence: ${confidencePct}%)\\n` +\n ` ${body}\\n` +\n ` type: ${r.type}` +\n ` terms: ${terms}` +\n (fields ? ` fields: ${fields}` : '')\n );\n })\n .join('\\n\\n');\n\n const footer =\n `\\nShowing ${String(start)}-${String(end)}` +\n ` of ${String(paged.total)} results`;\n const hint = paged.has_more\n ? `\\nUse --offset ${String(end)} to see more`\n : '';\n\n return lines + footer + hint;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\n\n/**\n * Formats paged search results as a JSON-RPC 2.0 envelope\n * with a human-readable `text` content block.\n *\n * @param paged - paginated search results to serialise\n * @param content - when true, use full content (preview)\n * instead of snippet\n */\nexport function formatMcpOutput(\n paged: PagedSearchDisplay,\n content?: boolean,\n): string {\n const text =\n paged.items.length === 0\n ? 'No results found.'\n : paged.items\n .map((r) => {\n const body = content\n ? r.preview || '(no content)'\n : r.snippet || r.preview;\n return (\n `[${r.kbid}]` +\n ` ${r.heading || '(untitled)'}` +\n ` \u2014 ${body}`\n );\n })\n .join('\\n');\n\n return JSON.stringify(\n {\n jsonrpc: '2.0',\n result: {\n content: [{ type: 'text', text }],\n total: paged.total,\n offset: paged.offset,\n limit: paged.limit,\n has_more: paged.has_more,\n },\n },\n null,\n 2,\n );\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Resolves a dot-notation property path (e.g.\n * `'cacheStats.contentCount'`) against an object, returning\n * `undefined` if any segment along the path is missing.\n *\n * @param obj - the object to traverse\n * @param key - dot-separated property path\n */\nexport function resolveRecfileKey(obj: unknown, key: string): unknown {\n const parts = key.split('.');\n let current: unknown = obj;\n for (const part of parts) {\n if (current == null || typeof current !== 'object') {\n return undefined;\n }\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Renders a value for recfile output, or returns `null` when the\n * value is absent and the field should be omitted.\n *\n * Arrays render comma-separated; booleans render as `'true'` or\n * `'false'`; `null`, `undefined`, empty strings, and empty\n * arrays are treated as absent.\n *\n * @param value - the value to render\n */\nexport function renderRecfileValue(value: unknown): string | null {\n if (value === null || value === undefined) return null;\n if (Array.isArray(value)) {\n if (value.length === 0) return null;\n return value.map(String).join(', ');\n }\n if (typeof value === 'boolean') return value ? 'true' : 'false';\n if (typeof value === 'number') return String(value);\n if (typeof value === 'string') return value === '' ? null : value;\n return JSON.stringify(value);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { RecfileFieldMap } from '../typings/recfile-field-map.type.ts';\nimport { resolveRecfileKey } from './resolve-recfile-key.function.ts';\nimport { renderRecfileValue } from './render-recfile-value.function.ts';\n\n/**\n * Formats one or more records as recfile (GNU recutils style)\n * output: `Field: Value` pairs, blank-line separated records,\n * and `+ ` continuation lines for multi-line values.\n *\n * @param data - a single record or an array of records\n * @param fields - ordered field map controlling which\n * properties are rendered and in what order\n */\nexport function formatRecfileOutput(\n data: unknown,\n fields: RecfileFieldMap,\n): string {\n const records = Array.isArray(data) ? data : [data];\n return records\n .map((record) => formatRecord(record, fields))\n .filter(Boolean)\n .join('\\n\\n');\n}\n\nfunction formatRecord(\n record: unknown,\n fields: RecfileFieldMap,\n): string {\n if (!record || typeof record !== 'object') return '';\n const lines: string[] = [];\n for (const [field, key] of fields) {\n const value = resolveRecfileKey(record, key);\n const rendered = renderRecfileValue(value);\n if (rendered === null) continue;\n lines.push(formatField(field, rendered));\n }\n return lines.join('\\n');\n}\n\nfunction formatField(field: string, value: string): string {\n const lines = value.split('\\n');\n if (lines.length === 1) return `${field}: ${lines[0]}`;\n return [\n `${field}: ${lines[0]}`,\n ...lines.slice(1).map((line) => `+ ${line}`),\n ].join('\\n');\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { RecfileFieldMap } from '../typings/recfile-field-map.type.ts';\n\n/** Field map for search results (per item in `items[]`). */\nexport const SEARCH_FIELDS: RecfileFieldMap = [\n ['kbid', 'kbid'],\n ['heading', 'heading'],\n ['score', 'score'],\n ['confidence', 'confidence'],\n ['type', 'type'],\n ['terms', 'matched_terms'],\n ['fields', 'matched_fields'],\n ['snippet', 'snippet'],\n ['level', 'level'],\n] as const;\n\n/** Field map for search results with `--content` flag. */\nexport const SEARCH_CONTENT_FIELDS: RecfileFieldMap = [\n ['kbid', 'kbid'],\n ['heading', 'heading'],\n ['score', 'score'],\n ['confidence', 'confidence'],\n ['type', 'type'],\n ['terms', 'matched_terms'],\n ['fields', 'matched_fields'],\n ['content', 'preview'],\n ['level', 'level'],\n] as const;\n\n/** Field map for learn results (list payload). */\nexport const LEARN_FIELDS: RecfileFieldMap = [\n ['items', 'items'],\n ['total', 'total'],\n ['offset', 'offset'],\n ['superseded', 'superseded'],\n ['warnings', 'warnings'],\n] as const;\n\n/** Field map for unlearn (remove) result. */\nexport const UNLEARN_FIELDS: RecfileFieldMap = [\n ['removed', 'removed'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n\n/** Field map for recall results (per item). */\nexport const RECALL_FIELDS: RecfileFieldMap = [\n ['kbid', 'kbid'],\n ['heading', 'heading'],\n ['type', 'type'],\n ['docids', 'docids'],\n ['content', 'content'],\n ['level', 'level'],\n] as const;\n\n/** Field map for export result. */\nexport const EXPORT_FIELDS: RecfileFieldMap = [\n ['path', 'path'],\n ['sections', 'sections_exported'],\n ['documents', 'documents_exported'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n\n/** Field map for import result. */\nexport const IMPORT_FIELDS: RecfileFieldMap = [\n ['sections', 'sections_imported'],\n ['documents', 'documents_imported'],\n ['rebuilt', 'rebuilt'],\n ['dry_run', 'dry_run'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n\n/** Field map for status result. */\nexport const STATUS_FIELDS: RecfileFieldMap = [\n ['initialized', 'initialized'],\n ['path', 'context_path'],\n ['documents', 'document_count'],\n ['sections', 'section_count'],\n ['content_cached', 'cacheStats.contentCount'],\n ['index_cached', 'cacheStats.indexCount'],\n] as const;\n\n/** Field map for check (integrity) result. */\nexport const CHECK_FIELDS: RecfileFieldMap = [\n ['ok', 'ok'],\n ['sections_checked', 'sections_checked'],\n ['documents_checked', 'documents_checked'],\n ['references_checked', 'references_checked'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n\n/** Field map for gc result. */\nexport const GC_FIELDS: RecfileFieldMap = [\n ['removed_sections', 'removed_sections'],\n ['removed_bytes', 'removed_bytes'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n\n/** Field map for rebuild result. */\nexport const REBUILD_FIELDS: RecfileFieldMap = [\n ['sections_reindexed', 'sections_reindexed'],\n ['terms_indexed', 'terms_indexed'],\n ['elapsed_ms', 'elapsed_ms'],\n] as const;\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { OutputFormat } from '../typings/cli-options.interface.ts';\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\nimport { formatTextOutput } from './format-text-output.function.ts';\nimport { formatMcpOutput } from './format-mcp-output.function.ts';\nimport { formatRecfileOutput } from './format-recfile-output.function.ts';\nimport {\n SEARCH_FIELDS,\n SEARCH_CONTENT_FIELDS,\n} from '../constants/recfile-field-maps.constant.ts';\n\n/**\n * Serialises a paged search result into the requested output\n * format string.\n *\n * @param paged - paginated search results to format\n * @param format - target output format\n * @param content - when true, display full content instead\n * of snippet\n */\nexport function formatOutput(\n paged: PagedSearchDisplay,\n format: OutputFormat,\n content?: boolean,\n): string {\n switch (format) {\n case 'json':\n return JSON.stringify(paged, null, 2);\n case 'text':\n return formatTextOutput(paged, content);\n case 'rec':\n return formatRecfileOutput(\n paged.items,\n content ? SEARCH_CONTENT_FIELDS : SEARCH_FIELDS,\n );\n case 'mcp':\n return formatMcpOutput(paged, content);\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { RecfileFieldMap } from '../typings/recfile-field-map.type.ts';\nimport {\n CHECK_FIELDS,\n EXPORT_FIELDS,\n GC_FIELDS,\n IMPORT_FIELDS,\n LEARN_FIELDS,\n REBUILD_FIELDS,\n RECALL_FIELDS,\n STATUS_FIELDS,\n UNLEARN_FIELDS,\n} from './recfile-field-maps.constant.ts';\n\n/**\n * Looks up the recfile field map for a dispatch command name.\n * Commands without an entry (e.g. `search`, which renders via\n * `formatOutput` instead) fall back to JSON in\n * `formatCommandOutput`.\n */\nexport const RECFILE_COMMAND_FIELD_MAP: Readonly<\n Partial<Record<string, RecfileFieldMap>>\n> = {\n learn: LEARN_FIELDS,\n unlearn: UNLEARN_FIELDS,\n recall: RECALL_FIELDS,\n export: EXPORT_FIELDS,\n import: IMPORT_FIELDS,\n status: STATUS_FIELDS,\n check: CHECK_FIELDS,\n gc: GC_FIELDS,\n rebuild: REBUILD_FIELDS,\n};\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Formats a non-search command result as human-readable\n * text. Each command type has a tailored presentation;\n * unknown commands fall back to pretty-printed JSON.\n *\n * @param data - raw command result\n * @param command - dispatch command name\n */\nfunction str(v: unknown): string {\n if (typeof v === 'string') return v;\n if (typeof v === 'number') return String(v);\n if (typeof v === 'boolean') return String(v);\n if (v == null) return '';\n return JSON.stringify(v);\n}\n\nexport function formatCommandText(\n data: unknown,\n command: string,\n): string {\n const obj = data as Record<string, unknown>;\n switch (command) {\n case 'status':\n return formatStatus(obj);\n case 'check':\n return formatCheck(obj);\n case 'gc':\n return formatGc(obj);\n case 'rebuild':\n return formatRebuild(obj);\n case 'unlearn':\n return formatUnlearn(obj);\n case 'learn':\n return formatLearn(data);\n default:\n return JSON.stringify(data, null, 2);\n }\n}\n\nfunction formatStatus(o: Record<string, unknown>): string {\n const cs = o['cacheStats'] as Record<string, unknown> | undefined;\n const path = o['context_path'] ?? o['contextPath'] ?? '(unknown)';\n const lines = [\n `Initialized: ${str(o['initialized'] ?? false)}`,\n `Path: ${str(path)}`,\n ];\n if (o['document_count'] != null)\n lines.push(`Documents: ${str(o['document_count'])}`);\n if (o['section_count'] != null)\n lines.push(`Sections: ${str(o['section_count'])}`);\n if (cs) {\n lines.push(\n `Content cached: ${str(cs['contentCount'] ?? 0)}`,\n `Index cached: ${str(cs['indexCount'] ?? 0)}`,\n );\n }\n return lines.join('\\n');\n}\n\nfunction formatCheck(o: Record<string, unknown>): string {\n const ok = o['ok'] ? 'OK' : 'FAILED';\n return (\n `Integrity check: ${ok}` +\n ` (${str(o['sections_checked'] ?? 0)} sections,` +\n ` ${str(o['documents_checked'] ?? 0)} documents,` +\n ` ${str(o['references_checked'] ?? 0)} refs,` +\n ` ${str(o['elapsed_ms'] ?? 0)}ms)`\n );\n}\n\nfunction formatGc(o: Record<string, unknown>): string {\n return (\n `GC: removed ${str(o['removed_sections'] ?? 0)}` +\n ` sections, reclaimed` +\n ` ${str(o['removed_bytes'] ?? 0)} bytes` +\n ` (${str(o['elapsed_ms'] ?? 0)}ms)`\n );\n}\n\nfunction formatRebuild(o: Record<string, unknown>): string {\n return (\n `Rebuild: ${str(o['sections_reindexed'] ?? 0)}` +\n ` sections reindexed,` +\n ` ${str(o['terms_indexed'] ?? 0)} terms` +\n ` (${str(o['elapsed_ms'] ?? 0)}ms)`\n );\n}\n\nfunction formatUnlearn(o: Record<string, unknown>): string {\n const removed = o['removed'];\n if (Array.isArray(removed)) {\n return `Removed: ${removed.length.toString()} section(s)`;\n }\n return (\n `Removed: ${str(removed ?? false)}` +\n ` (${str(o['elapsed_ms'] ?? 0)}ms)`\n );\n}\n\nfunction formatLearn(data: unknown): string {\n const obj = data as Record<string, unknown>;\n const items = obj['items'];\n if (Array.isArray(items)) {\n return items.map((id) => `Learned: ${str(id)}`).join('\\n');\n }\n return JSON.stringify(data, null, 2);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { formatCommandText } from './format-command-text.function.ts';\n\n/**\n * Wraps a non-search command result in a JSON-RPC 2.0\n * envelope with a human-readable `text` content block.\n *\n * @param data - raw command result\n * @param command - dispatch command name\n */\nexport function wrapMcpEnvelope(\n data: unknown,\n command: string,\n): string {\n const text = formatCommandText(data, command);\n return JSON.stringify(\n {\n jsonrpc: '2.0',\n result: {\n content: [{ type: 'text', text }],\n },\n },\n null,\n 2,\n );\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { OutputFormat } from '../typings/cli-options.interface.ts';\nimport { formatRecfileOutput } from './format-recfile-output.function.ts';\nimport { RECFILE_COMMAND_FIELD_MAP } from '../constants/recfile-command-field-map.constant.ts';\nimport { formatCommandText } from './format-command-text.function.ts';\nimport { wrapMcpEnvelope } from './wrap-mcp-envelope.function.ts';\n\n/**\n * Formats a command result for the given output format.\n *\n * @param data - the command result to render\n * @param format - target output format\n * @param command - dispatch command name used to look up the\n * recfile field map (e.g. `'learn'`, `'status'`)\n */\nexport function formatCommandOutput(\n data: unknown,\n format: OutputFormat,\n command: string,\n): string {\n switch (format) {\n case 'rec': {\n const fields = RECFILE_COMMAND_FIELD_MAP[command];\n return fields\n ? formatRecfileOutput(data, fields)\n : JSON.stringify(data, null, 2);\n }\n case 'json':\n return JSON.stringify(data, null, 2);\n case 'text':\n return formatCommandText(data, command);\n case 'mcp':\n return wrapMcpEnvelope(data, command);\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** A single raw search result item returned by the daemon. */\ninterface RawSearchItem {\n /** Knowledge-base identifier of the matched section. */\n readonly kbid: string;\n /** Section heading, or null when untitled. */\n readonly heading: string | null;\n /** MIME type of the section content. */\n readonly type: string;\n /** Document IDs this section belongs to. */\n readonly docids: readonly string[];\n /** Relevance score from the ranking engine. */\n readonly score: number;\n /** KWIC excerpt centered on the highest-scoring matched term. */\n readonly snippet: string;\n /** Query terms that matched within this section. */\n readonly matched_terms: readonly string[];\n /**\n * Fields that contained at least one match.\n * May be absent from older daemon versions.\n */\n readonly matched_fields?: readonly string[];\n /**\n * Normalised confidence score (0.0-1.0) relative to the top result.\n * May be absent from older daemon versions.\n */\n readonly confidence?: number;\n /**\n * ISO 8601 creation timestamp of the section.\n * May be absent from older daemon versions.\n */\n readonly created_at?: string;\n}\n\n/** Raw paginated search response from the daemon. */\ninterface RawSearchResponse {\n /** Result items for the current page. */\n readonly items: readonly RawSearchItem[];\n /** Total number of matches across all pages. */\n readonly total: number;\n /** Number of results skipped. */\n readonly offset: number;\n /** Maximum results per page. */\n readonly limit: number;\n /** Whether more results exist beyond this page. */\n readonly has_more: boolean;\n /**\n * When `true`, the engine relaxed the query to produce results.\n * May be absent from older daemon versions.\n */\n readonly relaxed?: boolean;\n /** Server-side computation time in milliseconds. */\n readonly elapsed_ms?: number;\n /** Algorithm that produced these results. */\n readonly search_mode?: string;\n /** Retrieval strategy used (e.g. `'lexical'`, `'rrf'`). */\n readonly retrieval_method?: string;\n}\n\n/**\n * Minimal client interface required by `runSearch`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface SearchClient {\n /**\n * Searches the knowledge base and returns paginated results.\n *\n * @param params - query, mode, limit, and offset\n */\n search(params: {\n query: string;\n mode?: string;\n limit?: number;\n offset?: number;\n algo?: string;\n relaxed?: boolean;\n }): Promise<RawSearchResponse>;\n}\n\n/**\n * Executes a search query via the provided client and maps the\n * daemon results to the `PagedSearchDisplay` format used by the\n * CLI.\n *\n * Returns an empty paged result without calling the client when\n * `options.args` contains no query terms.\n *\n * @param client - search client to delegate to\n * @param options - parsed CLI options supplying query args and\n * search parameters\n */\nexport async function runSearch(\n client: SearchClient,\n options: CliOptions,\n): Promise<PagedSearchDisplay> {\n log('searching: ' + options.args.join(' '), LogLevel.DEBUG);\n const query = options.args.join(' ').trim();\n if (!query) {\n return {\n items: [],\n total: 0,\n offset: 0,\n limit: options.limit,\n has_more: false,\n relaxed: false,\n };\n }\n\n const results = await client.search({\n query,\n mode: options.mode,\n limit: options.limit,\n offset: options.offset,\n algo: options.algo,\n relaxed: options.relaxed,\n });\n\n log(\n 'search returned ' + results.total.toString() + ' results',\n LogLevel.DEBUG,\n );\n\n return {\n items: results.items.map((r) => ({\n kbid: r.kbid,\n heading: r.heading || '(untitled)',\n type: r.type,\n docids: r.docids,\n score: r.score,\n confidence: r.confidence ?? 0,\n snippet: r.snippet,\n matched_terms: r.matched_terms,\n matched_fields: r.matched_fields ?? [],\n created_at: r.created_at ?? '',\n preview: '',\n })),\n total: results.total,\n offset: results.offset,\n limit: results.limit,\n has_more: results.has_more,\n relaxed: results.relaxed ?? false,\n elapsed_ms: results.elapsed_ms,\n search_mode: results.search_mode,\n retrieval_method: results.retrieval_method,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface for listing section kbids.\n *\n * Decouples prefix resolution from the concrete\n * `WorkerClient` so tests can use lightweight mocks.\n */\nexport interface PrefixResolver {\n /** Returns all sections of the given type. */\n listByType(\n sectionType: string,\n ): Promise<readonly { kbid: string }[]>;\n}\n\n/** Section types to scan when resolving a kbid prefix. */\nconst SECTION_TYPES = ['text', 'code', 'image'] as const;\n\n/**\n * Resolves a potentially short kbid prefix to its full\n * 26-character identifier.\n *\n * Full-length identifiers (>= 26 chars) are returned as-is.\n * For shorter prefixes, all section types are scanned to find\n * matching kbids. Throws when no match is found or the prefix\n * is ambiguous (matches more than one kbid).\n *\n * @param prefix - full or partial kbid string\n * @param client - client providing `listByType`\n * @returns the resolved full kbid\n * @throws when no match or ambiguous match is found\n */\nexport async function resolveKbidPrefix(\n prefix: string,\n client: PrefixResolver,\n): Promise<string> {\n if (prefix.length >= 26) return prefix;\n if (prefix.length < 2) {\n const msg =\n `prefix \"${prefix}\" is too short` + ` (minimum 2 characters)`;\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n\n const seen = new Set<string>();\n for (const type of SECTION_TYPES) {\n const records = await client.listByType(type);\n for (const r of records) {\n if (r.kbid.startsWith(prefix)) seen.add(r.kbid);\n }\n }\n\n if (seen.size === 0) {\n const msg =\n `no section matches prefix \"${prefix}\".` +\n ` Try \"kbdb content --search <query>\"` +\n ` to find by keyword`;\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n if (seen.size > 1) {\n const msg =\n `ambiguous prefix \"${prefix}\":` +\n ` ${seen.size.toString()} matches`;\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n\n return [...seen][0];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { RecallResult } from '../../worker-client/typings/recall-result.model.ts';\nimport type { PrefixResolver } from './resolve-kbid-prefix.function.ts';\nimport { resolveKbidPrefix } from './resolve-kbid-prefix.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** Maximum allowed expansion depth for recall operations. */\nconst MAX_RECALL_DEPTH = 3;\n\n/**\n * Minimal client interface required by `runRecall`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n * Extends `PrefixResolver` so short kbid prefixes can be resolved\n * before the recall call is made.\n */\nexport interface RecallClient extends PrefixResolver {\n /**\n * Retrieves full content and context for one or more sections\n * by their knowledge-base identifiers.\n *\n * @param params - section identifier(s) and optional expansion\n * depth (0--3)\n * @returns a single `RecallResult` when `kbid` is supplied, or\n * a `RecallResult[]` when `kbids` is supplied\n */\n recall(params: {\n kbid?: string;\n kbids?: string[];\n depth?: number;\n }): Promise<RecallResult | RecallResult[]>;\n}\n\n/**\n * Retrieves full content and progressive context for one or more\n * sections by kbid via the provided client.\n *\n * Returns an error result when no kbids are provided in\n * `options.args`. Short kbid prefixes in `options.args` are\n * resolved to full identifiers before the recall call. For a single\n * kbid, calls `client.recall` with the `kbid` parameter and returns\n * the single `RecallResult`. For multiple kbids, calls\n * `client.recall` with the `kbids` array.\n *\n * The `depth` option is read from `options.depth`, defaulting to 0\n * and clamped to the range 0--3.\n *\n * @param client - recall client to delegate to\n * @param options - parsed CLI options supplying kbids in `args` and\n * expansion depth in `depth`\n * @returns the `RecallResult` or `RecallResult[]` from the client,\n * or an error object when no kbids are provided\n * @throws when a prefix matches no section or is ambiguous\n */\nexport async function runRecall(\n client: RecallClient,\n options: CliOptions,\n): Promise<RecallResult | RecallResult[] | { error: string }> {\n log('running recall', LogLevel.DEBUG);\n if (options.args.length === 0) {\n return { error: 'no kbid provided' };\n }\n\n const depth = Math.min(\n MAX_RECALL_DEPTH,\n Math.max(0, options.depth ?? 0),\n );\n\n const resolved = await Promise.all(\n options.args.map((a) => resolveKbidPrefix(a, client)),\n );\n\n if (resolved.length === 1) {\n return client.recall({ kbid: resolved[0], depth });\n }\n\n return client.recall({ kbids: resolved, depth });\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { resolve } from 'node:path';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { ExportResult } from '../../worker-client/typings/export-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runExport`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface ExportClient {\n /**\n * Exports the database to the given directory path.\n *\n * @param params - optional absolute target path; the daemon\n * picks its own default, relative to the database directory,\n * when `path` is `undefined`\n * @returns export report with the resolved path and file counts\n */\n export(params: { path?: string }): Promise<ExportResult>;\n}\n\n/**\n * Exports the knowledge-base database to a target directory via the\n * provided client.\n *\n * The target path is taken from `options.args[0]` and resolved\n * against the current working directory so that the daemon --\n * which may run with a different working directory -- always\n * receives an absolute path. When no argument is given, the daemon\n * picks its own default.\n *\n * @param client - export client to delegate to\n * @param options - parsed CLI options whose first positional\n * argument, if present, is the target directory path\n * @returns the export result containing the resolved path and file\n * counts\n */\nexport async function runExport(\n client: ExportClient,\n options: CliOptions,\n): Promise<ExportResult> {\n log('running export', LogLevel.DEBUG);\n const path =\n options.args.length > 0\n ? resolve(process.cwd(), options.args[0])\n : undefined;\n return client.export({ path });\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { readFileSync } from 'node:fs';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { LearnResult } from '../typings/learn-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { collectFiles } from './collect-files.function.ts';\nimport { computeDirectoryLevel } from './compute-directory-level.function.ts';\n\n/** Enriched add-section result returned by the daemon. */\ninterface AddSectionResult {\n /** List of knowledge-base identifiers assigned. */\n readonly items: string[];\n /** Number of items in the result set. */\n readonly total: number;\n /** Offset into the result set (always 0 for learn). */\n readonly offset: number;\n /**\n * Kbid of the section superseded via `--replace`,\n * or `null` / `undefined` when none.\n */\n readonly superseded?: string | null;\n /**\n * Advisory warning strings (e.g. `\"heading_missing\"`).\n * May be absent from older daemon versions.\n */\n readonly warnings?: string[];\n /**\n * Near-duplicate sections with similarity >= 0.85.\n * May be absent from older daemon versions.\n */\n readonly near_duplicates?: {\n readonly kbid: string;\n readonly similarity: number;\n }[];\n}\n\n/**\n * Minimal client interface required by `runLearn`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface LearnClient {\n /**\n * Ingests a content section into the knowledge base.\n *\n * @param params - section metadata and raw text content\n * @returns enriched result containing the new kbid plus\n * optional supersession, warnings, and near-duplicate info\n */\n addSection(params: {\n sectionType: string;\n content: string;\n title?: string;\n description?: string;\n docid?: string;\n tags?: string[];\n replace?: boolean;\n sourcePath?: string;\n level?: number;\n }): Promise<AddSectionResult>;\n}\n\n/** Injectable I/O for testing without real stdin. */\nexport interface LearnIO {\n readStdin: () => Promise<string>;\n}\n\n/**\n * Ingests one or more files or directories listed in `options.args`\n * into the knowledge base via the provided client.\n *\n * Each argument is resolved to a set of supported files. Unsupported\n * extensions, dotfiles, dot-directories, and non-existent paths are\n * silently skipped. The `-` argument reads content from stdin\n * (consumed only once).\n *\n * When `options.level` is unset, the level sent for each file is\n * auto-detected from its depth relative to the target argument\n * (root = 1, each subdirectory +1, capped at 6). Stdin input has no\n * directory to derive a level from, so it is sent unset unless\n * `options.level` is explicit.\n *\n * @param client - learn client to delegate ingestion to\n * @param options - parsed CLI options whose `args` list targets to\n * ingest\n * @param io - injectable I/O (defaults to reading process.stdin)\n * @returns one `LearnResult` per file successfully ingested\n */\nexport async function runLearn(\n client: LearnClient,\n options: CliOptions,\n io?: LearnIO,\n): Promise<LearnResult[]> {\n log(\n 'learning ' + options.args.length.toString() + ' targets',\n LogLevel.DEBUG,\n );\n const results: LearnResult[] = [];\n let stdinConsumed = false;\n const readStdin = io?.readStdin ?? readProcessStdin;\n\n for (const target of options.args) {\n if (target === '-') {\n if (stdinConsumed) continue;\n stdinConsumed = true;\n const content = await readStdin();\n const result = await client.addSection({\n sectionType: 'text',\n content,\n title: options.title,\n description: options.description,\n docid: options.docid,\n tags: options.tags,\n replace: options.replace,\n level: options.level,\n });\n results.push(\n mapAddSectionResult(result, '-', content.length, 'text'),\n );\n continue;\n }\n\n const files = collectFiles(target);\n for (const file of files) {\n const content = readFileSync(file, 'utf-8');\n const result = await client.addSection({\n sectionType: 'text',\n content,\n title: options.title,\n description: options.description,\n docid: options.docid,\n tags: options.tags,\n replace: options.replace,\n sourcePath: file,\n level: options.level ?? computeDirectoryLevel(file, target),\n });\n results.push(\n mapAddSectionResult(result, file, content.length, 'text'),\n );\n }\n }\n\n log(\n 'learned ' + results.length.toString() + ' sections',\n LogLevel.DEBUG,\n );\n return results;\n}\n\n/**\n * Maps an `AddSectionResult` to a `LearnResult` record.\n *\n * @param result - raw result from `client.addSection()`\n * @param path - source file path or `'-'` for stdin\n * @param size - UTF-8 character count of the ingested content\n * @param sectionType - semantic type used for ingestion\n */\nfunction mapAddSectionResult(\n result: AddSectionResult,\n path: string,\n size: number,\n sectionType: string,\n): LearnResult {\n return {\n kbid: result.items[0] ?? '',\n indexed_terms_count: 0,\n type: sectionType,\n path,\n size,\n skipped: false,\n superseded: result.superseded ?? null,\n warnings: result.warnings ?? [],\n near_duplicates: result.near_duplicates ?? [],\n };\n}\n\nfunction readProcessStdin(): Promise<string> {\n return new Promise<string>((resolve) => {\n const chunks: Buffer[] = [];\n process.stdin.on('data', (chunk: Buffer) => {\n chunks.push(chunk);\n });\n process.stdin.on('end', () => {\n resolve(Buffer.concat(chunks).toString('utf-8'));\n });\n process.stdin.resume();\n });\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { readdirSync, statSync } from 'node:fs';\nimport { basename, extname, join } from 'node:path';\nimport { SUPPORTED_EXTENSIONS } from '../constants/defaults.constant.ts';\n\n/**\n * Resolves a single target path to a flat list of supported files.\n *\n * When `target` is a file, returns it wrapped in an array if its\n * extension is in `SUPPORTED_EXTENSIONS` and it is not a dotfile;\n * otherwise returns `[]`. When `target` is a directory, recursively\n * collects all matching files, skipping dot-entries at every level.\n * Returns `[]` for non-existent or inaccessible paths.\n *\n * @param target - file or directory path to resolve\n * @returns flat array of absolute or relative paths to supported files\n */\nexport function collectFiles(target: string): string[] {\n try {\n const stat = statSync(target);\n if (stat.isFile()) {\n return isSupportedFile(target) ? [target] : [];\n }\n if (stat.isDirectory()) {\n return scanDirectory(target);\n }\n } catch {\n // Non-existent or inaccessible path -- skip\n }\n return [];\n}\n\nfunction scanDirectory(dir: string): string[] {\n const files: string[] = [];\n for (const entry of readdirSync(dir)) {\n if (entry.startsWith('.')) continue;\n const full = join(dir, entry);\n try {\n const stat = statSync(full);\n if (stat.isDirectory()) {\n files.push(...scanDirectory(full));\n } else if (isSupportedFile(full)) {\n files.push(full);\n }\n } catch {\n // Skip inaccessible entries\n }\n }\n return files;\n}\n\nfunction isSupportedFile(path: string): boolean {\n if (basename(path).startsWith('.')) return false;\n const ext = extname(path).toLowerCase();\n return (SUPPORTED_EXTENSIONS as readonly string[]).includes(ext);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Maximum hierarchical level. Deeper paths are clamped to this. */\nconst MAX_LEVEL = 6;\n\n/**\n * Derives a hierarchical level (1-6) from a file's depth relative\n * to the target path it was learned from.\n *\n * A file at the root of `basePath` is level 1; each intervening\n * subdirectory adds one level, up to `MAX_LEVEL`. When `filePath`\n * equals `basePath` (a single file target), the result is 1.\n *\n * @param filePath - absolute path to the file being learned\n * @param basePath - the target path originally passed on the CLI\n * (a file or directory)\n * @returns the computed level, clamped between 1 and `MAX_LEVEL`\n */\nexport function computeDirectoryLevel(\n filePath: string,\n basePath: string,\n): number {\n const relative = filePath.slice(basePath.length).replace(/^\\//, '');\n const depth = relative.split('/').length - 1;\n return Math.min(depth + 1, MAX_LEVEL);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { PrefixResolver } from './resolve-kbid-prefix.function.ts';\nimport { resolveKbidPrefix } from './resolve-kbid-prefix.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** Removal result returned by `UnlearnClient.removeSection`. */\ninterface RemoveSectionResult {\n /** `true` when the section was found and successfully removed. */\n readonly removed: boolean;\n /** Time taken to perform the removal, in milliseconds. */\n readonly elapsed_ms: number;\n}\n\n/**\n * Minimal client interface required by `runUnlearn`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n * Extends `PrefixResolver` so short kbid prefixes can be resolved\n * before each section is removed.\n */\nexport interface UnlearnClient extends PrefixResolver {\n /**\n * Removes a section from the knowledge base.\n *\n * @param kbid - identifier of the section to remove\n * @returns removal result with `removed` flag and elapsed time\n */\n removeSection(kbid: string): Promise<RemoveSectionResult>;\n}\n\n/** Result record produced for each kbid processed by the unlearn command. */\nexport interface UnlearnResult {\n /** Knowledge-base identifier that was targeted for removal. */\n kbid: string;\n /** `true` when the section was found and successfully removed. */\n removed: boolean;\n}\n\n/**\n * Removes the knowledge-base sections identified by `options.args`\n * via the provided client.\n *\n * Short kbid prefixes in `options.args` are resolved to full\n * identifiers before removal. Each kbid is processed independently.\n * If a kbid does not exist in the knowledge base, `removed` is set\n * to `false` rather than throwing.\n *\n * @param client - unlearn client to delegate removal to\n * @param options - parsed CLI options whose `args` list the kbids to\n * remove\n * @returns one `UnlearnResult` per kbid processed\n * @throws when a prefix matches no section or is ambiguous\n */\nexport async function runUnlearn(\n client: UnlearnClient,\n options: CliOptions,\n): Promise<UnlearnResult[]> {\n log('running unlearn', LogLevel.DEBUG);\n const results: UnlearnResult[] = [];\n for (const arg of options.args) {\n const kbid = await resolveKbidPrefix(arg, client);\n const result = await client.removeSection(kbid);\n results.push({ kbid, removed: result.removed });\n }\n return results;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { PrefixResolver } from './resolve-kbid-prefix.function.ts';\nimport { resolveKbidPrefix } from './resolve-kbid-prefix.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** Result returned by content composition. */\ninterface ContentResult {\n /** MIME type of the composed output, always `'text/markdown'`. */\n readonly type: 'text/markdown';\n /** The composed Markdown string. */\n readonly data: string;\n /** Character count of `data` (not byte count). */\n readonly total: number;\n}\n\n/** Minimal search result shape needed to extract kbids. */\ninterface SearchHit {\n readonly kbid: string;\n}\n\n/** Paged search result with items array. */\ninterface SearchResult {\n readonly items: readonly SearchHit[];\n}\n\n/**\n * Minimal client interface required by `runContent`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n * Extends `PrefixResolver` so short kbid prefixes can be resolved\n * before the content call is made.\n */\nexport interface ContentClient extends PrefixResolver {\n /** Composes rendered Markdown from identifiers. */\n content(ids: string[]): Promise<ContentResult>;\n\n /** Searches the knowledge base by query. */\n search(params: {\n query: string;\n limit?: number;\n }): Promise<SearchResult>;\n}\n\n/**\n * Composes and returns a rendered Markdown document from the\n * identifiers listed in `options.args`.\n *\n * When `options.search` is set, the args are joined as a\n * search query and results are resolved to kbids before\n * composing content.\n *\n * @param client - content client to delegate composition to\n * @param options - parsed CLI options\n */\nexport async function runContent(\n client: ContentClient,\n options: CliOptions,\n): Promise<ContentResult> {\n log('running content', LogLevel.DEBUG);\n\n if (options.search) {\n return runContentSearch(client, options);\n }\n\n const resolved = await Promise.all(\n options.args.map((a) => resolveKbidPrefix(a, client)),\n );\n return client.content(resolved);\n}\n\nasync function runContentSearch(\n client: ContentClient,\n options: CliOptions,\n): Promise<ContentResult> {\n const query = options.args.join(' ');\n const result = await client.search({\n query,\n limit: options.limit,\n });\n const kbids = result.items.map((hit) => hit.kbid);\n if (kbids.length === 0) {\n return { type: 'text/markdown', data: '', total: 0 };\n }\n return client.content(kbids);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** A single integrity error found during a database check. */\ninterface IntegrityError {\n /**\n * The category of integrity violation detected.\n *\n * - `'checksum_mismatch'` -- stored content does not match its hash\n * - `'orphan_section'` -- section not referenced by any document\n * - `'orphan_document'` -- document references no existing sections\n * - `'broken_reference'` -- a marker references a non-existent entity\n * - `'type_mismatch'` -- stored MIME type conflicts with content\n * - `'circular_reference'` -- marker chain contains a cycle\n */\n readonly type:\n | 'checksum_mismatch'\n | 'orphan_section'\n | 'orphan_document'\n | 'broken_reference'\n | 'type_mismatch'\n | 'circular_reference'\n | 'divergent_content';\n /** Identifier of the entity (kbid or docid) that has the issue. */\n readonly entity: string;\n /** Human-readable description of the specific problem. */\n readonly detail: string;\n}\n\n/**\n * A single entry in the divergent-content map.\n * Groups kbids under a common source key.\n */\ninterface DivergentContentEntry {\n /** Source key that has multiple divergent content versions. */\n readonly sourceKey: string;\n /** Kbids of sections sharing this source key but with different content. */\n readonly kbids: string[];\n}\n\n/**\n * Integrity check report returned by the daemon.\n */\ninterface IntegrityCheckResult {\n /** `true` when all checks passed and no errors were found. */\n readonly ok: boolean;\n /** All integrity errors found; empty when `ok` is `true`. */\n readonly errors: IntegrityError[];\n /** Total number of sections examined. */\n readonly sections_checked: number;\n /** Total number of documents examined. */\n readonly documents_checked: number;\n /** Total number of marker references checked. */\n readonly references_checked: number;\n /** Time taken to complete the check, in milliseconds. */\n readonly elapsed_ms: number;\n /**\n * Sections that share a source key but have divergent content.\n * Each entry groups the kbids under a common source key.\n * Empty when no divergent content is found.\n */\n readonly divergent_content: DivergentContentEntry[];\n}\n\n/** Raw daemon response from `integrityCheck`. */\ninterface RawIntegrityCheckResult {\n /** `true` when all checks passed and no errors were found. */\n readonly ok: boolean;\n /** All integrity errors found; empty when `ok` is `true`. */\n readonly errors: IntegrityError[];\n /** Total number of sections examined. */\n readonly sections_checked: number;\n /** Total number of documents examined. */\n readonly documents_checked: number;\n /** Total number of marker references checked. */\n readonly references_checked: number;\n /** Time taken to complete the check, in milliseconds. */\n readonly elapsed_ms: number;\n /**\n * Encoded divergent-content map.\n *\n * Format: `sk1:kbid1,kbid2;sk2:kbid3,kbid4`\n *\n * Each semicolon-separated segment is a source key followed by\n * a colon and a comma-separated list of kbids. Absent when no\n * divergent content exists.\n */\n readonly divergent_content?: string;\n}\n\n/**\n * Minimal client interface required by `runCheck`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface CheckClient {\n /**\n * Runs an integrity check on the knowledge-base database.\n *\n * @returns a report of all issues found; `ok` is `true` when\n * no errors were detected\n */\n integrityCheck(): Promise<RawIntegrityCheckResult>;\n}\n\n/**\n * Parses the encoded `divergent_content` string from the daemon\n * into a structured array.\n *\n * Input format: `sk1:kbid1,kbid2;sk2:kbid3,kbid4`\n *\n * @param encoded - raw encoded string, or empty / absent\n * @returns structured entries grouped by source key\n */\nfunction parseDivergentContent(\n encoded: string | undefined,\n): DivergentContentEntry[] {\n if (!encoded) return [];\n return encoded\n .split(';')\n .filter((segment) => segment.includes(':'))\n .map((segment) => {\n const colonIdx = segment.indexOf(':');\n const sourceKey = segment.slice(0, colonIdx);\n const kbids = segment\n .slice(colonIdx + 1)\n .split(',')\n .filter((k) => k.length > 0);\n return { sourceKey, kbids };\n })\n .filter((entry) => entry.kbids.length > 0);\n}\n\n/**\n * Runs an integrity check on the database and returns the report.\n *\n * Delegates to `client.integrityCheck()`, then parses the encoded\n * `divergent_content` field into structured form. The caller is\n * responsible for printing the result to stdout and setting the\n * process exit code based on `result.ok`.\n *\n * @param client - check client to delegate to\n * @param _options - parsed CLI options (unused; reserved for future flags)\n * @returns the integrity check report with parsed `divergent_content`\n */\nexport async function runCheck(\n client: CheckClient,\n _options: CliOptions,\n): Promise<IntegrityCheckResult> {\n log('running check', LogLevel.DEBUG);\n const raw = await client.integrityCheck();\n const divergent = parseDivergentContent(raw.divergent_content);\n const divergentErrors: IntegrityError[] = divergent.map((d) => ({\n type: 'divergent_content' as const,\n entity: d.sourceKey,\n detail:\n `${d.kbids.length.toString()} divergent sections:` +\n ` ${d.kbids.join(', ')}`,\n }));\n const errors = [...raw.errors, ...divergentErrors];\n return {\n ok: raw.ok && errors.length === 0,\n errors,\n sections_checked: raw.sections_checked,\n documents_checked: raw.documents_checked,\n references_checked: raw.references_checked,\n elapsed_ms: raw.elapsed_ms,\n divergent_content: divergent,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Garbage collection report returned by the daemon.\n */\ninterface GcResult {\n /** Number of unreferenced sections removed. */\n readonly removed_sections: number;\n /** Total bytes freed by removing unreferenced sections. */\n readonly removed_bytes: number;\n /** Time taken to complete garbage collection, in milliseconds. */\n readonly elapsed_ms: number;\n /**\n * Number of sections whose `source_path` file no longer\n * contains their heading text (advisory; not auto-removed).\n * Absent on older daemon versions.\n */\n readonly stale_sources?: number;\n}\n\n/**\n * Minimal client interface required by `runGc`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface GcClient {\n /**\n * Removes unreferenced sections from the database.\n *\n * @returns a report of sections removed and bytes freed\n */\n gc(): Promise<GcResult>;\n}\n\n/**\n * Runs garbage collection on the database and returns the report.\n *\n * Delegates to `client.gc()`. The caller is responsible for printing\n * the result to stdout.\n *\n * @param client - gc client to delegate to\n * @param _options - parsed CLI options (unused; reserved for future flags)\n * @returns the garbage collection report from the daemon\n */\nexport async function runGc(\n client: GcClient,\n _options: CliOptions,\n): Promise<GcResult> {\n log('running gc', LogLevel.DEBUG);\n return client.gc();\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Index rebuild report returned by the daemon.\n */\ninterface RebuildResult {\n /** Number of text and code sections that were re-indexed. */\n readonly sections_reindexed: number;\n /** Total number of unique terms written to the rebuilt indexes. */\n readonly terms_indexed: number;\n /** Time taken to complete the rebuild, in milliseconds. */\n readonly elapsed_ms: number;\n}\n\n/**\n * Minimal client interface required by `runRebuild`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface RebuildClient {\n /**\n * Reconstructs all index files from section files and document\n * manifests on disk. Text and code sections are re-tokenized;\n * image sections are skipped.\n *\n * @returns a report of sections and terms re-indexed\n */\n rebuildIndexes(): Promise<RebuildResult>;\n}\n\n/**\n * Rebuilds all database indexes and returns the report.\n *\n * Delegates to `client.rebuildIndexes()`. The caller is responsible\n * for printing the result to stdout.\n *\n * @param client - rebuild client to delegate to\n * @param _options - parsed CLI options (unused; reserved for future flags)\n * @returns the index rebuild report from the daemon\n */\nexport async function runRebuild(\n client: RebuildClient,\n _options: CliOptions,\n): Promise<RebuildResult> {\n log('running rebuild', LogLevel.DEBUG);\n return client.rebuildIndexes();\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync } from 'node:fs';\nimport { dirname, join, resolve } from 'node:path';\n\n/**\n * Locates the `.kbdb` database directory.\n *\n * When `dbPath` is provided, checks only that directory.\n * When omitted, walks up from the current working directory\n * until a `.kbdb` directory is found or the filesystem root\n * is reached.\n *\n * @param dbPath - explicit base directory; skips traversal\n * @returns absolute path to `.kbdb`, or `null` when not found\n */\nexport function findDb(dbPath?: string): string | null {\n if (dbPath) {\n const target = join(resolve(dbPath), '.kbdb');\n return existsSync(target) ? target : null;\n }\n let current = process.cwd();\n let parent = dirname(current);\n while (parent !== current) {\n const candidate = join(current, '.kbdb');\n if (existsSync(candidate)) return candidate;\n current = parent;\n parent = dirname(current);\n }\n const candidate = join(current, '.kbdb');\n return existsSync(candidate) ? candidate : null;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { installDefaultSkills } from './install-default-skills.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Result returned by `runInit` describing whether the directory was\n * successfully initialised.\n */\nexport interface InitResult {\n /** `true` when the database directory was created successfully. */\n readonly ok: boolean;\n /** Absolute path to the directory that was (or should have been) initialised. */\n readonly targetPath: string;\n /**\n * Human-readable error message when `ok` is `false`.\n * `undefined` when `ok` is `true`.\n */\n readonly errorMessage?: string;\n}\n\nconst DB_FORMAT_VERSION = 1;\n\nconst CATALOG_TOML = `version = ${DB_FORMAT_VERSION.toString()}\nsection_count = 0\ndocument_count = 0\ncreated_at = 0\nupdated_at = 0\nchecksum = \"\"\n`;\n\nconst WORKER_TOML = '# kbdb worker configuration\\n';\n\nconst GITIGNORE = [\n '# kbdb binary indexes (auto-generated)',\n 'corpus.bin',\n 'inverted.idx',\n 'positional.idx',\n '',\n].join('\\n');\n\n/**\n * Creates the `.kbdb` directory scaffold directly on disk.\n *\n * This mirrors the Rust `init_directory` in\n * `engine/crates/fs-database/src/scaffold.rs` and does not\n * require a running worker daemon.\n */\nfunction createScaffold(dbDir: string): void {\n mkdirSync(dbDir, { recursive: true });\n mkdirSync(join(dbDir, 'sections'));\n mkdirSync(join(dbDir, 'documents'));\n writeFileSync(join(dbDir, 'catalog.toml'), CATALOG_TOML);\n writeFileSync(join(dbDir, 'corpus.bin'), '');\n writeFileSync(join(dbDir, 'inverted.idx'), '');\n writeFileSync(join(dbDir, 'positional.idx'), '');\n writeFileSync(join(dbDir, 'worker.toml'), WORKER_TOML);\n writeFileSync(join(dbDir, '.gitignore'), GITIGNORE);\n}\n\n/**\n * Initialises a new `.kbdb` database directory.\n *\n * Creates the full scaffold directly on disk without requiring a\n * running worker daemon. Resolves the target path from\n * `options.dbPath` or `process.cwd()`.\n *\n * @param options - parsed CLI options supplying the optional `dbPath`\n * @returns init result indicating success or failure\n */\nexport function runInit(options: CliOptions): InitResult {\n log('running init', LogLevel.DEBUG);\n const basePath = options.dbPath\n ? resolve(options.dbPath)\n : process.cwd();\n const dbDir = join(basePath, '.kbdb');\n\n try {\n if (existsSync(dbDir)) {\n return {\n ok: false,\n targetPath: dbDir,\n errorMessage: `database directory already exists: ${dbDir}`,\n };\n }\n createScaffold(dbDir);\n installDefaultSkills(dbDir);\n return { ok: true, targetPath: dbDir };\n } catch (err: unknown) {\n const errorMessage =\n err instanceof Error ? err.message : String(err);\n return { ok: false, targetPath: dbDir, errorMessage };\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { createHash } from 'node:crypto';\nimport { existsSync, mkdirSync, writeFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\n/**\n * RFC 4648 base32 alphabet (upper-case, no padding).\n * Used to encode the SHA-256-derived kbid bytes.\n */\nconst BASE32_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567';\n\n/**\n * Encodes a byte array as a lowercase base32 string without padding.\n *\n * Mirrors the `data_encoding::BASE32_NOPAD` encoding used in the\n * Rust engine's `KbId::from_content`.\n *\n * @param bytes - raw bytes to encode\n * @returns lowercase base32-encoded string\n */\nfunction base32Encode(bytes: Uint8Array): string {\n let result = '';\n let bits = 0;\n let value = 0;\n for (const byte of bytes) {\n value = (value << 8) | byte;\n bits += 8;\n while (bits >= 5) {\n result += BASE32_ALPHABET[(value >>> (bits - 5)) & 0x1f];\n bits -= 5;\n }\n }\n if (bits > 0) {\n result += BASE32_ALPHABET[(value << (5 - bits)) & 0x1f];\n }\n return result.toLowerCase();\n}\n\n/**\n * Computes a 26-character kbid for a section using the same algorithm\n * as the Rust engine's `hash_section`.\n *\n * Algorithm:\n * 1. Build input: `\"section <mime> <byteLen>\\0<content>\"`\n * 2. SHA-256 hash the input\n * 3. Take the first 16 bytes\n * 4. Base32 encode (RFC 4648, no padding), lowercased \u2192 26 chars\n *\n * @param mimeType - MIME type string (e.g. `\"text/markdown\"`)\n * @param content - UTF-8 section content string\n * @returns 26-character lowercase base32 kbid\n */\nfunction computeSectionKbid(mimeType: string, content: string): string {\n const contentBytes = Buffer.from(content, 'utf-8');\n const header = `section ${mimeType} ${contentBytes.length.toString()}\\0`;\n const headerBytes = Buffer.from(header, 'utf-8');\n const input = Buffer.concat([headerBytes, contentBytes]);\n const hash = createHash('sha256').update(input).digest();\n const truncated = new Uint8Array(hash.buffer, 0, 16);\n return base32Encode(truncated);\n}\n\n/**\n * Escapes backslashes and double-quotes in a string for TOML inline\n * string values.\n *\n * Mirrors the `escape_toml_str` function in the Rust engine.\n *\n * @param s - string to escape\n * @returns escaped string safe for use inside TOML double-quoted strings\n */\nfunction escapeToml(s: string): string {\n return s.replace(/\\\\/g, '\\\\\\\\').replace(/\"/g, '\\\\\"');\n}\n\n/**\n * Serializes a skill section record to the `.section` file format.\n *\n * Format:\n * ```\n * kbid = \"...\"\n * section_type = \"text/markdown\"\n * type_name = \"skill\"\n * title = \"...\"\n * description = \"...\"\n * size = 0\n * token_count = 0\n * heading_token_count = 0\n * body_token_count = 0\n * code_token_count = 0\n * created_at = 0\n * checksum = \"...\"\n *\n * ---\n * <json content>\n * ```\n *\n * @param kbid - 26-char content-addressed identifier\n * @param title - skill name used as section title\n * @param description - human-readable description\n * @param content - serialised JSON skill definition\n * @returns file content string\n */\nfunction serializeSkillSection(\n kbid: string,\n title: string,\n description: string,\n content: string,\n): string {\n const size = Buffer.byteLength(content, 'utf-8');\n const header = [\n `kbid = \"${escapeToml(kbid)}\"`,\n `section_type = \"text/markdown\"`,\n `type_name = \"skill\"`,\n `title = \"${escapeToml(title)}\"`,\n `description = \"${escapeToml(description)}\"`,\n `size = ${size.toString()}`,\n `token_count = 0`,\n `heading_token_count = 0`,\n `body_token_count = 0`,\n `code_token_count = 0`,\n `created_at = 0`,\n `checksum = \"${escapeToml(kbid)}\"`,\n '',\n ].join('\\n');\n return `${header}\\n---\\n${content}`;\n}\n\n/** Descriptor for a skill to install. */\ninterface SkillDescriptor {\n /** Unique skill name (kebab-case). */\n readonly name: string;\n /** Human-readable description. */\n readonly description: string;\n /** Template body text. */\n readonly body: string;\n}\n\n/**\n * Installs a single skill section file under `sectionsDir`.\n *\n * Creates the shard subdirectory if it does not exist. Skips\n * writing if the section file already exists, preserving any\n * user modifications.\n *\n * @param sectionsDir - absolute path to `.kbdb/sections`\n * @param skill - skill definition to serialise and store\n */\nfunction installSkill(\n sectionsDir: string,\n skill: SkillDescriptor,\n): void {\n const content = JSON.stringify({\n name: skill.name,\n description: skill.description,\n arguments: [],\n body: skill.body,\n });\n const kbid = computeSectionKbid('text/markdown', content);\n const prefix = kbid.slice(0, 2);\n const shardDir = join(sectionsDir, prefix);\n const filePath = join(shardDir, `${kbid}.section`);\n\n if (existsSync(filePath)) {\n return;\n }\n\n mkdirSync(shardDir, { recursive: true });\n\n const fileContent = serializeSkillSection(\n kbid,\n skill.name,\n skill.description,\n content,\n );\n writeFileSync(filePath, fileContent, 'utf-8');\n}\n\n/**\n * Body text for the `query-guidance` default skill.\n *\n * Teaches AI agents how to effectively search the knowledge base\n * using lexical BM25F queries.\n */\nconst QUERY_GUIDANCE_BODY =\n 'This knowledge base uses lexical search (stemmed BM25F), not' +\n ' semantic/vector search. Follow these guidelines for effective' +\n ' retrieval:\\n\\n' +\n '1. Issue MULTIPLE short keyword queries rather than one long' +\n ' natural-language question. Each query should target 2-3' +\n ' specific terms.\\n\\n' +\n '2. EXPAND SYNONYMS yourself. \"login\" will not match \"sign-in\"' +\n ' unless both terms appear in the content. Try alternative' +\n ' phrasings: search for \"login\", then \"sign-in\", then' +\n ' \"authentication\".\\n\\n' +\n '3. USE BOOLEAN AND PHRASE SYNTAX:\\n' +\n ' - Exact phrases: \"error handling\"\\n' +\n ' - Boolean AND: auth AND token\\n' +\n ' - Boolean OR: cache OR redis\\n' +\n ' - Exclusion: auth -oauth\\n\\n' +\n '4. LEAN ON HEADINGS. Headings carry 2x weight in ranking.' +\n ' Search for terms that are likely in section titles.\\n\\n' +\n '5. STEMMING IS AUTOMATIC. \"connections\" matches \"connect\",' +\n ' \"running\" matches \"run\". You do not need to try inflected' +\n ' forms.\\n\\n' +\n '6. USE RECALL AFTER SEARCH. After finding relevant sections' +\n ' with search, use recall with increasing depth (0-3) to' +\n ' progressively expand context: depth 0 = full content, depth' +\n ' 1 = parent documents + back-references, depth 2 = siblings' +\n ' + forward references, depth 3 = referenced sections.\\n\\n' +\n '7. CODE IDENTIFIERS ARE SPLIT. camelCase and snake_case names' +\n ' are decomposed: getUserById becomes searchable as \"get\",' +\n ' \"user\", \"by\", \"id\".\\n\\n' +\n '8. PAGINATION. Default limit is 20 results. Use offset for' +\n ' additional pages if total > limit.';\n\n/**\n * Body text for the `memory-protocol` default skill.\n *\n * Teaches AI agents when and what to store in the knowledge base\n * to keep it accurate and useful.\n */\nconst MEMORY_PROTOCOL_BODY =\n 'Follow these guidelines to keep the knowledge base accurate' +\n ' and useful:\\n\\n' +\n '1. STORE DURABLE FACTS: decisions, architecture choices,' +\n ' configuration values, corrections to prior knowledge, API' +\n ' contracts, and resolved incidents. These are the facts that' +\n ' matter weeks later.\\n\\n' +\n '2. DO NOT STORE: transient conversation context, debugging' +\n ' output, ephemeral task state, raw log dumps, or information' +\n ' that changes every session. The brain should contain' +\n ' knowledge, not activity logs.\\n\\n' +\n '3. SEARCH BEFORE STORING. Always search the knowledge base' +\n ' before adding new content. If a section already covers the' +\n ' topic, use learn with --replace to update it rather than' +\n ' creating a duplicate.\\n\\n' +\n '4. USE --replace FOR CORRECTIONS. When a fact changes (e.g.,' +\n ' rate limit updated from 100 to 200 req/min), re-learn the' +\n ' corrected content with --replace so the old version is' +\n ' superseded. Without --replace, both the old and new versions' +\n ' coexist with equal ranking.\\n\\n' +\n '5. ATTACH TAGS for scoping. Use tags like project name,' +\n ' domain, or topic (e.g., --tags auth,api,v2) so queries can' +\n ' be filtered by scope later.\\n\\n' +\n '6. PREFER RECENT RESULTS. When search returns multiple' +\n ' sections covering the same topic, prefer the one with the' +\n ' most recent created_at timestamp -- it is more likely to' +\n ' reflect the current state.\\n\\n' +\n '7. USE RECALL AFTER SEARCH. After finding relevant sections,' +\n ' use recall with increasing depth (0-3) to expand context' +\n ' progressively before making decisions.\\n\\n' +\n '8. INCLUDE HEADINGS. Always provide a descriptive title when' +\n ' storing content. Headings carry 2x ranking weight -- omitting' +\n ' them significantly reduces searchability.';\n\n/**\n * Default skills installed on every fresh `kbdb db init`.\n *\n * These provide baseline guidance that improves AI agent\n * effectiveness out of the box. They are regular skill sections\n * and can be deleted by users.\n */\nconst DEFAULT_SKILLS: readonly SkillDescriptor[] = [\n {\n name: 'query-guidance',\n description:\n 'How to effectively search this knowledge base.' +\n ' Read this before issuing search queries.',\n body: QUERY_GUIDANCE_BODY,\n },\n {\n name: 'memory-protocol',\n description:\n 'Guidelines for what to store in this knowledge base' +\n ' and when. Read this before using the learn tool.',\n body: MEMORY_PROTOCOL_BODY,\n },\n];\n\n/**\n * Writes the two default skills (`query-guidance` and\n * `memory-protocol`) as section files directly into the `.kbdb`\n * directory scaffold.\n *\n * Called by `runInit` after the directory scaffold is created.\n * Does not require a running worker daemon. Skips any skill whose\n * section file already exists so user modifications are preserved.\n *\n * @param dbDir - absolute path to the `.kbdb` directory\n */\nexport function installDefaultSkills(dbDir: string): void {\n const sectionsDir = join(dbDir, 'sections');\n for (const skill of DEFAULT_SKILLS) {\n installSkill(sectionsDir, skill);\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Converts an unknown thrown value to a human-readable message.\n *\n * @param err - the caught value\n * @returns the error message string\n */\nexport function errorToMessage(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Returns `true` when stdin is an interactive terminal.\n *\n * @param stdin - readable stream to check (defaults to\n * `process.stdin`)\n */\nexport function isStdinTty(\n stdin: NodeJS.ReadStream = process.stdin,\n): boolean {\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- isTTY is undefined at runtime for non-TTY despite Node types saying boolean\n return stdin.isTTY ?? false;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { createInterface } from 'node:readline';\n\n/** Injectable I/O for testing without real stdin. */\nexport interface PromptIO {\n ask: (question: string) => Promise<string>;\n}\n\n/**\n * Prompts the user on stdin (TTY only) and returns the\n * trimmed reply.\n *\n * @param question - the prompt text to display\n * @param io - injectable I/O (defaults to readline on\n * process.stdin/stdout)\n */\nexport async function promptUser(\n question: string,\n io?: PromptIO,\n): Promise<string> {\n const ask = io?.ask ?? askReadline;\n const answer = await ask(question);\n return answer.trim();\n}\n\nfunction askReadline(question: string): Promise<string> {\n return new Promise<string>((resolve) => {\n const rl = createInterface({\n input: process.stdin,\n output: process.stdout,\n });\n rl.question(question, (answer) => {\n rl.close();\n resolve(answer);\n });\n });\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runStatus`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface StatusClient {\n dbStatus(): Promise<unknown>;\n}\n\n/**\n * Retrieves the database status and returns the summary report.\n *\n * Delegates to `client.dbStatus()`. The caller is responsible\n * for serialising the result and setting the process exit code.\n *\n * @param client - status client to delegate to\n * @param _options - parsed CLI options (unused; reserved for\n * future flags)\n * @returns the status report from the daemon\n */\nexport async function runStatus(\n client: StatusClient,\n _options: CliOptions,\n): Promise<unknown> {\n log('running status', LogLevel.DEBUG);\n return client.dbStatus();\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { InitResult } from './run-init.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Callable signature for the init operation injected into\n * `runDbInit`.\n */\nexport type RunInitFn = (options: CliOptions) => InitResult;\n\n/**\n * Executes the `db init` compound command by delegating to the\n * provided `runInit` function and mapping the result to a\n * `CommandResult`.\n *\n * Accepts `runInit` as an injectable parameter so the function\n * can be tested without touching the filesystem.\n *\n * @param options - parsed CLI options (forwarded to `runInitFn`)\n * @param runInitFn - function that performs the actual\n * initialisation\n * @returns a `CommandResult` with JSON output on success or an\n * error message on failure\n */\nexport function runDbInit(\n options: CliOptions,\n runInitFn: RunInitFn,\n): CommandResult {\n log('running db-init', LogLevel.DEBUG);\n const result = runInitFn(options);\n if (result.ok) {\n return {\n output: JSON.stringify(\n { path: result.targetPath, created: true },\n null,\n 2,\n ),\n exitCode: 0,\n };\n }\n return {\n error: result.errorMessage ?? 'init failed',\n exitCode: 1,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { MigrateResult } from '../../worker-client/typings/migrate-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runDbMigrate`.\n *\n * Intentionally narrower than `MigrateClient` from\n * `run-migrate.function.ts` \u2014 this variant skips the version\n * check and unconditionally runs migrations. Callers that need\n * version-aware migration should use `runMigrate` instead.\n */\nexport interface DbMigrateClient {\n /**\n * Runs all pending database migrations.\n *\n * @param targetPath - absolute path to the `.kbdb` database root\n */\n migrateDatabase(targetPath: string): Promise<MigrateResult>;\n}\n\n/**\n * Runs database migrations unconditionally via `client.migrateDatabase`.\n *\n * Resolves the target path from `options.dbPath` when provided,\n * falling back to `process.cwd()`. Does not perform a version\n * compatibility check before migrating \u2014 use `runMigrate` for\n * version-aware migration flows.\n *\n * @param client - database migration client to delegate to\n * @param options - parsed CLI options supplying the optional\n * `dbPath`\n * @returns the migration report returned by the daemon\n */\nexport async function runDbMigrate(\n client: DbMigrateClient,\n options: CliOptions,\n): Promise<MigrateResult> {\n log('running db-migrate', LogLevel.DEBUG);\n const dbPath = options.dbPath ?? process.cwd();\n return client.migrateDatabase(dbPath);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { SkillArgument } from '../typings/skill-types.interface.ts';\n\n/**\n * Extracts `{{argName}}` placeholder names from a skill body string\n * and returns them as `SkillArgument` objects marked as required.\n *\n * Each placeholder is included only once regardless of how many\n * times it appears, and the returned array preserves the order of\n * first occurrence.\n *\n * @param body - skill body template text to scan for placeholders\n * @returns ordered, deduplicated list of argument definitions\n */\nexport function extractSkillArguments(body: string): SkillArgument[] {\n const seen = new Set<string>();\n const args: SkillArgument[] = [];\n const re = /\\{\\{(\\w+)\\}\\}/g;\n let match: RegExpExecArray | null;\n while ((match = re.exec(body)) !== null) {\n const name = match[1];\n if (!seen.has(name)) {\n seen.add(name);\n args.push({ name, required: true });\n }\n }\n return args;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { SkillDefinition } from '../typings/skill-types.interface.ts';\n\n/**\n * Serializes a `SkillDefinition` to a JSON string suitable for\n * storage as a knowledge-base section's `content` field.\n *\n * @param skill - skill definition to serialize\n * @returns JSON string representation of the skill\n */\nexport function serializeSkillContent(skill: SkillDefinition): string {\n return JSON.stringify(skill);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { AddSectionResult } from '../../worker-client/typings/add-section-result.model.ts';\nimport { extractSkillArguments } from '../../mcp/functions/extract-skill-arguments.function.ts';\nimport { serializeSkillContent } from '../../mcp/functions/serialize-skill-content.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runSkillLearn`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface SkillLearnClient {\n /**\n * Stores a skill section in the knowledge base.\n *\n * @param params - section type, serialized JSON content,\n * and optional title and description\n * @returns result containing the assigned kbid\n */\n addSection(params: {\n readonly sectionType: string;\n readonly content: string;\n readonly title?: string;\n readonly description?: string;\n }): Promise<AddSectionResult>;\n}\n\n/**\n * Creates or updates a skill definition in the knowledge base.\n *\n * Validates that `--name` and `--body` are provided, extracts\n * `{{argName}}` placeholders from the body, serializes the skill\n * to JSON, and stores it as a `'skill'` section.\n *\n * @param client - client used to store the skill section\n * @param options - parsed CLI options with `name` and `body` fields\n * @returns a `CommandResult` with the stored section info or an error\n */\nexport async function runSkillLearn(\n client: SkillLearnClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running skill-learn', LogLevel.DEBUG);\n const name = options.name;\n if (!name) {\n return { error: '--name is required', exitCode: 1 };\n }\n const body = options.body;\n if (!body) {\n return { error: '--body is required', exitCode: 1 };\n }\n const args = extractSkillArguments(body);\n const skill = {\n name,\n description: options.description,\n arguments: args.length > 0 ? args : undefined,\n body,\n };\n const json = serializeSkillContent(skill);\n const result = await client.addSection({\n sectionType: 'skill',\n content: json,\n title: name,\n description: options.description,\n });\n return {\n output: JSON.stringify(\n {\n kbid: result.items[0],\n name,\n arguments: args.length > 0 ? args : [],\n },\n null,\n 2,\n ),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * A single row returned by `listByType` for the skill client.\n */\ninterface SkillRecord {\n /** Knowledge-base identifier for the skill section. */\n kbid: string;\n /** Skill name stored as the section title. */\n title: string | null;\n /** Optional skill description stored on the section. */\n description: string | null;\n /** Serialized `SkillDefinition` JSON stored as section content. */\n content: string;\n}\n\n/**\n * Minimal client interface required by `runSkillList`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface SkillListClient {\n /**\n * Retrieves all sections stored with the given type name.\n *\n * @param sectionType - the type name to filter by\n * @returns matching section rows\n */\n listByType(sectionType: string): Promise<SkillRecord[]>;\n}\n\n/**\n * Lists all skill definitions stored in the knowledge base.\n *\n * Calls `client.listByType('skill')` and maps each record to a\n * summary that includes the argument count parsed from the JSON\n * content. Parse errors default the argument count to `0`.\n *\n * @param client - client used to list skill sections\n * @param _options - parsed CLI options (unused; reserved for future flags)\n * @returns a `CommandResult` containing a JSON array of skill summaries\n */\nexport async function runSkillList(\n client: SkillListClient,\n _options: CliOptions,\n): Promise<CommandResult> {\n log('running skill-list', LogLevel.DEBUG);\n const records = await client.listByType('skill');\n const items = records.map((r) => {\n let argumentCount = 0;\n try {\n const parsed = JSON.parse(r.content) as Record<\n string,\n unknown\n >;\n if (Array.isArray(parsed['arguments'])) {\n argumentCount = parsed['arguments'].length;\n }\n } catch {\n // ignore parse errors\n }\n return {\n kbid: r.kbid,\n name: r.title,\n description: r.description,\n argumentCount,\n };\n });\n return {\n output: JSON.stringify(items, null, 2),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport type {\n SkillArgument,\n SkillDefinition,\n} from '../typings/skill-types.interface.ts';\n\n/**\n * Parses a JSON string into a `SkillDefinition`.\n *\n * Validates that the required `name` and `body` fields are present\n * and are non-empty strings, then returns the full definition\n * including optional `description` and `arguments`.\n *\n * @param json - JSON string representing a serialized skill\n * @returns the parsed skill definition\n * @throws {SyntaxError} when `json` is not valid JSON\n * @throws {Error} when `name` is missing or empty\n * @throws {Error} when `body` is missing or not a string\n */\nexport function parseSkillContent(json: string): SkillDefinition {\n const raw = JSON.parse(json) as Record<string, unknown>;\n if (typeof raw['name'] !== 'string' || !raw['name']) {\n log('skill name is required', LogLevel.ERROR);\n throw new Error('skill name is required');\n }\n if (typeof raw['body'] !== 'string') {\n log('skill body is required', LogLevel.ERROR);\n throw new Error('skill body is required');\n }\n return {\n name: raw['name'],\n description:\n typeof raw['description'] === 'string'\n ? raw['description']\n : undefined,\n arguments: Array.isArray(raw['arguments'])\n ? (raw['arguments'] as SkillArgument[])\n : undefined,\n body: raw['body'],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { parseSkillContent } from '../../mcp/functions/parse-skill-content.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runSkillGet`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface SkillGetClient {\n /**\n * Retrieves one or more sections by their knowledge-base IDs.\n *\n * @param kbids - list of knowledge-base identifiers to fetch\n * @returns matching section rows\n */\n readSections(\n kbids: string[],\n ): Promise<{ kbid: string; content: string }[]>;\n\n /**\n * Retrieves all sections stored with the given type name.\n *\n * @param sectionType - the type name to filter by\n * @returns matching section rows\n */\n listByType(\n sectionType: string,\n ): Promise<\n { kbid: string; title: string | null; content: string }[]\n >;\n}\n\n/**\n * Retrieves a skill definition by name or kbid.\n *\n * Accepts the identifier as the first positional argument or as\n * `options.name`. When the identifier looks like a hex hash\n * (16 or more hex characters) it is tried as a kbid first; if\n * no section is found it falls back to a name lookup. When the\n * identifier is not hex-like it goes directly to name lookup.\n * For name lookups the most recently stored match (last in the\n * array) is returned.\n *\n * @param client - client used to look up the skill section\n * @param options - parsed CLI options; first positional arg or `name`\n * is used as the identifier\n * @returns a `CommandResult` containing the serialized\n * `SkillDefinition` JSON or an error message\n */\nexport async function runSkillGet(\n client: SkillGetClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running skill-get', LogLevel.DEBUG);\n const identifier = options.args[0] ?? options.name;\n if (!identifier) {\n return {\n error: 'skill name or kbid required',\n exitCode: 1,\n };\n }\n let content: string | undefined;\n let kbid: string | undefined;\n // Try as kbid first when it looks like a base32 hash.\n if (/^[a-z2-7]{26}$/.test(identifier)) {\n const sections = await client.readSections([identifier]);\n if (sections.length > 0) {\n content = sections[0]?.content;\n kbid = identifier;\n }\n }\n // If not found by kbid, try by name.\n if (content === undefined) {\n const records = await client.listByType('skill');\n const match = records.filter((r) => r.title === identifier).pop();\n if (match) {\n content = match.content;\n kbid = match.kbid;\n }\n }\n if (content === undefined || kbid === undefined) {\n return {\n error: `skill not found: ${identifier}`,\n exitCode: 1,\n };\n }\n const skill = parseSkillContent(content);\n return {\n output: JSON.stringify({ kbid, ...skill }, null, 2),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runSkillDelete`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface SkillDeleteClient {\n /**\n * Removes a section from the knowledge base.\n *\n * @param kbid - knowledge-base identifier of the section to remove\n * @returns result indicating whether the section was found and removed\n */\n removeSection(kbid: string): Promise<{ removed: boolean }>;\n}\n\n/**\n * Deletes a skill section from the knowledge base by its kbid.\n *\n * The kbid must be supplied as the first positional argument. Returns\n * an error result if it is missing.\n *\n * @param client - client used to remove the skill section\n * @param options - parsed CLI options; `args[0]` is the kbid\n * @returns a `CommandResult` with the kbid and removal status\n */\nexport async function runSkillDelete(\n client: SkillDeleteClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running skill-delete', LogLevel.DEBUG);\n const kbid = options.args[0];\n if (!kbid) {\n return { error: 'kbid is required', exitCode: 1 };\n }\n const result = await client.removeSection(kbid);\n return {\n output: JSON.stringify(\n { removed: result.removed ? [kbid] : [] },\n null,\n 2,\n ),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { AddSectionResult } from '../../worker-client/typings/add-section-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runAgentCreate`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface AgentCreateClient {\n /**\n * Ingests a content section into the knowledge base.\n *\n * @param params - section type label, raw content, and optional\n * metadata\n * @returns result object containing the assigned knowledge-base\n * identifier\n */\n addSection(params: {\n readonly sectionType: string;\n readonly content: string;\n readonly title?: string;\n readonly description?: string;\n }): Promise<AddSectionResult>;\n\n /**\n * Groups a set of sections under a named document.\n *\n * @param title - human-readable document title\n * @param kbids - identifiers of the sections to group\n * @param docType - application-level document type tag; omit or\n * pass an empty string for untagged documents\n * @returns the assigned document identifier\n */\n groupSections(\n title: string,\n kbids: string[],\n docType?: string,\n ): Promise<string>;\n\n /**\n * Retrieves one or more sections by their identifiers.\n *\n * @param kbids - list of knowledge-base identifiers to fetch\n * @returns sections found; missing kbids are omitted from the result\n */\n readSections(kbids: string[]): Promise<{ kbid: string }[]>;\n}\n\n/**\n * Creates a new agent in the knowledge base.\n *\n * Validates `--name` and `--persona` options, verifies that all\n * referenced skill kbids exist, stores agent metadata as a JSON\n * section, and groups all sections under a single document.\n *\n * @param client - agent create client to delegate operations to\n * @param options - parsed CLI options providing `name`, `persona`,\n * optional `description`, and optional `skills` kbid list\n * @returns a `CommandResult` with serialised creation info or an\n * error message and a non-zero exit code\n */\nexport async function runAgentCreate(\n client: AgentCreateClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running agent-create', LogLevel.DEBUG);\n const name = options.name;\n if (!name) {\n return { error: '--name is required', exitCode: 1 };\n }\n const persona = options.persona;\n if (!persona) {\n return { error: '--persona is required', exitCode: 1 };\n }\n const skills = options.skills ?? [];\n\n if (skills.length > 0) {\n const sections = await client.readSections(skills);\n const found = new Set(sections.map((s) => s.kbid));\n const missing = skills.filter((k) => !found.has(k));\n if (missing.length > 0) {\n return {\n error: `skill not found: ${missing.join(', ')}`,\n exitCode: 1,\n };\n }\n }\n\n const metadata = JSON.stringify({\n name,\n description: options.description ?? '',\n persona,\n });\n\n const metaResult = await client.addSection({\n sectionType: 'text',\n content: metadata,\n title: name,\n description: options.description,\n });\n\n const allKbids = [metaResult.items[0], ...skills];\n const docid = await client.groupSections(name, allKbids, 'agent');\n\n return {\n output: JSON.stringify(\n { docid, name, skillCount: skills.length },\n null,\n 2,\n ),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** A document summary as returned by `listDocumentsByType`. */\ninterface DocumentSummary {\n /** Unique document identifier. */\n readonly docid: string;\n /** Human-readable document title used as the agent name. */\n readonly title: string;\n /** Ordered list of section references for this document. */\n readonly sections: readonly { kbid: string; position: number }[];\n}\n\n/**\n * Minimal client interface required by `runAgentList`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface AgentListClient {\n /**\n * Retrieves all documents whose type name matches the given string.\n *\n * @param docType - the application-level document type to filter by\n * @returns all document summaries with a matching type name\n */\n listDocumentsByType(docType: string): Promise<DocumentSummary[]>;\n}\n\n/**\n * Lists all agents stored in the knowledge base.\n *\n * Retrieves all documents with `doc_type: 'agent'` and returns a\n * summary list. The `skillCount` for each agent is\n * `Math.max(0, sections.length - 1)` because the first section\n * always holds the agent's metadata JSON rather than a skill\n * reference.\n *\n * @param client - agent list client to delegate retrieval to\n * @param _options - parsed CLI options (unused; reserved for future\n * filtering flags)\n * @returns a `CommandResult` with serialised agent summary list\n */\nexport async function runAgentList(\n client: AgentListClient,\n _options: CliOptions,\n): Promise<CommandResult> {\n log('running agent-list', LogLevel.DEBUG);\n const docs = await client.listDocumentsByType('agent');\n const items = docs.map((d) => ({\n docid: d.docid,\n name: d.title,\n skillCount: Math.max(0, d.sections.length - 1),\n }));\n return {\n output: JSON.stringify(items, null, 2),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** A document section reference as returned by `retrieveDocument`. */\ninterface DocumentSection {\n /** Knowledge-base identifier of the section. */\n readonly kbid: string;\n /** Zero-based position of the section within the document. */\n readonly position: number;\n}\n\n/** A document record as returned by `retrieveDocument`. */\ninterface AgentDocument {\n /** Unique document identifier. */\n readonly docid: string;\n /** Human-readable document title used as agent name fallback. */\n readonly title: string;\n /** Ordered list of section references. */\n readonly sections: DocumentSection[];\n}\n\n/** A section record as returned by `readSections`. */\ninterface SectionRecord {\n /** Knowledge-base identifier of the section. */\n readonly kbid: string;\n /** Raw text content stored in the section. */\n readonly content: string;\n}\n\n/**\n * Minimal client interface required by `runAgentGet`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface AgentGetClient {\n /**\n * Retrieves a full document record including its ordered sections.\n *\n * @param docid - identifier of the document to retrieve\n * @returns the document record\n */\n retrieveDocument(docid: string): Promise<unknown>;\n\n /**\n * Retrieves one or more sections by their identifiers.\n *\n * @param kbids - list of knowledge-base identifiers to fetch\n * @returns sections found; missing kbids are omitted from the result\n */\n readSections(kbids: string[]): Promise<SectionRecord[]>;\n}\n\n/**\n * Reads agent metadata from the first section's JSON content.\n * Falls back to `fallbackName` when the section is absent or the\n * content cannot be parsed.\n */\nasync function readAgentMeta(\n client: AgentGetClient,\n metaKbid: string,\n fallbackName: string,\n): Promise<{ name: string; description: string; persona: string }> {\n const sections = await client.readSections([metaKbid]);\n const first = sections.at(0);\n if (!first) {\n return { name: fallbackName, description: '', persona: '' };\n }\n try {\n const meta = JSON.parse(first.content) as Record<string, unknown>;\n return {\n name:\n typeof meta['name'] === 'string'\n ? meta['name']\n : fallbackName,\n description:\n typeof meta['description'] === 'string'\n ? meta['description']\n : '',\n persona:\n typeof meta['persona'] === 'string' ? meta['persona'] : '',\n };\n } catch {\n return { name: fallbackName, description: '', persona: '' };\n }\n}\n\n/**\n * Resolves skill names by reading each skill section's JSON content.\n * Returns `null` for any reference whose section no longer exists\n * (dangling reference).\n */\nasync function resolveSkills(\n client: AgentGetClient,\n skillRefs: DocumentSection[],\n): Promise<{ kbid: string; name: string | null; position: number }[]> {\n if (skillRefs.length === 0) {\n return [];\n }\n const kbids = skillRefs.map((r) => r.kbid);\n const sections = await client.readSections(kbids);\n const sectionMap = new Map(sections.map((s) => [s.kbid, s]));\n return skillRefs.map((ref) => {\n const sec = sectionMap.get(ref.kbid);\n if (!sec) {\n return { kbid: ref.kbid, name: null, position: ref.position };\n }\n try {\n const parsed = JSON.parse(sec.content) as Record<\n string,\n unknown\n >;\n const skillName =\n typeof parsed['name'] === 'string' ? parsed['name'] : null;\n return {\n kbid: ref.kbid,\n name: skillName,\n position: ref.position,\n };\n } catch {\n return { kbid: ref.kbid, name: null, position: ref.position };\n }\n });\n}\n\n/**\n * Retrieves a full agent definition from the knowledge base.\n *\n * Reads the agent document identified by `options.args[0]`, extracts\n * metadata (name, description, persona) from the first section, and\n * resolves skill names from the remaining sections. Dangling skill\n * references appear with `name: null`.\n *\n * @param client - agent get client to delegate retrieval to\n * @param options - parsed CLI options; `args[0]` must be the docid\n * @returns a `CommandResult` with serialised agent definition or an\n * error message and a non-zero exit code\n */\nexport async function runAgentGet(\n client: AgentGetClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running agent-get', LogLevel.DEBUG);\n const docid = options.args[0];\n if (!docid) {\n return { error: 'docid is required', exitCode: 1 };\n }\n\n const doc = (await client.retrieveDocument(docid)) as AgentDocument;\n const metaKbid = doc.sections[0]?.kbid;\n const skillRefs = doc.sections.slice(1);\n\n const { name, description, persona } = metaKbid\n ? await readAgentMeta(client, metaKbid, doc.title)\n : { name: doc.title, description: '', persona: '' };\n\n const skills = await resolveSkills(client, skillRefs);\n\n return {\n output: JSON.stringify(\n { docid, name, description, persona, skills },\n null,\n 2,\n ),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runAgentDelete`.\n *\n * Decouples the CLI function from the concrete `WorkerClient`\n * implementation, making it straightforward to test with mocks.\n */\nexport interface AgentDeleteClient {\n /**\n * Removes the document grouping for the given document.\n *\n * The sections themselves are not deleted; only the grouping\n * record is removed.\n *\n * @param docid - identifier of the document grouping to remove\n */\n removeGrouping(docid: string): Promise<void>;\n}\n\n/**\n * Deletes an agent from the knowledge base.\n *\n * Removes the document grouping identified by `options.args[0]`.\n * Skill sections referenced by the agent are not deleted; only\n * the grouping record is removed.\n *\n * @param client - agent delete client to delegate removal to\n * @param options - parsed CLI options; `args[0]` must be the docid\n * @returns a `CommandResult` confirming removal or an error message\n * with a non-zero exit code\n */\nexport async function runAgentDelete(\n client: AgentDeleteClient,\n options: CliOptions,\n): Promise<CommandResult> {\n log('running agent-delete', LogLevel.DEBUG);\n const docid = options.args[0];\n if (!docid) {\n return { error: 'docid is required', exitCode: 1 };\n }\n await client.removeGrouping(docid);\n return {\n output: JSON.stringify({ removed: [docid] }, null, 2),\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\nimport type { SearchClient } from './run-search.function.ts';\nimport { runSearch } from './run-search.function.ts';\n\n/**\n * Runs a search scoped to skill sections.\n *\n * Executes a regular search, then filters results to\n * only include items whose type is `'skill'`.\n *\n * @param client - search client to delegate to\n * @param options - parsed CLI options\n */\nexport async function runSkillSearch(\n client: SearchClient,\n options: CliOptions,\n): Promise<PagedSearchDisplay> {\n const paged = await runSearch(client, options);\n const filtered = paged.items.filter((item) => item.type === 'skill');\n return {\n ...paged,\n items: filtered,\n total: filtered.length,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\nimport type { SearchClient } from './run-search.function.ts';\nimport { runSearch } from './run-search.function.ts';\n\n/**\n * Runs a search scoped to agent documents.\n *\n * Executes a regular search, then filters results to\n * only include items whose type is `'agent'`.\n *\n * @param client - search client to delegate to\n * @param options - parsed CLI options\n */\nexport async function runAgentSearch(\n client: SearchClient,\n options: CliOptions,\n): Promise<PagedSearchDisplay> {\n const paged = await runSearch(client, options);\n const filtered = paged.items.filter((item) => item.type === 'agent');\n return {\n ...paged,\n items: filtered,\n total: filtered.length,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { resolve } from 'node:path';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { ImportResult } from '../../worker-client/typings/import-result.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Minimal client interface required by `runImport`.\n */\nexport interface ImportClient {\n /**\n * Imports an exported database from the given directory.\n *\n * @param params - source path and dry-run flag\n * @returns import report with counts and timing\n */\n import(params: {\n from: string;\n dryRun: boolean;\n }): Promise<ImportResult>;\n}\n\n/**\n * Imports an exported knowledge-base from the path specified by\n * `--from`, delegating to the worker client.\n *\n * The path is resolved against the current working directory so\n * that the daemon -- which may run with a different working\n * directory -- always receives an absolute path.\n *\n * @param client - import client to delegate to\n * @param options - parsed CLI options with `from` path\n * @returns the import result with section/document counts\n * @throws when `--from` is not provided\n */\nexport async function runImport(\n client: ImportClient,\n options: CliOptions,\n): Promise<ImportResult> {\n const from = options.from;\n if (!from) {\n const msg = 'import requires --from <path>';\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n return client.import({\n from: resolve(process.cwd(), from),\n dryRun: options.dryRun === true,\n });\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { PagedSearchDisplay } from '../typings/search-display.model.ts';\nimport type { ContentClient } from './run-content.function.ts';\n\n/**\n * Hydrates each result's `preview` field with the actual section\n * content fetched from the client.\n *\n * Failures for individual results are caught and suppressed so that\n * one unavailable section does not prevent other previews from\n * being returned.\n *\n * @param client - content client used to fetch section text\n * @param paged - mutable search display records to hydrate\n */\nexport async function hydrateSearchPreviews(\n client: ContentClient,\n paged: PagedSearchDisplay,\n): Promise<void> {\n await Promise.all(\n paged.items.map(async (result) => {\n try {\n const contentResult = await client.content([result.kbid]);\n result.preview = contentResult.data;\n } catch {\n // Leave preview as empty string on failure.\n }\n }),\n );\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { DispatchClient } from '../typings/dispatch-client.type.ts';\nimport type { LearnIO } from './run-learn.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { runSearch } from './run-search.function.ts';\nimport { runLearn } from './run-learn.function.ts';\nimport { runUnlearn } from './run-unlearn.function.ts';\nimport { runContent } from './run-content.function.ts';\nimport { runCheck } from './run-check.function.ts';\nimport { runGc } from './run-gc.function.ts';\nimport { runRebuild } from './run-rebuild.function.ts';\nimport { runStatus } from './run-status.function.ts';\nimport { runDbInit } from './run-db-init.function.ts';\nimport { runInit } from './run-init.function.ts';\nimport { runDbMigrate } from './run-db-migrate.function.ts';\nimport { runSkillLearn } from './run-skill-learn.function.ts';\nimport { runSkillList } from './run-skill-list.function.ts';\nimport { runSkillGet } from './run-skill-get.function.ts';\nimport { runSkillDelete } from './run-skill-delete.function.ts';\nimport { runAgentCreate } from './run-agent-create.function.ts';\nimport { runAgentList } from './run-agent-list.function.ts';\nimport { runAgentGet } from './run-agent-get.function.ts';\nimport { runAgentDelete } from './run-agent-delete.function.ts';\nimport { runSkillSearch } from './run-skill-search.function.ts';\nimport { runAgentSearch } from './run-agent-search.function.ts';\nimport { runRecall } from './run-recall.function.ts';\nimport { runExport } from './run-export.function.ts';\nimport { runImport } from './run-import.function.ts';\nimport { formatOutput } from './format-output.function.ts';\nimport { formatCommandOutput } from './format-command-output.function.ts';\nimport { errorToMessage } from './error-to-message.function.ts';\nimport { hydrateSearchPreviews } from './hydrate-search-previews.function.ts';\n\nexport type { DispatchClient } from '../typings/dispatch-client.type.ts';\n\n/**\n * Routes a parsed CLI command to the appropriate handler and\n * returns a `CommandResult` without touching process globals.\n *\n * @param client - worker client covering all data commands\n * @param options - parsed CLI options with command and args\n * @param io - optional injectable I/O for learn stdin\n */\nexport async function dispatchCommand(\n client: DispatchClient,\n options: CliOptions,\n io?: LearnIO,\n): Promise<CommandResult> {\n log('dispatching command: ' + options.command, LogLevel.DEBUG);\n switch (options.command) {\n case 'learn':\n return handleLearn(client, options, io);\n case 'unlearn':\n return handleUnlearn(client, options);\n case 'search':\n return handleSearch(client, options);\n case 'recall':\n return handleRecall(client, options);\n case 'content':\n return handleContent(client, options);\n case 'check':\n return handleCheck(client, options);\n case 'gc':\n return handleGc(client, options);\n case 'rebuild':\n return handleRebuild(client, options);\n case 'status':\n return handleStatus(client, options);\n case 'export':\n return handleExport(client, options);\n case 'import':\n return handleImport(client, options);\n case 'db-init':\n return handleDbInit(options);\n case 'db-migrate':\n return handleDbMigrate(client, options);\n case 'skill-learn': {\n const result = await runSkillLearn(client, options);\n return result;\n }\n case 'skill-list': {\n const result = await runSkillList(client, options);\n return result;\n }\n case 'skill-get': {\n const result = await runSkillGet(client, options);\n return result;\n }\n case 'skill-delete': {\n const result = await runSkillDelete(client, options);\n return result;\n }\n case 'agent-create': {\n const result = await runAgentCreate(client, options);\n return result;\n }\n case 'agent-list': {\n const result = await runAgentList(client, options);\n return result;\n }\n case 'agent-get': {\n const result = await runAgentGet(client, options);\n return result;\n }\n case 'agent-delete': {\n const result = await runAgentDelete(client, options);\n return result;\n }\n case 'skill-search':\n return handleTypedSearch(client, options, 'skill');\n case 'agent-search':\n return handleTypedSearch(client, options, 'agent');\n default:\n log('unknown command: ' + options.command, LogLevel.WARNING);\n return {\n error: `unknown command: ${options.command}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleLearn(\n client: DispatchClient,\n options: CliOptions,\n io?: LearnIO,\n): Promise<CommandResult> {\n try {\n const results = await runLearn(client, options, io);\n const items = results.map((r) => r.kbid);\n const base = {\n items,\n total: results.length,\n offset: 0,\n };\n if (results.length === 0) {\n const empty = {\n ...base,\n superseded: null,\n warnings: [],\n near_duplicates: [],\n };\n return {\n output: formatCommandOutput(empty, options.format, 'learn'),\n exitCode: 0,\n };\n }\n const last = results[results.length - 1];\n const data = {\n ...base,\n superseded: last.superseded,\n warnings: last.warnings,\n near_duplicates: last.near_duplicates,\n };\n return {\n output: formatCommandOutput(data, options.format, 'learn'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `learn failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleUnlearn(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const results = await runUnlearn(client, options);\n const removed = results\n .filter((r) => r.removed)\n .map((r) => r.kbid);\n return {\n output: formatCommandOutput(\n { removed },\n options.format,\n 'unlearn',\n ),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `unlearn failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleSearch(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const results = await runSearch(client, options);\n if (options.content) {\n await hydrateSearchPreviews(client, results);\n }\n return {\n output: formatOutput(results, options.format, options.content),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `search failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleRecall(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runRecall(client, options);\n if ('error' in result) {\n return {\n error: `error: ${result.error}`,\n exitCode: 1,\n };\n }\n return {\n output: formatCommandOutput(result, options.format, 'recall'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `recall failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleExport(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runExport(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'export'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `export failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleImport(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runImport(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'import'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `import failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleContent(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runContent(client, options);\n if (options.format === 'text') {\n return { output: result.data, exitCode: 0 };\n }\n if (options.format === 'rec') {\n const header =\n `type: ${result.type}\\n` +\n `total: ${String(result.total)}\\n\\n`;\n return {\n output: header + result.data,\n exitCode: 0,\n };\n }\n if (options.format === 'mcp') {\n const text = result.data || '(empty)';\n return {\n output: JSON.stringify(\n {\n jsonrpc: '2.0',\n result: {\n content: [{ type: 'text', text }],\n },\n },\n null,\n 2,\n ),\n exitCode: 0,\n };\n }\n const envelope =\n !options.search && options.args.length === 1\n ? { kbid: options.args[0], ...result }\n : result;\n return {\n output: JSON.stringify(envelope, null, 2),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `content failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleCheck(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runCheck(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'check'),\n exitCode: result.ok ? 0 : 1,\n };\n } catch (err) {\n return {\n error: `check failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleGc(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runGc(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'gc'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `gc failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleRebuild(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runRebuild(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'rebuild'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `rebuild failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleStatus(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runStatus(client, options);\n return {\n output: formatCommandOutput(result, options.format, 'status'),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `status failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nfunction handleDbInit(options: CliOptions): CommandResult {\n return runDbInit(options, runInit);\n}\n\nasync function handleDbMigrate(\n client: DispatchClient,\n options: CliOptions,\n): Promise<CommandResult> {\n try {\n const result = await runDbMigrate(client, options);\n return {\n output: formatCommandOutput(\n result,\n options.format,\n 'db-migrate',\n ),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `db-migrate failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleTypedSearch(\n client: DispatchClient,\n options: CliOptions,\n type: 'skill' | 'agent',\n): Promise<CommandResult> {\n try {\n const runner = type === 'skill' ? runSkillSearch : runAgentSearch;\n const results = await runner(client, options);\n return {\n output: formatOutput(results, options.format),\n exitCode: 0,\n };\n } catch (err) {\n return {\n error: `${type} search failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Current package version, kept in sync with package.json. */\nexport const VERSION = '0.6.1';\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { VERSION } from '../../version/index.ts';\n\n/**\n * The set of all recognised top-level command names,\n * including group commands (`db`, `skill`, `agent`, `worker`).\n */\nconst KNOWN_COMMANDS = new Set([\n 'learn',\n 'unlearn',\n 'search',\n 'recall',\n 'content',\n 'check',\n 'gc',\n 'rebuild',\n 'status',\n 'export',\n 'mcp',\n 'db',\n 'skill',\n 'agent',\n 'worker',\n]);\n\n/** Subcommands available under each group command. */\nconst GROUP_SUBCOMMANDS: Readonly<\n Record<string, readonly (readonly [string, string])[]>\n> = {\n db: [\n ['init', 'Initialise a new .kbdb directory'],\n ['migrate', 'Migrate database to current format'],\n ['path', 'Show resolved database path'],\n ],\n skill: [\n ['learn', 'Create a new skill definition'],\n ['list', 'List all skills'],\n ['get', 'Retrieve a skill by name or kbid'],\n ['delete', 'Remove a skill'],\n ],\n agent: [\n ['create', 'Create an agent with skill refs'],\n ['list', 'List all agents'],\n ['get', 'Retrieve an agent by docid'],\n ['delete', 'Remove an agent'],\n ],\n worker: [\n ['stop', 'Stop the worker daemon'],\n ['restart', 'Restart the worker daemon'],\n ],\n};\n\n/**\n * Returns `true` when `cmd` is a recognised command name.\n *\n * Accepts both simple top-level names (`'learn'`, `'db'`)\n * and the hyphenated compound form produced by `parseArgs`\n * when a group + subcommand precedes `--help`\n * (e.g. `'db-init'`, `'skill-learn'`).\n */\nexport function isKnownCommand(cmd: string): boolean {\n if (KNOWN_COMMANDS.has(cmd)) {\n return true;\n }\n // Check hyphenated compound form: 'db-init', 'skill-learn'\n const dashIdx = cmd.indexOf('-');\n if (dashIdx < 0) {\n return false;\n }\n const group = cmd.slice(0, dashIdx);\n return group in GROUP_SUBCOMMANDS;\n}\n\n/**\n * Generates contextual help text for the `kbdb` CLI.\n *\n * Three levels of detail are produced depending on\n * how many command tokens are supplied:\n *\n * - No arguments: global help listing all commands.\n * - `command` only: command-level help. When `command`\n * is a hyphenated compound (`'db-init'`), it is split\n * into group + subcommand automatically. Group\n * commands show a subcommand listing; leaf commands\n * show detailed help; unknown commands show an error\n * prefix followed by global help.\n * - `command` + `subcommand`: detailed help for that\n * specific subcommand (falls back to group help when\n * the subcommand is not recognised).\n *\n * @param command - optional top-level command token,\n * or a hyphenated compound such as `'db-init'`\n * @param subcommand - optional subcommand token\n */\nexport function generateHelp(\n command?: string,\n subcommand?: string,\n): string {\n if (!command) {\n return generateGlobalHelp();\n }\n // Handle compound form produced by parseArgs:\n // 'db-init' -> group='db', sub='init'\n if (!subcommand && command.includes('-')) {\n const dashIdx = command.indexOf('-');\n const group = command.slice(0, dashIdx);\n const sub = command.slice(dashIdx + 1);\n if (group in GROUP_SUBCOMMANDS) {\n return generateSubcommandHelp(group, sub);\n }\n }\n if (subcommand) {\n return generateSubcommandHelp(command, subcommand);\n }\n return generateCommandHelp(command);\n}\n\n// ---------------------------------------------------------------------------\n// Level 1: Global help\n// ---------------------------------------------------------------------------\n\nfunction generateGlobalHelp(): string {\n return (\n `kbdb v${VERSION} - File-based knowledge base` +\n ` database for AI agents\\n` +\n `\\n` +\n `Usage: kbdb [options]\\n` +\n ` kbdb <command> [options] ...[parameters]\\n` +\n ` kbdb <command> <subcommand> [options]` +\n ` ...[params]\\n` +\n `\\n` +\n `Knowledge Base:\\n` +\n ` learn Import content from` +\n ` files/stdin\\n` +\n ` unlearn Remove sections by kbid\\n` +\n ` search Query the knowledge base\\n` +\n ` recall Retrieve section context` +\n ` by kbid\\n` +\n ` content Compose rendered content` +\n ` from ids\\n` +\n `\\n` +\n `Database:\\n` +\n ` db init Initialise a new .kbdb` +\n ` directory\\n` +\n ` db migrate Migrate database to current` +\n ` format\\n` +\n ` db path Show resolved database` +\n ` path\\n` +\n `\\n` +\n `Maintenance:\\n` +\n ` check Verify knowledge base` +\n ` integrity\\n` +\n ` gc Garbage collect unreferenced\\n` +\n ` sections\\n` +\n ` rebuild Reconstruct all index` +\n ` files\\n` +\n ` status Show database status\\n` +\n ` export Snapshot database for` +\n ` backup\\n` +\n `\\n` +\n `Skills:\\n` +\n ` skill learn Create a new skill` +\n ` definition\\n` +\n ` skill list List all skills\\n` +\n ` skill get Retrieve a skill by name` +\n ` or kbid\\n` +\n ` skill delete Remove a skill\\n` +\n `\\n` +\n `Agents:\\n` +\n ` agent create Create an agent with skill` +\n ` refs\\n` +\n ` agent list List all agents\\n` +\n ` agent get Retrieve an agent by docid\\n` +\n ` agent delete Remove an agent\\n` +\n `\\n` +\n `Worker:\\n` +\n ` worker stop Stop the worker daemon\\n` +\n ` worker restart Restart the worker daemon\\n` +\n `\\n` +\n `Server:\\n` +\n ` mcp Start MCP server mode` +\n ` (stdio)\\n` +\n `\\n` +\n `Global Options:\\n` +\n ` -h, --help Show this help message\\n` +\n ` -v, --version Show version information\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n ` --format <fmt> Output format` +\n ` (json|text|mcp)\\n` +\n `\\n` +\n `Run \"kbdb <command> --help\" for detailed` +\n ` information.\\n`\n );\n}\n\n// ---------------------------------------------------------------------------\n// Level 2: Command help\n// ---------------------------------------------------------------------------\n\nfunction generateCommandHelp(command: string): string {\n if (command in GROUP_SUBCOMMANDS) {\n return generateGroupHelp(command);\n }\n const leaf = LEAF_HELP[command];\n if (leaf) {\n return leaf;\n }\n return `Unknown command: ${command}\\n\\n` + generateGlobalHelp();\n}\n\nfunction generateGroupHelp(group: string): string {\n const subs = GROUP_SUBCOMMANDS[group] ?? [];\n const subLines = subs\n .map(([name, desc]) => ` ${name.padEnd(20)}${desc}`)\n .join('\\n');\n const desc = GROUP_DESCRIPTIONS[group] ?? group;\n return (\n `kbdb ${group} - ${desc}\\n` +\n `\\n` +\n `Usage: kbdb ${group} <subcommand> [options]\\n` +\n `\\n` +\n `Subcommands:\\n` +\n `${subLines}\\n` +\n `\\n` +\n `Global Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n ` -h, --help Show this help message\\n` +\n `\\n` +\n `Run \"kbdb ${group} <subcommand> --help\"` +\n ` for details.\\n`\n );\n}\n\n/** One-line description for each group command. */\nconst GROUP_DESCRIPTIONS: Readonly<Record<string, string>> = {\n db: 'Database management',\n skill: 'Skill management',\n agent: 'Agent management',\n worker: 'Worker daemon management',\n};\n\n// ---------------------------------------------------------------------------\n// Leaf command help texts\n// ---------------------------------------------------------------------------\n\nconst LEAF_HELP: Readonly<Record<string, string>> = {\n learn:\n `kbdb learn - Import content from files or stdin\\n` +\n `\\n` +\n `Usage: kbdb learn [options] <path | ->...\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <path | -> File path, directory,` +\n ` or - for stdin\\n` +\n `\\n` +\n `Options:\\n` +\n ` --title <title> Section title\\n` +\n ` --description <d> Section description\\n` +\n ` --docid <docid> Document ID to group` +\n ` under\\n` +\n ` --tags <t,...> Comma-separated tags\\n` +\n ` --replace Supersede existing section` +\n ` by source key\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON array of { kbid, path, size, skipped,\\n` +\n ` superseded, warnings,` +\n ` near_duplicates }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb learn README.md\\n` +\n ` kbdb learn ./docs/\\n` +\n ` kbdb learn --tags auth,api --replace doc.md\\n` +\n ` cat notes.txt | kbdb learn -\\n`,\n\n unlearn:\n `kbdb unlearn - Remove sections by kbid\\n` +\n `\\n` +\n `Usage: kbdb unlearn [options] <kbid>...\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <kbid> 26-character knowledge` +\n ` base identifier\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON array of { kbid, removed }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb unlearn abcdef1234567890abcdef1234\\n` +\n ` kbdb unlearn id1 id2 id3\\n`,\n\n search:\n `kbdb search - Query the knowledge base\\n` +\n `\\n` +\n `Usage: kbdb search [options] <query>...\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <query> One or more query terms\\n` +\n `\\n` +\n `Options:\\n` +\n ` --mode <mode> Result granularity` +\n ` (sections|documents|stats)\\n` +\n ` --limit <n> Max results (default: 20)\\n` +\n ` --format <fmt> Output format` +\n ` (json|text|mcp)\\n` +\n ` --content, -c Hydrate results with` +\n ` section content\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON array of { kbid, score, preview,` +\n ` matches }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb search \"machine learning\"\\n` +\n ` kbdb search --limit 5 --format text query\\n` +\n ` kbdb search --mode documents --content term\\n`,\n\n recall:\n `kbdb recall - Retrieve section context by kbid\\n` +\n `\\n` +\n `Usage: kbdb recall [options] <kbid>...\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <kbid> 26-character knowledge` +\n ` base identifier\\n` +\n `\\n` +\n `Options:\\n` +\n ` --depth <n>, -d Expansion depth (0-3,` +\n ` default: 0)\\n` +\n ` --tags <t,...> Filter by tags\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON RecallResult or RecallResult[]\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb recall abcdef1234567890abcdef1234\\n` +\n ` kbdb recall kbid1 --depth 2\\n`,\n\n content:\n `kbdb content - Compose rendered content from ids\\n` +\n `\\n` +\n `Usage: kbdb content [options] <id>...\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <id> kbid or docid identifier\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { type, data, total }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb content abcdef1234567890abcdef1234\\n` +\n ` kbdb content id1 id2\\n`,\n\n check:\n `kbdb check - Verify knowledge base integrity\\n` +\n `\\n` +\n `Usage: kbdb check [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { ok, errors }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb check\\n` +\n ` kbdb check --db /path/to/project\\n`,\n\n gc:\n `kbdb gc - Garbage collect unreferenced sections\\n` +\n `\\n` +\n `Usage: kbdb gc [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { removed_sections, removed_bytes }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb gc\\n` +\n ` kbdb gc --db /path/to/project\\n`,\n\n rebuild:\n `kbdb rebuild - Reconstruct all index files\\n` +\n `\\n` +\n `Usage: kbdb rebuild [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { sections_reindexed, terms_indexed }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb rebuild\\n` +\n ` kbdb rebuild --db /path/to/project\\n`,\n\n status:\n `kbdb status - Show database status\\n` +\n `\\n` +\n `Usage: kbdb status [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON database status object\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb status\\n` +\n ` kbdb status --db /path/to/project\\n`,\n\n export:\n `kbdb export - Snapshot database for backup\\n` +\n `\\n` +\n `Usage: kbdb export [options] [<path>]\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <path> Output directory path\\n` +\n ` (default: ./kbdb-export/)\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { path, sections_exported,` +\n ` documents_exported }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb export\\n` +\n ` kbdb export ./my-backup\\n` +\n ` kbdb export --db /path/to/project\\n`,\n\n mcp:\n `kbdb mcp - Start MCP server mode (stdio)\\n` +\n `\\n` +\n `Usage: kbdb mcp [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Environment:\\n` +\n ` KBDB_DB_DIR Fallback database path\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb mcp --db /path/to/project\\n` +\n ` KBDB_DB_DIR=/path/to/project kbdb mcp\\n`,\n};\n\n// ---------------------------------------------------------------------------\n// Level 3: Subcommand help\n// ---------------------------------------------------------------------------\n\n/**\n * Detailed help texts keyed by `\"group-subcommand\"`.\n * Falls back to group help when the key is absent.\n */\nconst SUBCOMMAND_HELP: Readonly<Record<string, string>> = {\n 'db-init':\n `kbdb db init - Initialise a new .kbdb directory\\n` +\n `\\n` +\n `Usage: kbdb db init [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to create .kbdb in\\n` +\n ` (default: current directory)\\n` +\n ` -h, --help Show this help message\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { path, created }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb db init\\n` +\n ` kbdb db init --db /path/to/project\\n`,\n\n 'db-migrate':\n `kbdb db migrate - Migrate database to current` +\n ` format\\n` +\n `\\n` +\n `Usage: kbdb db migrate [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path containing .kbdb\\n` +\n ` (default: current directory)\\n` +\n ` -h, --help Show this help message\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON MigrateResult or \"already up to date\"\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb db migrate\\n` +\n ` kbdb db migrate --db /path/to/project\\n`,\n\n 'db-path':\n `kbdb db path - Show resolved database path\\n` +\n `\\n` +\n `Usage: kbdb db path [options]\\n` +\n `\\n` +\n `Prints the absolute path of the .kbdb database\\n` +\n `that would be used by the current command\\n` +\n `context. Useful for debugging database\\n` +\n `resolution.\\n` +\n `\\n` +\n `Resolution order:\\n` +\n ` 1. --db <path> Explicit flag\\n` +\n ` 2. cwd traversal Walk up from cwd\\n` +\n ` 3. KBDB_DB_DIR Environment variable\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n ` --format json Show full diagnostic\\n` +\n ` -h, --help Show this help message\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb db path\\n` +\n ` kbdb db path --format json\\n` +\n ` kbdb db path --db /path/to/project\\n`,\n\n 'skill-learn':\n `kbdb skill learn - Create a new skill definition\\n` +\n `\\n` +\n `Usage: kbdb skill learn [options]` +\n ` --name <n> --body <file|->\\n` +\n `\\n` +\n `Options:\\n` +\n ` --name <name> Skill name (required)\\n` +\n ` --description <d> Skill description\\n` +\n ` --body <file|-> Template body file or` +\n ` stdin (required)\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { kbid, name, arguments }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb skill learn --name summarize` +\n ` --body prompt.txt\\n` +\n ` cat body.txt | kbdb skill learn` +\n ` --name my-skill --body -\\n`,\n\n 'skill-list':\n `kbdb skill list - List all skills\\n` +\n `\\n` +\n `Usage: kbdb skill list [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON array of { kbid, name, description,` +\n ` argumentCount }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb skill list\\n` +\n ` kbdb skill list --db /path/to/project\\n`,\n\n 'skill-get':\n `kbdb skill get - Retrieve a skill by name` +\n ` or kbid\\n` +\n `\\n` +\n `Usage: kbdb skill get [options] <name-or-kbid>\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <name-or-kbid> Skill name or 26-char` +\n ` kbid\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON SkillDefinition object\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb skill get summarize-document\\n` +\n ` kbdb skill get abcdef1234567890abcdef1234\\n`,\n\n 'skill-delete':\n `kbdb skill delete - Remove a skill\\n` +\n `\\n` +\n `Usage: kbdb skill delete [options] <kbid>\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <kbid> 26-character kbid of the` +\n ` skill to remove\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { kbid, removed }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb skill delete abcdef1234567890abcdef1234\\n`,\n\n 'agent-create':\n `kbdb agent create - Create an agent with skill` +\n ` refs\\n` +\n `\\n` +\n `Usage: kbdb agent create [options] --name <n>` +\n ` --persona <file|-> --skills <kbid,...>\\n` +\n `\\n` +\n `Options:\\n` +\n ` --name <name> Agent name (required)\\n` +\n ` --description <d> Agent description\\n` +\n ` --persona <file|-> Persona file or stdin` +\n ` (required)\\n` +\n ` --skills <kbid,...> Comma-separated skill` +\n ` kbids (required)\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { docid, name, skills }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb agent create --name code-reviewer` +\n ` --persona ./p.txt --skills abc123\\n` +\n ` cat persona.txt | kbdb agent create` +\n ` --name my-agent --persona - --skills abc123\\n`,\n\n 'agent-list':\n `kbdb agent list - List all agents\\n` +\n `\\n` +\n `Usage: kbdb agent list [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON array of { docid, name, description,` +\n ` skillCount }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb agent list\\n` +\n ` kbdb agent list --db /path/to/project\\n`,\n\n 'agent-get':\n `kbdb agent get - Retrieve an agent by docid\\n` +\n `\\n` +\n `Usage: kbdb agent get [options] <docid>\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <docid> Agent document identifier\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON AgentDefinition object with resolved` +\n ` skills\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb agent get agent-code-reviewer\\n`,\n\n 'agent-delete':\n `kbdb agent delete - Remove an agent\\n` +\n `\\n` +\n `Usage: kbdb agent delete [options] <docid>\\n` +\n `\\n` +\n `Arguments:\\n` +\n ` <docid> Agent document identifier\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Output:\\n` +\n ` JSON { docid, removed }\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb agent delete agent-code-reviewer\\n`,\n\n 'worker-stop':\n `kbdb worker stop - Stop the worker daemon\\n` +\n `\\n` +\n `Usage: kbdb worker stop [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb worker stop\\n` +\n ` kbdb worker stop --db /path/to/project\\n`,\n\n 'worker-restart':\n `kbdb worker restart - Restart the worker daemon\\n` +\n `\\n` +\n `Usage: kbdb worker restart [options]\\n` +\n `\\n` +\n `Options:\\n` +\n ` --db <path> Path to .kbdb directory\\n` +\n `\\n` +\n `Examples:\\n` +\n ` kbdb worker restart\\n` +\n ` kbdb worker restart --db /path/to/project\\n`,\n};\n\nfunction generateSubcommandHelp(\n command: string,\n subcommand: string,\n): string {\n const key = `${command}-${subcommand}`;\n const text = SUBCOMMAND_HELP[key];\n if (text) {\n return text;\n }\n // Fall back to group help when subcommand is unknown\n return generateCommandHelp(command);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { DbResolution } from '../typings/db-resolution.interface.ts';\n\n/** Options controlling database directory resolution. */\ninterface ResolveDbDirOptions {\n /** Explicit `--db` flag value, if provided. */\n dbPath?: string;\n /** When true, skips cwd upward traversal. */\n skipTraversal?: boolean;\n}\n\n/**\n * Resolves the `.kbdb` database directory using a strict\n * priority chain: explicit `--db` flag, then upward cwd\n * traversal, then the `KBDB_DB_DIR` environment variable.\n *\n * An explicit `--db` flag that fails to resolve returns\n * `null` immediately -- it never falls through to\n * traversal or the environment variable.\n *\n * @param findDb - locates a `.kbdb` directory. Called with\n * a base path to resolve from, or with no argument to\n * trigger upward traversal from the current working\n * directory.\n */\nexport function resolveDbDir(\n options: ResolveDbDirOptions,\n findDb: (basePath?: string) => string | null,\n): DbResolution | null {\n if (options.dbPath) {\n const flagResult = findDb(options.dbPath);\n return flagResult ? { path: flagResult, source: 'flag' } : null;\n }\n\n if (!options.skipTraversal) {\n const traversalResult = findDb();\n if (traversalResult) {\n return { path: traversalResult, source: 'traversal' };\n }\n }\n\n const envDir = process.env['KBDB_DB_DIR'];\n if (envDir) {\n const envResult = findDb(envDir);\n if (envResult) {\n return { path: envResult, source: 'env' };\n }\n }\n\n return null;\n}\n\nexport type { ResolveDbDirOptions };\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Options controlling the \"database not found\" diagnostic. */\ninterface FormatDbNotFoundOptions {\n /** Explicit `--db` flag value, if provided. */\n dbPath?: string;\n /** When true, omits the cwd traversal line and init hint. */\n skipTraversal?: boolean;\n}\n\n/**\n * Formats the error message shown when no `.kbdb` database\n * directory can be resolved.\n *\n * When `options.dbPath` is set, an explicit `--db` flag failed\n * to resolve and a single-line message is returned. Otherwise a\n * multi-line diagnostic lists each fallback that was checked so\n * the user can see why resolution failed.\n *\n * @param options - resolution context that produced the failure\n */\nexport function formatDbNotFound(\n options: FormatDbNotFoundOptions,\n): string {\n if (options.dbPath) {\n return `error: no .kbdb database found at ${options.dbPath}`;\n }\n\n const envValue = process.env['KBDB_DB_DIR'] ?? '(not set)';\n const lines = [\n 'error: no .kbdb database found',\n ' --db: (not set)',\n ];\n\n if (!options.skipTraversal) {\n lines.push(` cwd: ${process.cwd()} (searched upward)`);\n }\n\n lines.push(` KBDB_DB_DIR: ${envValue}`);\n\n if (!options.skipTraversal) {\n lines.push('Run \"kbdb db init\" to create a database.');\n }\n\n return lines.join('\\n');\n}\n\nexport type { FormatDbNotFoundOptions };\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport { resolveDbDir } from './resolve-db-dir.function.ts';\nimport { formatDbNotFound } from './format-db-not-found.function.ts';\n\n/**\n * Handles the `kbdb db path` subcommand.\n *\n * Prints the resolved `.kbdb` directory path. With\n * `--format json`, outputs a full diagnostic object\n * showing which source provided the resolution.\n */\nexport function runDbPath(\n options: Pick<CliOptions, 'dbPath' | 'format'>,\n findDb: (basePath?: string) => string | null,\n): CommandResult {\n const resolution = resolveDbDir({ dbPath: options.dbPath }, findDb);\n\n if (!resolution) {\n return {\n error: formatDbNotFound({ dbPath: options.dbPath }),\n exitCode: 1,\n };\n }\n\n if (options.format === 'json') {\n const diagnostic = {\n path: resolution.path,\n source: resolution.source,\n flag: options.dbPath ?? null,\n cwd: process.cwd(),\n env: process.env['KBDB_DB_DIR'] ?? null,\n };\n return {\n output: JSON.stringify(diagnostic, null, 2),\n exitCode: 0,\n };\n }\n\n return { output: resolution.path, exitCode: 0 };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { connect } from 'node:net';\nimport type { Socket } from 'node:net';\nimport { discoverDaemon } from '../functions/discover-daemon.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport type { SearchParams } from '../typings/search-params.model.ts';\nimport type { PagedSearchResult } from '../typings/search-result.model.ts';\nimport type {\n AddSectionParams,\n Section,\n} from '../typings/section.model.ts';\nimport type { StatusResult } from '../typings/status-result.model.ts';\nimport type { AddSectionResult } from '../typings/add-section-result.model.ts';\nimport type { RemoveSectionResult } from '../typings/remove-section-result.model.ts';\nimport type { ContentResult } from '../typings/content-result.model.ts';\nimport type { IntegrityCheckResult } from '../typings/integrity-check-result.model.ts';\nimport type { GcResult } from '../typings/gc-result.model.ts';\nimport type { RebuildResult } from '../typings/rebuild-result.model.ts';\nimport type { MigrateResult } from '../typings/migrate-result.model.ts';\nimport type { VersionStatus } from '../typings/version-status.model.ts';\nimport type { SectionRecord } from '../../wasm-codec/functions/decode-section-records.function.ts';\nimport type { DocumentManifest } from '../../wasm-codec/functions/decode-document-manifest.function.ts';\nimport type {\n RecallParams,\n RecallResult,\n} from '../typings/recall-result.model.ts';\nimport type { ExportResult } from '../typings/export-result.model.ts';\nimport type { ImportResult } from '../typings/import-result.model.ts';\n\n/** Pending JSON-RPC call awaiting a response from the daemon. */\ninterface PendingCall {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n timer?: ReturnType<typeof setTimeout>;\n}\n\n/** Shape of a JSON-RPC 2.0 error object from the daemon. */\ninterface JsonRpcError {\n readonly code: number;\n readonly message: string;\n}\n\n/** Shape of a JSON-RPC 2.0 response from the daemon. */\ninterface JsonRpcResponse {\n readonly id: number;\n readonly result?: unknown;\n readonly error?: JsonRpcError;\n}\n\n/**\n * IPC client that communicates with the worker daemon over a Unix\n * domain socket (or Windows named pipe) using JSON-RPC 2.0 with\n * newline-delimited message framing.\n *\n * Call `connect()` before any other method and `disconnect()` when\n * done to release the underlying socket.\n */\nexport class WorkerClient {\n /** Underlying socket; `null` when not connected. */\n private socket: Socket | null = null;\n\n /** Monotonically increasing request ID counter. */\n private nextId = 1;\n\n /** Map of outstanding request IDs to their resolve/reject pairs. */\n private readonly pending = new Map<number, PendingCall>();\n\n /** Partial line buffer for split TCP/IPC frames. */\n private buffer = '';\n\n /**\n * @param socketPath - absolute path to the daemon's IPC socket\n * (or Windows named pipe path)\n * @param contextId - 16-character context identifier sent as\n * `ctx` in every JSON-RPC request\n * @param requestTimeoutMs - per-request timeout in ms\n * (0 or undefined disables the timeout)\n */\n constructor(\n private readonly socketPath: string,\n private readonly contextId: string,\n private readonly requestTimeoutMs?: number,\n ) {}\n\n /** Whether the underlying socket is connected. */\n get isConnected(): boolean {\n return this.socket !== null;\n }\n\n /**\n * Establishes the IPC connection to the worker daemon.\n *\n * Retries up to 5 times with exponential backoff on\n * transient errors (`ENOENT`, `ECONNREFUSED`).\n *\n * @throws {Error} if the connection cannot be established\n */\n async connect(): Promise<void> {\n log('connecting to ' + this.socketPath, LogLevel.DEBUG);\n const maxRetries = 5;\n let delay = 50;\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n await this.tryConnect();\n log('connected', LogLevel.DEBUG);\n return;\n } catch (err: unknown) {\n const code = (err as NodeJS.ErrnoException).code;\n const retriable =\n code === 'ENOENT' || code === 'ECONNREFUSED';\n if (!retriable || attempt === maxRetries) {\n throw err;\n }\n log(\n 'connect retry: attempt=' +\n attempt.toString() +\n ' code=' +\n code +\n ' delay=' +\n delay.toString() +\n 'ms',\n LogLevel.DEBUG,\n );\n await new Promise<void>((r) => setTimeout(r, delay));\n delay = Math.min(delay * 2, 1000);\n }\n }\n }\n\n /** Destroys the IPC socket and clears the connection state. */\n disconnect(): void {\n log('disconnecting client', LogLevel.DEBUG);\n if (this.socket) {\n this.socket.destroy();\n this.socket = null;\n }\n }\n\n /**\n * Kills the daemon process and disconnects the client.\n *\n * Discovers the daemon via PID file and sends `SIGTERM`.\n * Always disconnects the socket regardless of kill outcome.\n */\n killDaemon(): void {\n const info = discoverDaemon(this.contextId);\n log(\n 'killing daemon: pid=' +\n (info ? info.pid.toString() : 'unknown'),\n LogLevel.DEBUG,\n );\n if (info) {\n try {\n process.kill(info.pid, 'SIGTERM');\n } catch {\n // already dead\n }\n }\n this.disconnect();\n }\n\n /**\n * Single connection attempt with keepalive and\n * post-connect failure handlers.\n */\n private async tryConnect(): Promise<void> {\n return new Promise<void>((resolve, reject) => {\n const sock = connect(this.socketPath, () => {\n sock.removeListener('error', reject);\n sock.setKeepAlive(true, 30_000);\n sock.on('error', (err: Error) => {\n log(\n 'socket error: code=' +\n ((err as NodeJS.ErrnoException).code ??\n err.message),\n LogLevel.DEBUG,\n );\n this.handleSocketFailure(err);\n });\n sock.on('close', () => {\n log('socket closed', LogLevel.DEBUG);\n if (this.pending.size > 0) {\n this.handleSocketFailure(\n new Error('connection closed'),\n );\n }\n this.socket = null;\n });\n this.socket = sock;\n resolve();\n });\n sock.on('error', reject);\n sock.on('data', (chunk: Buffer) => {\n this.handleData(chunk.toString());\n });\n });\n }\n\n /**\n * Rejects all pending calls and marks the client as\n * disconnected.\n */\n private handleSocketFailure(err: Error): void {\n log(\n 'socket failure: pending=' +\n this.pending.size.toString() +\n ' err=' +\n err.message,\n LogLevel.DEBUG,\n );\n const sock = this.socket;\n this.socket = null;\n for (const [id, call] of this.pending) {\n this.pending.delete(id);\n if (call.timer) clearTimeout(call.timer);\n call.reject(err);\n }\n if (sock) sock.destroy();\n }\n\n /**\n * Searches the knowledge base.\n *\n * @param params - query parameters including the search string\n * @returns paginated search results with metadata\n */\n async search(params: SearchParams): Promise<PagedSearchResult> {\n return this.call('search', {\n ...params,\n algo: params.algo,\n }) as Promise<PagedSearchResult>;\n }\n\n /**\n * Retrieves full content and context for one or more sections by\n * their knowledge-base identifiers.\n *\n * @param params - section identifier(s) and optional expansion depth\n * @returns a single `RecallResult` when `kbid` is provided without\n * `kbids`, or a `RecallResult[]` when `kbids` is provided\n */\n async recall(\n params: RecallParams,\n ): Promise<RecallResult | RecallResult[]> {\n return this.call('recall', params) as Promise<\n RecallResult | RecallResult[]\n >;\n }\n\n /**\n * Adds a new section to the knowledge base.\n *\n * @param params - section content and metadata\n * @returns the result including the assigned knowledge-base\n * identifier and indexing statistics\n */\n async addSection(\n params: AddSectionParams,\n ): Promise<AddSectionResult> {\n return this.call(\n 'addSection',\n params,\n ) as Promise<AddSectionResult>;\n }\n\n /**\n * Replaces an existing section's content and metadata.\n *\n * @param kbid - identifier of the section to update\n * @param params - new content and metadata\n * @returns the knowledge-base identifier of the updated section\n */\n async updateSection(\n kbid: string,\n params: AddSectionParams,\n ): Promise<string> {\n return this.call('updateSection', {\n kbid,\n ...params,\n }) as Promise<string>;\n }\n\n /**\n * Removes a section from the knowledge base.\n *\n * @param kbid - identifier of the section to remove\n * @returns removal result with `removed` flag and elapsed time\n */\n async removeSection(kbid: string): Promise<RemoveSectionResult> {\n return this.call('removeSection', {\n kbid,\n }) as Promise<RemoveSectionResult>;\n }\n\n /**\n * Retrieves multiple sections by their identifiers.\n *\n * @param kbids - list of knowledge-base identifiers to fetch\n * @returns sections in the order their IDs were requested\n */\n async readSections(kbids: string[]): Promise<Section[]> {\n return this.call('readSections', {\n kbids,\n }) as Promise<Section[]>;\n }\n\n /**\n * Groups a set of sections under a named document.\n *\n * @param title - human-readable document title\n * @param kbids - identifiers of the sections to group\n * @param docType - application-level document type tag; omit or\n * pass an empty string for untagged documents\n * @returns the assigned document identifier\n */\n async groupSections(\n title: string,\n kbids: string[],\n docType?: string,\n ): Promise<string> {\n const result = (await this.call('groupSections', {\n title,\n kbids,\n docType: docType ?? '',\n })) as { docid: string } | string;\n return typeof result === 'string' ? result : result.docid;\n }\n\n /**\n * Removes the document grouping for the given document.\n *\n * The sections themselves are not deleted; only the grouping\n * record is removed.\n *\n * @param docid - identifier of the document grouping to remove\n */\n async removeGrouping(docid: string): Promise<void> {\n await this.call('removeGrouping', { docid });\n }\n\n /**\n * Retrieves a full document record including its sections.\n *\n * @param docid - identifier of the document to retrieve\n * @returns the document record as returned by the daemon\n */\n async retrieveDocument(docid: string): Promise<unknown> {\n return this.call('retrieveDocument', { docid });\n }\n\n /**\n * Composes a rendered Markdown document from one or more kbid\n * or docid identifiers.\n *\n * @param ids - list of kbid or docid identifiers (may be mixed)\n * @returns composed Markdown result with character count\n */\n async content(ids: string[]): Promise<ContentResult> {\n return this.call('content', { ids }) as Promise<ContentResult>;\n }\n\n /**\n * Runs an integrity check on the knowledge-base database.\n *\n * @returns a report of all issues found; `ok` is `true` when\n * no errors were detected\n */\n async integrityCheck(): Promise<IntegrityCheckResult> {\n return this.call(\n 'integrityCheck',\n {},\n ) as Promise<IntegrityCheckResult>;\n }\n\n /**\n * Removes unreferenced sections from the database.\n *\n * @returns a report of sections removed and bytes freed\n */\n async gc(): Promise<GcResult> {\n return this.call('gc', {}) as Promise<GcResult>;\n }\n\n /**\n * Reconstructs all index files from section files and document\n * manifests on disk. Text and code sections are re-tokenized;\n * image sections are skipped.\n *\n * @returns a report of sections and terms re-indexed\n */\n async rebuildIndexes(): Promise<RebuildResult> {\n return this.call('rebuildIndexes', {}) as Promise<RebuildResult>;\n }\n\n /**\n * Invalidates the in-memory cache entry for a single section.\n *\n * @param kbid - identifier of the section to evict from cache\n */\n async invalidate(kbid: string): Promise<void> {\n await this.call('invalidate', { kbid });\n }\n\n /** Clears all entries from the daemon's in-memory cache. */\n async invalidateAll(): Promise<void> {\n await this.call('invalidateAll', {});\n }\n\n /**\n * Retrieves diagnostic status information from the daemon.\n *\n * @returns current initialization state and cache statistics\n */\n async status(): Promise<StatusResult> {\n return this.call('status', {}) as Promise<StatusResult>;\n }\n\n /**\n * Returns database metadata and status from the daemon,\n * including document count, section count, index size, and\n * cache statistics.\n *\n * @returns database metadata from the daemon's cached state\n */\n async dbStatus(): Promise<StatusResult> {\n return this.call('dbStatus', {}) as Promise<StatusResult>;\n }\n\n /**\n * Initialises a new `.kbdb` database directory at the given path\n * by sending an init request to the worker daemon.\n *\n * The daemon creates all required subdirectories and seed files via\n * the `worker_init_directory` WASM export.\n *\n * @param targetPath - absolute path to the directory that will\n * contain the new `.kbdb` database\n * @throws {Error} if the `.kbdb` directory already exists or the\n * daemon cannot create the layout\n */\n async initDirectory(targetPath: string): Promise<void> {\n await this.call('initDirectory', { targetPath });\n }\n\n /**\n * Runs all pending database migrations for the `.kbdb` directory\n * at the given path.\n *\n * Delegates to the `worker_migrate` WASM export on the daemon.\n * Each migration step updates `catalog.toml` on success, so\n * retrying after a partial failure is safe.\n *\n * @param targetPath - absolute path to the `.kbdb` database root\n * @returns migration report with old version, new version, and\n * number of migration steps applied\n */\n async migrateDatabase(targetPath: string): Promise<MigrateResult> {\n return this.call('migrateDatabase', {\n targetPath,\n }) as Promise<MigrateResult>;\n }\n\n /**\n * Checks the format version of the `.kbdb` database at the given\n * path against the version required by the current WASM engine.\n *\n * This is a read-only operation: it reads `catalog.toml` and\n * returns the compatibility status without making any changes.\n *\n * @param targetPath - absolute path to the `.kbdb` database root\n * @returns version compatibility report\n */\n async checkVersion(targetPath: string): Promise<VersionStatus> {\n return this.call('checkVersion', {\n targetPath,\n }) as Promise<VersionStatus>;\n }\n\n /**\n * Retrieves all sections whose type name matches the given string.\n *\n * @param sectionType - the application-level type name to filter by\n * @returns all section records with a matching type name\n */\n async listByType(sectionType: string): Promise<SectionRecord[]> {\n return this.call('listByType', {\n sectionType,\n }) as Promise<SectionRecord[]>;\n }\n\n /**\n * Retrieves all documents whose type name matches the given string.\n *\n * @param docType - the application-level document type to filter by\n * @returns all document manifests with a matching type name\n */\n async listDocumentsByType(\n docType: string,\n ): Promise<DocumentManifest[]> {\n return this.call('listDocumentsByType', {\n docType,\n }) as Promise<DocumentManifest[]>;\n }\n\n /**\n * Exports the database to a target directory on disk.\n *\n * Copies section files, document manifests, and `catalog.toml`\n * to `params.path`. Index files are not exported because they\n * are derivable from the section and document data.\n *\n * @param params - optional export parameters\n * @param params.path - target directory path; defaults to\n * `./kbdb-export/` when not provided\n * @returns export report with the resolved path and file counts\n */\n async export(params?: {\n path?: string;\n format?: string;\n }): Promise<ExportResult> {\n return this.call('export', {\n targetPath: params?.path || undefined,\n format: params?.format,\n }) as Promise<ExportResult>;\n }\n\n /**\n * Imports an exported database from the given path.\n *\n * @param params - source path and dry-run flag\n * @returns import report with counts and timing\n */\n async import(params: {\n from: string;\n dryRun: boolean;\n }): Promise<ImportResult> {\n return this.call('importDb', {\n sourcePath: params.from,\n dryRun: params.dryRun,\n }) as Promise<ImportResult>;\n }\n\n /**\n * Sends a JSON-RPC 2.0 request and awaits the response.\n *\n * @param method - the RPC method name\n * @param params - parameters to include in the request\n * @throws {Error} if not connected\n * @throws {Error} when the daemon returns an error response\n */\n private async call(\n method: string,\n params: unknown,\n ): Promise<unknown> {\n const socket = this.socket;\n if (!socket) {\n throw new Error('not connected');\n }\n\n const id = this.nextId++;\n log(\n 'call: method=' + method + ' id=' + id.toString(),\n LogLevel.DEBUG,\n );\n const request = {\n jsonrpc: '2.0',\n id,\n method,\n params: { ctx: this.contextId, ...(params as object) },\n };\n\n const timeoutMs = this.requestTimeoutMs;\n return new Promise<unknown>((resolve, reject) => {\n const call: PendingCall = { resolve, reject };\n if (timeoutMs) {\n call.timer = setTimeout(() => {\n if (!this.pending.has(id)) return;\n this.pending.delete(id);\n log(\n 'request timeout after ' + String(timeoutMs) + 'ms',\n LogLevel.WARNING,\n );\n const err = new Error(\n `request timeout after ${String(timeoutMs)}ms`,\n );\n (err as unknown as Record<string, unknown>).code =\n 'REQUEST_TIMEOUT';\n reject(err);\n }, timeoutMs);\n }\n this.pending.set(id, call);\n socket.write(JSON.stringify(request) + '\\n');\n });\n }\n\n /**\n * Processes incoming data from the socket, splitting on newlines\n * and dispatching complete JSON-RPC response objects.\n *\n * @param data - raw string chunk received from the socket\n */\n private handleData(data: string): void {\n this.buffer += data;\n const lines = this.buffer.split('\\n');\n this.buffer = lines.pop() ?? '';\n\n for (const line of lines) {\n if (!line.trim()) continue;\n try {\n const response = JSON.parse(line) as JsonRpcResponse;\n const pending = this.pending.get(response.id);\n if (pending) {\n this.pending.delete(response.id);\n if (pending.timer) clearTimeout(pending.timer);\n if (response.error) {\n log(\n 'response error: id=' +\n response.id.toString() +\n ' code=' +\n response.error.code.toString(),\n LogLevel.DEBUG,\n );\n const err = new Error(response.error.message);\n (err as unknown as Record<string, unknown>).code =\n response.error.code;\n pending.reject(err);\n } else {\n log(\n 'response ok: id=' + response.id.toString(),\n LogLevel.DEBUG,\n );\n pending.resolve(response.result);\n }\n } else {\n log(\n 'unmatched response id=' + response.id.toString(),\n LogLevel.DEBUG,\n );\n }\n } catch (parseErr: unknown) {\n log(\n 'json parse error: ' + (parseErr as Error).message,\n LogLevel.DEBUG,\n );\n }\n }\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync, readFileSync, unlinkSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { isProcessAlive } from '../../platform/functions/is-process-alive.function.ts';\nimport type { DaemonInfo } from '../typings/daemon-info.model.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\nexport type { DaemonInfo };\n\n/**\n * Discovers a running worker daemon for the given context.\n *\n * Reads the PID file at `<tmpdir>/kbdb-<contextId>.pid`. If the\n * file exists and the process is alive, returns its PID and the\n * expected socket path. If the file is stale (process dead or PID\n * unparseable), removes the PID file and returns `null`.\n *\n * @param contextId - the 16-character context identifier\n * @returns daemon location info, or `null` if no live daemon found\n */\nexport function discoverDaemon(contextId: string): DaemonInfo | null {\n log('discovering daemon for context: ' + contextId, LogLevel.DEBUG);\n const pidPath = join(tmpdir(), `kbdb-${contextId}.pid`);\n\n if (!existsSync(pidPath)) {\n log(\n 'no daemon PID file found for context: ' + contextId,\n LogLevel.DEBUG,\n );\n return null;\n }\n\n const pidStr = readFileSync(pidPath, 'utf-8').trim();\n const pid = parseInt(pidStr, 10);\n\n if (isNaN(pid) || !isProcessAlive(pid)) {\n log(\n 'daemon process not alive for context: ' + contextId,\n LogLevel.DEBUG,\n );\n try {\n unlinkSync(pidPath);\n } catch {\n // Stale PID file removal is best-effort\n }\n return null;\n }\n\n log('daemon found: pid=' + pid.toString(), LogLevel.DEBUG);\n const socketPath = join(tmpdir(), `kbdb-${contextId}.sock`);\n\n const crashPath = join(tmpdir(), `kbdb-${contextId}.crash`);\n try {\n unlinkSync(crashPath);\n } catch {\n // stale crash file removal is best-effort\n }\n\n return { pid, socketPath };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Checks whether a process with the given PID is alive.\n *\n * Sends signal `0` to the process, which performs a permission\n * check without sending an actual signal. Returns `true` if the\n * process exists and is reachable, `false` otherwise.\n *\n * @param pid - the process identifier to probe\n */\nexport function isProcessAlive(pid: number): boolean {\n try {\n process.kill(pid, 0);\n return true;\n } catch {\n return false;\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync } from 'node:fs';\nimport { join, resolve } from 'node:path';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Resolves the absolute path to the `.kbdb` database directory.\n *\n * Searches for a `.kbdb` sub-directory inside `targetDir`. When\n * `targetDir` is omitted, `process.cwd()` is used as the base.\n *\n * @param targetDir - directory to search in; defaults to cwd\n * @throws {Error} if no `.kbdb` directory exists at the resolved\n * path\n */\nexport function resolveDbPath(targetDir?: string): string {\n const base = targetDir ? resolve(targetDir) : process.cwd();\n const dbPath = join(base, '.kbdb');\n if (!existsSync(dbPath)) {\n const msg = `database not found: ${dbPath}`;\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n return dbPath;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { computeSha256 } from '../../hash/functions/compute-sha256.ts';\n\n/**\n * Computes a short context identifier for an absolute path.\n *\n * Hashes the path with SHA-256 and returns the first 16 hex\n * characters. The result is stable for the same input and unique\n * enough to avoid accidental collisions across typical path sets.\n *\n * @param absolutePath - the absolute filesystem path to identify\n * @returns a 16-character lowercase hex string\n */\nexport async function computeContextId(\n absolutePath: string,\n): Promise<string> {\n const hash = await computeSha256(absolutePath);\n return hash.slice(0, 16);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { spawn } from 'node:child_process';\nimport type { Runtime } from '../../runtime/typings/runtime.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { buildDenoPermissions } from './build-deno-permissions.function.ts';\n\n/**\n * Spawns a detached worker daemon process for the given context.\n *\n * @param contextPath - absolute path to the context directory the\n * daemon should serve\n * @param runtime - the current JavaScript runtime environment\n * @param workerScript - absolute path to the worker daemon script,\n * resolved by `resolveSpawnScript`\n */\nexport function spawnDaemon(\n contextPath: string,\n runtime: Runtime,\n workerScript?: string,\n): void {\n if (!workerScript) {\n const msg =\n 'workerScript must be provided' + ' (resolve at entry point)';\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n const execPath = runtime === 'deno' ? 'deno' : process.execPath;\n\n const logLevelEnv = process.env['KBDB_LOG_LEVEL'];\n const logArgs = logLevelEnv ? ['--log-level', logLevelEnv] : [];\n\n const args =\n runtime === 'deno'\n ? [\n 'run',\n ...buildDenoPermissions(),\n workerScript,\n contextPath,\n ...logArgs,\n ]\n : [workerScript, contextPath, ...logArgs];\n\n log(\n 'spawning daemon: ' + execPath + ' ' + args.join(' '),\n LogLevel.DEBUG,\n );\n const child = spawn(execPath, args, {\n detached: true,\n stdio: 'ignore',\n });\n child.unref();\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Deno permission flags for the worker daemon.\n *\n * - read: WASM modules, DB files, config\n * - write: DB files, IPC socket, crash logs, exports\n * - env: KBDB_LOG_LEVEL, HOME, TMPDIR, XDG_RUNTIME_DIR\n * - run: not used by daemon itself (CLI needs it to\n * spawn the daemon, included for symmetry)\n * - sys: os.tmpdir(), os.hostname() via node:os compat\n */\nexport function buildDenoPermissions(): string[] {\n return [\n '--allow-read',\n '--allow-write',\n '--allow-env',\n '--allow-run',\n '--allow-sys',\n ];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/** Default maximum wait time for the daemon PID file to appear. */\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\n/** Polling interval in milliseconds between existence checks. */\nconst POLL_INTERVAL_MS = 100;\n\n/**\n * Waits for the worker daemon's PID file to appear on disk.\n *\n * Polls every 100 ms until the PID file at\n * `<tmpdir>/kbdb-<contextId>.pid` exists or the timeout elapses.\n *\n * @param contextId - the 16-character context identifier\n * @param timeoutMs - maximum wait time in milliseconds; defaults\n * to 10 000 ms\n * @returns `true` if the PID file appeared before the timeout,\n * `false` otherwise\n */\nexport async function waitForDaemon(\n contextId: string,\n timeoutMs: number = DEFAULT_TIMEOUT_MS,\n): Promise<boolean> {\n log('waiting for daemon: contextId=' + contextId, LogLevel.DEBUG);\n const pidPath = join(tmpdir(), `kbdb-${contextId}.pid`);\n const start = Date.now();\n let iteration = 0;\n while (Date.now() - start < timeoutMs) {\n if (existsSync(pidPath)) {\n log('daemon PID file appeared', LogLevel.DEBUG);\n return true;\n }\n iteration++;\n if (iteration % 10 === 0) {\n const elapsed = Date.now() - start;\n log(\n 'still waiting for daemon: elapsed=' +\n elapsed.toString() +\n 'ms',\n LogLevel.DEBUG,\n );\n }\n await new Promise<void>((r) => setTimeout(r, POLL_INTERVAL_MS));\n }\n const elapsed = Date.now() - start;\n log(\n 'timed out waiting for daemon: elapsed=' +\n elapsed.toString() +\n 'ms',\n LogLevel.DEBUG,\n );\n return false;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { existsSync, readFileSync, unlinkSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { tmpdir } from 'node:os';\n\n/**\n * Reads and clears the crash log written by a worker daemon that\n * failed to start, returning a human-readable reason.\n *\n * @param contextId - the 16-char hex context ID for the daemon\n * @returns the recorded crash error, or a fallback message when no\n * usable crash log is found\n */\nexport function readCrashReason(contextId: string): string {\n const crashPath = join(tmpdir(), `kbdb-${contextId}.crash`);\n if (!existsSync(crashPath)) {\n return 'daemon failed to start (no details available)';\n }\n try {\n const raw = readFileSync(crashPath, 'utf-8');\n const crash = JSON.parse(raw) as { error?: string };\n unlinkSync(crashPath);\n return crash.error ?? 'unknown error (crash log empty)';\n } catch {\n return 'daemon failed to start (crash log unreadable)';\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { dirname, resolve } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\nimport { resolveWorkerScript } from '../../dir-resolver/index.ts';\n\nimport type { Runtime } from '../../runtime/typings/runtime.ts';\n\n/**\n * Resolves the worker daemon script path from within\n * the worker-client module.\n */\nexport function resolveSpawnScript(runtime: Runtime): string {\n return resolveWorkerScript(resolveScriptDir(runtime), runtime);\n}\n\nfunction resolveScriptDir(runtime: Runtime): string {\n if (typeof __dirname !== 'undefined') return __dirname;\n const thisDir = dirname(fileURLToPath(import.meta.url));\n if (runtime === 'deno') {\n return resolve(thisDir, '..', '..', '..');\n }\n return thisDir;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { WorkerClient } from '../classes/worker-client.class.ts';\nimport { resolveDbPath } from './resolve-db-path.function.ts';\nimport { computeContextId } from './compute-context-id.function.ts';\nimport { discoverDaemon } from './discover-daemon.function.ts';\nimport { spawnDaemon } from './spawn-daemon.function.ts';\nimport { waitForDaemon } from './wait-for-daemon.function.ts';\nimport { readCrashReason } from './read-crash-reason.function.ts';\nimport { detectRuntime } from '../../runtime/functions/detect-runtime.ts';\nimport { resolveSpawnScript } from './resolve-spawn-script.function.ts';\nimport { getIpcPath } from '../../platform/functions/get-ipc-path.function.ts';\nimport type { WorkerClientOptions } from '../typings/worker-client-options.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Creates and connects a `WorkerClient` to the worker daemon.\n *\n * Resolves the context path, derives a stable context identifier,\n * and checks whether a daemon is already running. If no daemon is\n * found and `autoSpawn` is not `false`, a new daemon process is\n * spawned and the factory waits for its PID file to appear before\n * connecting.\n *\n * @param options - optional configuration for path resolution,\n * auto-spawn behaviour, and connection timeout\n * @returns a connected `WorkerClient` ready to send requests\n * @throws {Error} if the `.kbdb` directory cannot be found\n * @throws {Error} if the socket connection cannot be established\n */\nexport async function createWorkerClient(\n options?: WorkerClientOptions,\n): Promise<WorkerClient> {\n const dbPath =\n options?.contextPath ?? resolveDbPath(options?.dbPath);\n const contextId = await computeContextId(dbPath);\n log('create-worker-client: contextId=' + contextId, LogLevel.DEBUG);\n const socketPath = getIpcPath(contextId);\n\n let daemon = discoverDaemon(contextId);\n\n if (daemon) {\n log('daemon found: pid=' + daemon.pid.toString(), LogLevel.DEBUG);\n } else {\n log('no daemon found', LogLevel.DEBUG);\n }\n\n if (!daemon && options?.autoSpawn !== false) {\n const runtime = detectRuntime();\n log('auto-spawning daemon', LogLevel.DEBUG);\n const workerScript = resolveSpawnScript(runtime);\n spawnDaemon(dbPath, runtime, workerScript);\n log('waiting for daemon after spawn', LogLevel.DEBUG);\n await waitForDaemon(contextId, options?.connectTimeoutMs);\n daemon = discoverDaemon(contextId);\n }\n\n if (!daemon) {\n const msg = `kbdb worker daemon did not start: ${readCrashReason(contextId)}`;\n log(msg, LogLevel.ERROR);\n throw new Error(msg);\n }\n\n log('connecting to daemon', LogLevel.DEBUG);\n const client = new WorkerClient(\n socketPath,\n contextId,\n options?.requestTimeoutMs,\n );\n await client.connect();\n return client;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport {\n computeContextId,\n discoverDaemon,\n} from '../../worker-client/index.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Stops the worker daemon for the resolved database path.\n *\n * Discovers the daemon via its PID file and sends `SIGTERM`.\n * Returns success when the daemon was stopped or was not running.\n *\n * @param dbDir - absolute path to the `.kbdb` directory\n * @returns command result indicating success or failure\n */\nexport async function runWorkerStop(\n dbDir: string,\n): Promise<CommandResult> {\n log('running worker-stop', LogLevel.DEBUG);\n const contextId = await computeContextId(dbDir);\n const info = discoverDaemon(contextId);\n if (!info) {\n return { output: 'no daemon running', exitCode: 0 };\n }\n log('pid found: ' + info.pid.toString(), LogLevel.DEBUG);\n try {\n process.kill(info.pid, 'SIGTERM');\n log('sigterm sent to pid=' + info.pid.toString(), LogLevel.DEBUG);\n } catch {\n return {\n error: 'error: failed to stop daemon',\n exitCode: 1,\n };\n }\n\n const deadline = Date.now() + 5_000;\n let pollIteration = 0;\n while (Date.now() < deadline) {\n try {\n process.kill(info.pid, 0);\n } catch {\n log(\n 'process exited: pid=' + info.pid.toString(),\n LogLevel.DEBUG,\n );\n break;\n }\n pollIteration++;\n if (pollIteration % 5 === 0) {\n log(\n 'waiting for exit: pid=' +\n info.pid.toString() +\n ' poll=' +\n pollIteration.toString(),\n LogLevel.DEBUG,\n );\n }\n await new Promise<void>((r) => setTimeout(r, 100));\n }\n\n if (Date.now() >= deadline) {\n log(\n 'timed out waiting for exit: pid=' + info.pid.toString(),\n LogLevel.DEBUG,\n );\n }\n\n return {\n output: `stopped daemon (pid ${info.pid.toString()})`,\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport { runWorkerStop } from './run-worker-stop.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Restarts the worker daemon by stopping any running instance.\n *\n * The daemon auto-spawns on the next CLI command, so restart\n * only needs to stop the current instance.\n *\n * @param dbDir - absolute path to the `.kbdb` directory\n * @returns command result indicating success or failure\n */\nexport async function runWorkerRestart(\n dbDir: string,\n): Promise<CommandResult> {\n log('running worker-restart', LogLevel.DEBUG);\n const stopResult = await runWorkerStop(dbDir);\n if (stopResult.exitCode !== 0) return stopResult;\n return {\n output: 'daemon will restart on next command',\n exitCode: 0,\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Retries an operation when the daemon responds with\n * a `REQUEST_TIMEOUT` error. Each retry disconnects\n * the current client, creates a fresh one (which\n * auto-spawns the daemon), and re-runs the operation.\n *\n * @param createClient - factory that returns a connected client\n * @param operation - the work to perform with the client\n * @param maxRetries - maximum retry attempts\n * @returns the final client and result\n */\nexport async function retryOnTimeout<\n TClient extends {\n disconnect(): void;\n killDaemon?: () => void;\n },\n TResult,\n>(\n createClient: () => Promise<TClient>,\n operation: (client: TClient) => Promise<TResult>,\n maxRetries: number,\n): Promise<{ client: TClient; result: TResult }> {\n let lastError: Error = new Error('retryOnTimeout exhausted');\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n log(\n 'retry-on-timeout: attempt=' +\n attempt.toString() +\n ' max=' +\n maxRetries.toString(),\n LogLevel.DEBUG,\n );\n const client = await createClient();\n try {\n const result = await operation(client);\n log(\n 'retry-on-timeout: success on attempt=' +\n attempt.toString(),\n LogLevel.DEBUG,\n );\n return { client, result };\n } catch (err: unknown) {\n const code = (err as Record<string, unknown>).code;\n if (code !== 'REQUEST_TIMEOUT' || attempt >= maxRetries) {\n log(\n 'retry-on-timeout: non-retriable error code=' +\n String(code),\n LogLevel.DEBUG,\n );\n client.disconnect();\n throw err;\n }\n lastError = err as Error;\n if (client.killDaemon) {\n log(\n 'retry ' +\n String(attempt + 1) +\n '/' +\n String(maxRetries) +\n ': killing daemon',\n LogLevel.WARNING,\n );\n client.killDaemon();\n } else {\n client.disconnect();\n }\n }\n }\n log(\n 'retry-on-timeout: all retries exhausted max=' +\n maxRetries.toString(),\n LogLevel.DEBUG,\n );\n throw lastError;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Default per-request timeout for daemon IPC calls (ms). */\nexport const DEFAULT_REQUEST_TIMEOUT_MS = 30_000;\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** Default number of retries on request timeout. */\nexport const DEFAULT_RETRY_COUNT = 5;\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { VERSION } from '../../version/index.ts';\nimport type { CliOptions } from '../typings/cli-options.interface.ts';\nimport type { CommandResult } from '../typings/command-result.model.ts';\nimport type { InitResult } from './run-init.function.ts';\nimport type { VersionStatus } from '../../worker-client/typings/version-status.model.ts';\nimport type { MigrateResult } from '../../worker-client/typings/migrate-result.model.ts';\nimport { parseArgs } from './parse-args.function.ts';\nimport { errorToMessage } from './error-to-message.function.ts';\nimport { dispatchCommand } from './dispatch-command.function.ts';\nimport type { DispatchClient } from './dispatch-command.function.ts';\nimport {\n generateHelp,\n isKnownCommand,\n} from './generate-help.function.ts';\nimport { runDbPath } from './run-db-path.function.ts';\nimport { runWorkerStop } from './run-worker-stop.function.ts';\nimport { runWorkerRestart } from './run-worker-restart.function.ts';\nimport { resolveDbDir } from './resolve-db-dir.function.ts';\nimport { formatDbNotFound } from './format-db-not-found.function.ts';\nimport { retryOnTimeout } from '../../worker-client/functions/retry-on-timeout.function.ts';\nimport { DEFAULT_REQUEST_TIMEOUT_MS } from '../../worker-client/constants/request-timeout.constant.ts';\nimport { DEFAULT_RETRY_COUNT } from '../../worker-client/constants/retry-defaults.constant.ts';\nimport { resolveLogLevel } from '../../log/functions/resolve-log-level.function.ts';\nimport { configureLog } from '../../log/functions/configure-log.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\nexport interface DisconnectableClient extends DispatchClient {\n checkVersion(targetPath: string): Promise<VersionStatus>;\n migrateDatabase(targetPath: string): Promise<MigrateResult>;\n disconnect(): void;\n}\n\n/**\n * Injectable dependencies for the CLI orchestrator.\n *\n * Every external side-effect is injected so the function\n * is fully testable without touching process globals,\n * filesystem, or network.\n */\nexport interface CliDeps {\n isStdinTty: () => boolean;\n isStdoutTty: () => boolean;\n promptUser: (question: string) => Promise<string>;\n createWorkerClient: (opts: {\n contextPath: string;\n requestTimeoutMs?: number;\n }) => Promise<DisconnectableClient>;\n findDb: (basePath?: string) => string | null;\n runInit: (options: CliOptions) => InitResult;\n startMcpServer?: (\n contextPath: string,\n clientFactory?: () => Promise<DisconnectableClient>,\n maxRetries?: number,\n ) => Promise<void>;\n}\n\n/**\n * Full CLI orchestrator extracted from `src/cli.ts`.\n *\n * Parses arguments, routes to the appropriate sub-flow\n * (help, version, init, mcp, migrate, data commands), and\n * returns a `CommandResult` without touching process globals.\n *\n * @param argv - raw CLI arguments (typically `process.argv.slice(2)`)\n * @param deps - injectable dependencies\n */\nexport async function runCli(\n argv: string[],\n deps: CliDeps,\n): Promise<CommandResult> {\n const options = parseArgs(argv);\n\n const logLevel = resolveLogLevel(options.logLevel);\n configureLog({ level: logLevel });\n log('command: ' + options.command, LogLevel.DEBUG);\n\n if (options.command === 'init') {\n log('--init is deprecated, use \"kbdb db init\"', LogLevel.WARNING);\n }\n if (options.command === 'migrate') {\n log(\n '--migrate is deprecated, use \"kbdb db migrate\"',\n LogLevel.WARNING,\n );\n }\n\n const nonInteractive =\n options.nonInteractive ||\n process.env['KBDB_NON_INTERACTIVE'] === '1' ||\n process.env['KBDB_NON_INTERACTIVE'] === 'true';\n const effectiveDeps: CliDeps = nonInteractive\n ? { ...deps, isStdinTty: () => false }\n : deps;\n\n if (options.command === 'help' || !options.command) {\n const helpCommand = options.args[0];\n const helpSubcommand = options.args[1];\n const helpText = generateHelp(helpCommand, helpSubcommand);\n if (helpCommand && !isKnownCommand(helpCommand)) {\n return { output: helpText, exitCode: 1 };\n }\n return { output: helpText, exitCode: 0 };\n }\n\n if (options.command === 'version') {\n return { output: VERSION, exitCode: 0 };\n }\n\n if (options.command === 'init' || options.command === 'db-init') {\n return handleInit(options, effectiveDeps);\n }\n\n if (options.command === 'db-path') {\n return runDbPath(options, effectiveDeps.findDb);\n }\n\n if (options.command === 'mcp') {\n return handleMcp(options, effectiveDeps);\n }\n\n if (\n options.command === 'migrate' ||\n options.command === 'db-migrate'\n ) {\n return handleMigrate(options, effectiveDeps);\n }\n\n if (options.command === 'worker-stop') {\n return handleWorkerLifecycle(\n options,\n effectiveDeps,\n runWorkerStop,\n );\n }\n\n if (options.command === 'worker-restart') {\n return handleWorkerLifecycle(\n options,\n effectiveDeps,\n runWorkerRestart,\n );\n }\n\n return handleDataCommand(options, effectiveDeps);\n}\n\nfunction handleInit(options: CliOptions, deps: CliDeps): CommandResult {\n const result = deps.runInit(options);\n if (result.ok) {\n return {\n output: result.targetPath,\n exitCode: 0,\n };\n }\n const msg = result.errorMessage ?? 'init failed';\n if (/already exists/i.test(msg)) {\n return {\n output: `${result.targetPath} (already initialized)`,\n exitCode: 0,\n };\n }\n return {\n error: `error: ${msg}`,\n exitCode: 1,\n };\n}\n\nfunction resolveTimeoutMs(options: CliOptions): number {\n return (\n options.timeoutMs ??\n (parseInt(process.env['KBDB_DAEMON_TIMEOUT'] ?? '', 10) ||\n DEFAULT_REQUEST_TIMEOUT_MS)\n );\n}\n\nfunction resolveRetryCount(options: CliOptions): number {\n return (\n options.retry ??\n (parseInt(process.env['KBDB_RETRY'] ?? '', 10) ||\n DEFAULT_RETRY_COUNT)\n );\n}\n\nasync function handleMcp(\n options: CliOptions,\n deps: CliDeps,\n): Promise<CommandResult> {\n const resolution = resolveDbDir(\n { dbPath: options.dbPath, skipTraversal: true },\n deps.findDb,\n );\n if (!resolution) {\n return {\n error: formatDbNotFound({\n dbPath: options.dbPath,\n skipTraversal: true,\n }),\n exitCode: 1,\n };\n }\n const dbDir = resolution.path;\n\n const timeoutMs = resolveTimeoutMs(options);\n const maxRetries = resolveRetryCount(options);\n let client: DisconnectableClient;\n try {\n client = await deps.createWorkerClient({\n contextPath: dbDir,\n requestTimeoutMs: timeoutMs,\n });\n } catch (err) {\n return {\n error: `error: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n\n try {\n const gateResult = await versionGate(client, dbDir);\n if (gateResult) return gateResult;\n\n if (deps.startMcpServer) {\n await deps.startMcpServer(\n dbDir,\n () =>\n deps.createWorkerClient({\n contextPath: dbDir,\n requestTimeoutMs: timeoutMs,\n }),\n maxRetries,\n );\n }\n return { exitCode: 0 };\n } catch (err) {\n return {\n error: `error: mcp failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n } finally {\n client.disconnect();\n }\n}\n\nasync function handleMigrate(\n options: CliOptions,\n deps: CliDeps,\n): Promise<CommandResult> {\n const resolution = resolveDbDir(\n { dbPath: options.dbPath },\n deps.findDb,\n );\n if (!resolution) {\n return {\n error: formatDbNotFound({ dbPath: options.dbPath }),\n exitCode: 1,\n };\n }\n const dbDir = resolution.path;\n\n let client: DisconnectableClient;\n try {\n client = await deps.createWorkerClient({\n contextPath: dbDir,\n });\n } catch (err) {\n return {\n error: `error: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n\n try {\n const versionStatus = await client.checkVersion(dbDir);\n\n if (versionStatus.status === 'too_new') {\n return {\n error:\n `error: database version` +\n ` ${versionStatus.currentVersion.toString()}` +\n ` is newer than kbdb version` +\n ` ${versionStatus.requiredVersion.toString()}` +\n ` -- upgrade kbdb`,\n exitCode: 1,\n };\n }\n\n if (versionStatus.status === 'needs_migration') {\n const migrateResult = await client.migrateDatabase(dbDir);\n return {\n output: JSON.stringify(migrateResult, null, 2),\n exitCode: 0,\n };\n }\n\n return { output: 'already up to date', exitCode: 0 };\n } catch (err) {\n return {\n error: `error: migrate failed: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n } finally {\n client.disconnect();\n }\n}\n\nasync function handleDataCommand(\n options: CliOptions,\n deps: CliDeps,\n): Promise<CommandResult> {\n const resolution = resolveDbDir(\n { dbPath: options.dbPath },\n deps.findDb,\n );\n let dbDir = resolution?.path ?? null;\n\n if (!dbDir) {\n const basePath = options.dbPath ?? process.cwd();\n\n if (!deps.isStdinTty()) {\n return {\n error: formatDbNotFound({\n dbPath: options.dbPath,\n }),\n exitCode: 1,\n };\n }\n\n const answer = await deps.promptUser(\n `No .kbdb database found. Create one in ${basePath}? [y/N] `,\n );\n\n if (answer.toLowerCase() !== 'y') {\n return {\n error: 'aborted: no database created',\n exitCode: 1,\n };\n }\n\n const initResult = deps.runInit(options);\n if (!initResult.ok) {\n return {\n error: `error: ${initResult.errorMessage ?? 'init failed'}`,\n exitCode: 1,\n };\n }\n dbDir = initResult.targetPath;\n }\n\n log('db path: ' + dbDir, LogLevel.DEBUG);\n const timeoutMs = resolveTimeoutMs(options);\n const maxRetries = resolveRetryCount(options);\n\n try {\n const { client, result } = await retryOnTimeout(\n () =>\n deps.createWorkerClient({\n contextPath: dbDir,\n requestTimeoutMs: timeoutMs,\n }),\n async (c) => {\n const gateResult = await versionGate(c, dbDir);\n if (gateResult) return gateResult;\n return dispatchCommand(c, options);\n },\n maxRetries,\n );\n client.disconnect();\n return result;\n } catch (err) {\n return {\n error: `error: ${errorToMessage(err)}`,\n exitCode: 1,\n };\n }\n}\n\nasync function handleWorkerLifecycle(\n options: CliOptions,\n deps: CliDeps,\n action: (dbDir: string) => Promise<CommandResult>,\n): Promise<CommandResult> {\n const resolution = resolveDbDir(\n { dbPath: options.dbPath },\n deps.findDb,\n );\n if (!resolution) {\n return {\n error: formatDbNotFound({ dbPath: options.dbPath }),\n exitCode: 1,\n };\n }\n const dbDir = resolution.path;\n return action(dbDir);\n}\n\nasync function versionGate(\n client: DisconnectableClient,\n dbDir: string,\n): Promise<CommandResult | null> {\n const versionStatus = await client.checkVersion(dbDir);\n\n if (versionStatus.status === 'needs_migration') {\n return {\n error:\n 'error: database needs migration' +\n ' -- run `kbdb --migrate`',\n exitCode: 1,\n };\n }\n\n if (versionStatus.status === 'too_new') {\n return {\n error:\n `error: database version` +\n ` ${versionStatus.currentVersion.toString()}` +\n ` is newer than kbdb version` +\n ` ${versionStatus.requiredVersion.toString()}` +\n ` -- upgrade kbdb`,\n exitCode: 1,\n };\n }\n\n return null;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { generateHelp } from '../functions/generate-help.function.ts';\n\n/** Global help text for the kbdb CLI. */\nexport const HELP_TEXT = generateHelp();\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { createInterface } from 'node:readline';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { createToolDefinitions } from '../functions/create-tool-definitions.function.ts';\nimport { createResourceTemplates } from '../functions/create-resource-templates.function.ts';\nimport { handleToolCall } from '../functions/handle-tool-call.function.ts';\nimport { handleResourceRead } from '../functions/handle-resource-read.function.ts';\nimport { createPromptDefinitions } from '../functions/create-prompt-definitions.function.ts';\nimport { handlePromptGet } from '../functions/handle-prompt-get.function.ts';\nimport { handleCompletion } from '../functions/handle-completion.function.ts';\nimport { handleRootsList } from '../functions/handle-roots-list.function.ts';\nimport { shouldEmitLog } from '../functions/should-emit-log.function.ts';\nimport { runAutoCapture } from '../functions/run-auto-capture.function.ts';\nimport { AutoCaptureController } from '../../auto-capture/classes/auto-capture-controller.class.ts';\nimport {\n PARSE_ERROR,\n METHOD_NOT_FOUND,\n RESOURCE_NOT_FOUND,\n} from '../constants/mcp-error-codes.constant.ts';\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type {\n McpRequest,\n McpResponse,\n} from '../typings/mcp-types.interface.ts';\nimport type { McpLogLevel } from '../typings/log-types.interface.ts';\nimport type {\n McpCompletionRef,\n McpCompletionArgument,\n} from '../functions/handle-completion.function.ts';\nimport type { AutoCaptureConfig } from '../../auto-capture/typings/auto-capture-config.interface.ts';\nimport { VERSION } from '../../version/index.ts';\nimport { DEFAULT_RETRY_COUNT } from '../../worker-client/constants/retry-defaults.constant.ts';\n\n/**\n * MCP server that speaks JSON-RPC 2.0 over stdio. Listens for\n * newline-delimited requests on `process.stdin`, dispatches each\n * to the appropriate knowledge-base operation via\n * `McpWorkerClient`, and writes JSON-RPC responses to\n * `process.stdout`.\n */\nexport class McpServer {\n private client: McpWorkerClient;\n private readonly contextPath: string;\n private readonly autoCaptureConfig: AutoCaptureConfig | null;\n private readonly clientFactory:\n | (() => Promise<McpWorkerClient>)\n | null;\n private readonly maxRetries: number;\n private autoCaptureController: AutoCaptureController | null = null;\n private initialized = false;\n private hostCapabilities: Record<string, unknown> | null = null;\n private logLevel: McpLogLevel | null = null;\n private readonly subscriptions = new Set<string>();\n private nextRequestId = 1;\n private readonly pendingRequests = new Map<\n number,\n {\n resolve: (value: unknown) => void;\n reject: (reason: unknown) => void;\n timer: ReturnType<typeof setTimeout>;\n }\n >();\n\n /**\n * @param client - worker client providing knowledge-base operations\n * @param contextPath - absolute path to the `.kbdb` directory\n * @param autoCaptureConfig - optional auto-capture configuration;\n * when provided the server activates auto-capture on connection\n * @param clientFactory - creates a fresh worker client (for retry)\n * @param maxRetries - max retries on REQUEST_TIMEOUT\n */\n constructor(\n client: McpWorkerClient,\n contextPath?: string,\n autoCaptureConfig?: AutoCaptureConfig,\n clientFactory?: (() => Promise<McpWorkerClient>) | null,\n maxRetries?: number,\n ) {\n this.client = client;\n this.contextPath = contextPath ?? '';\n this.autoCaptureConfig = autoCaptureConfig ?? null;\n this.clientFactory = clientFactory ?? null;\n this.maxRetries = maxRetries ?? DEFAULT_RETRY_COUNT;\n }\n\n private async reconnectClient(): Promise<void> {\n if (!this.clientFactory) {\n log('no client factory for reconnect', LogLevel.ERROR);\n throw new Error('no client factory for reconnect');\n }\n this.client.disconnect();\n this.client = await this.clientFactory();\n log('MCP client reconnected', LogLevel.DEBUG);\n }\n\n private async withRetry<T>(fn: () => Promise<T>): Promise<T> {\n for (let attempt = 0; ; attempt++) {\n try {\n return await fn();\n } catch (err: unknown) {\n const code = (err as Record<string, unknown>).code;\n if (\n code !== 'REQUEST_TIMEOUT' ||\n attempt >= this.maxRetries ||\n !this.clientFactory\n ) {\n throw err;\n }\n log(\n 'request timeout, reconnecting (attempt ' +\n (attempt + 1).toString() +\n '/' +\n this.maxRetries.toString() +\n ')',\n LogLevel.WARNING,\n );\n await this.reconnectClient();\n }\n }\n }\n\n async listen(): Promise<void> {\n const rl = createInterface({\n input: process.stdin,\n terminal: false,\n });\n log('MCP server listening on stdin', LogLevel.DEBUG);\n\n let pending = Promise.resolve();\n await new Promise<void>((resolve) => {\n rl.on('line', (line) => {\n pending = pending.then(() => this.dispatchLine(line));\n });\n\n rl.on('close', () => {\n void pending.then(() => {\n this.autoCaptureController?.reset();\n this.autoCaptureController = null;\n this.client.disconnect();\n log('MCP stdin closed', LogLevel.DEBUG);\n resolve();\n });\n });\n });\n }\n\n async handleLineForTest(line: string): Promise<McpResponse | null> {\n return this.processLine(line);\n }\n\n /**\n * Sends a JSON-RPC notification (no `id`, no response\n * expected) to stdout.\n */\n notify(method: string, params?: Record<string, unknown>): void {\n const notification: Record<string, unknown> = {\n jsonrpc: '2.0',\n method,\n };\n if (params !== undefined) {\n notification['params'] = params;\n }\n process.stdout.write(JSON.stringify(notification) + '\\n');\n }\n\n /**\n * Emits a log notification if the message severity meets or\n * exceeds the configured log level threshold.\n */\n log(level: McpLogLevel, message: unknown, logger?: string): void {\n if (this.logLevel === null) return;\n if (!shouldEmitLog(level, this.logLevel)) return;\n this.notify('notifications/message', {\n level,\n logger: logger ?? 'kbdb',\n data: message,\n });\n }\n\n /**\n * Sends a JSON-RPC request to the host (server-to-client)\n * and returns a Promise that resolves with the response\n * result. Times out after 30 seconds.\n */\n sendRequest(\n method: string,\n params: Record<string, unknown>,\n ): Promise<unknown> {\n const id = this.nextRequestId++;\n const request = { jsonrpc: '2.0', id, method, params };\n process.stdout.write(JSON.stringify(request) + '\\n');\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => {\n this.pendingRequests.delete(id);\n reject(new Error(`Request ${method} timed out`));\n }, 30000);\n this.pendingRequests.set(id, {\n resolve,\n reject,\n timer,\n });\n });\n }\n\n /**\n * Requests the host to generate text via the sampling\n * capability. Throws if the host did not advertise sampling\n * support during initialization.\n */\n async requestSampling(\n messages: {\n role: string;\n content: { type: string; text: string };\n }[],\n maxTokens: number,\n ): Promise<unknown> {\n if (!this.hostCapabilities?.['sampling']) {\n log('Host does not support sampling', LogLevel.ERROR);\n throw new Error('Host does not support sampling');\n }\n return this.sendRequest('sampling/createMessage', {\n messages,\n maxTokens,\n });\n }\n\n private async dispatchLine(line: string): Promise<void> {\n const response = await this.processLine(line);\n if (response !== null) {\n this.send(response);\n }\n }\n\n private async processLine(\n line: string,\n ): Promise<McpResponse | null> {\n if (!line.trim()) return null;\n\n let parsed: Record<string, unknown>;\n try {\n parsed = JSON.parse(line) as Record<string, unknown>;\n } catch {\n return {\n jsonrpc: '2.0',\n id: 0,\n error: {\n code: PARSE_ERROR,\n message: 'Parse error',\n },\n };\n }\n\n // Incoming response to an outgoing request (sampling)\n if (\n parsed['id'] !== undefined &&\n typeof parsed['method'] !== 'string'\n ) {\n const responseId = parsed['id'] as number;\n const pending = this.pendingRequests.get(responseId);\n if (pending) {\n this.pendingRequests.delete(responseId);\n clearTimeout(pending.timer);\n if (parsed['error']) {\n const err = parsed['error'] as {\n message?: string;\n };\n pending.reject(\n new Error(err.message ?? 'Request failed'),\n );\n } else {\n pending.resolve(parsed['result']);\n }\n }\n return null;\n }\n\n const request = parsed as unknown as McpRequest;\n log('MCP request: ' + request.method, LogLevel.DEBUG);\n\n if (request.id === undefined) {\n if (\n request.method === 'notifications/initialized' ||\n request.method === 'notifications/cancelled'\n ) {\n if (\n request.method === 'notifications/initialized' &&\n !this.initialized\n ) {\n this.initialized = true;\n log('MCP initialized', LogLevel.INFO);\n if (this.autoCaptureConfig !== null) {\n this.autoCaptureController =\n new AutoCaptureController(this.autoCaptureConfig);\n }\n void this.runStartupHealthCheck();\n }\n }\n return null;\n }\n\n const id = request.id;\n\n if (\n !this.initialized &&\n request.method !== 'initialize' &&\n request.method !== 'ping'\n ) {\n return {\n jsonrpc: '2.0',\n id,\n error: {\n code: RESOURCE_NOT_FOUND,\n message: 'Server not initialized',\n },\n };\n }\n\n const response = await this.handleRequest(request);\n return response;\n }\n\n private async handleRequest(\n request: McpRequest,\n ): Promise<McpResponse> {\n const id = request.id as number | string;\n\n switch (request.method) {\n case 'initialize': {\n const params = request.params ?? {};\n const caps = params['capabilities'];\n this.hostCapabilities = caps\n ? (caps as Record<string, unknown>)\n : null;\n return {\n jsonrpc: '2.0',\n id,\n result: {\n protocolVersion: '2025-11-25',\n serverInfo: {\n name: 'kbdb',\n version: VERSION,\n },\n capabilities: {\n tools: {},\n resources: { subscribe: true },\n prompts: {},\n logging: {},\n completions: {},\n },\n },\n };\n }\n\n case 'ping':\n return { jsonrpc: '2.0', id, result: {} };\n\n case 'tools/list':\n return {\n jsonrpc: '2.0',\n id,\n result: {\n tools: createToolDefinitions(),\n },\n };\n\n case 'resources/list':\n return {\n jsonrpc: '2.0',\n id,\n result: { resources: [] },\n };\n\n case 'resources/templates/list':\n return {\n jsonrpc: '2.0',\n id,\n result: {\n resourceTemplates: createResourceTemplates(),\n },\n };\n\n case 'tools/call': {\n const params = request.params ?? {};\n const rawName = params['name'];\n const name = typeof rawName === 'string' ? rawName : '';\n const args = (params['arguments'] ?? {}) as Record<\n string,\n unknown\n >;\n const result = await this.withRetry(() =>\n handleToolCall(this.client, name, args),\n );\n this.afterToolCall();\n return { jsonrpc: '2.0', id, result };\n }\n\n case 'resources/read': {\n const params = request.params ?? {};\n const rawUri = params['uri'];\n const uri = typeof rawUri === 'string' ? rawUri : '';\n try {\n const result = await this.withRetry(() =>\n handleResourceRead(this.client, uri),\n );\n return { jsonrpc: '2.0', id, result };\n } catch (err) {\n return {\n jsonrpc: '2.0',\n id,\n error: {\n code: RESOURCE_NOT_FOUND,\n message:\n err instanceof Error\n ? err.message\n : String(err),\n },\n };\n }\n }\n\n case 'prompts/list': {\n const skills = await this.client.listByType('skill');\n const agents =\n await this.client.listDocumentsByType('agent');\n const prompts = createPromptDefinitions(skills, agents);\n return {\n jsonrpc: '2.0',\n id,\n result: { prompts },\n };\n }\n\n case 'prompts/get': {\n const params = request.params ?? {};\n const name =\n typeof params['name'] === 'string' ? params['name'] : '';\n const promptArgs = (params['arguments'] ?? {}) as Record<\n string,\n string\n >;\n try {\n const messages = await handlePromptGet(\n name,\n promptArgs,\n this.client,\n );\n return {\n jsonrpc: '2.0',\n id,\n result: { messages },\n };\n } catch (err) {\n return {\n jsonrpc: '2.0',\n id,\n error: {\n code: RESOURCE_NOT_FOUND,\n message:\n err instanceof Error\n ? err.message\n : String(err),\n },\n };\n }\n }\n\n case 'completion/complete': {\n const params = request.params ?? {};\n const ref = params['ref'] as McpCompletionRef;\n const argument = (params['argument'] ?? {\n name: '',\n value: '',\n }) as McpCompletionArgument;\n const result = await handleCompletion(\n ref,\n argument,\n this.client,\n );\n return { jsonrpc: '2.0', id, result };\n }\n\n case 'roots/list': {\n const roots = handleRootsList(this.contextPath);\n return {\n jsonrpc: '2.0',\n id,\n result: { roots },\n };\n }\n\n case 'logging/setLevel': {\n const params = request.params ?? {};\n const level = params['level'] as McpLogLevel | undefined;\n this.logLevel = level ?? null;\n return { jsonrpc: '2.0', id, result: {} };\n }\n\n case 'resources/subscribe': {\n const params = request.params ?? {};\n const uri =\n typeof params['uri'] === 'string' ? params['uri'] : '';\n this.subscriptions.add(uri);\n return { jsonrpc: '2.0', id, result: {} };\n }\n\n case 'resources/unsubscribe': {\n const params = request.params ?? {};\n const uri =\n typeof params['uri'] === 'string' ? params['uri'] : '';\n this.subscriptions.delete(uri);\n return { jsonrpc: '2.0', id, result: {} };\n }\n\n default:\n return {\n jsonrpc: '2.0',\n id,\n error: {\n code: METHOD_NOT_FOUND,\n message: `Method not found: ` + request.method,\n },\n };\n }\n }\n\n private send(response: McpResponse): void {\n const json = JSON.stringify(response);\n process.stdout.write(json + '\\n');\n }\n\n /**\n * Records a tool call in the auto-capture controller and fires\n * a capture when the trigger condition is met.\n */\n private afterToolCall(): void {\n const ctrl = this.autoCaptureController;\n const cfg = this.autoCaptureConfig;\n if (ctrl === null || cfg === null) return;\n ctrl.recordToolCall();\n void runAutoCapture(\n ctrl,\n cfg,\n this.client,\n this.hostCapabilities,\n (messages, maxTokens) =>\n this.requestSampling(messages, maxTokens),\n );\n }\n\n /**\n * Runs an integrity check immediately after the MCP handshake\n * completes. Emits a `notifications/message` warning when the\n * check detects issues so the connected agent is aware before\n * making requests. The server continues operating regardless of\n * the result.\n */\n private async runStartupHealthCheck(): Promise<void> {\n try {\n const report = await this.client.integrityCheck();\n if (!report.ok) {\n const summary = report.errors\n .map((e) => `${e.type}: ${e.entity} -- ${e.detail}`)\n .join('; ');\n this.notify('notifications/message', {\n level: 'warning',\n logger: 'kbdb',\n data: `Database integrity issues detected: ${summary}`,\n });\n }\n } catch {\n // Health check failure is non-fatal -- server continues\n }\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpToolDefinition } from '../typings/mcp-types.interface.ts';\n\n/**\n * Returns the full list of MCP tool definitions exposed by the\n * knowledge-base server. Each definition includes the tool name,\n * a human-readable description, and a JSON Schema for its inputs.\n */\nexport function createToolDefinitions(): McpToolDefinition[] {\n return [\n {\n name: 'search',\n description:\n 'Query the knowledge base by keywords.' +\n ' Returns ranked results with heading,' +\n ' snippet, and matched terms. Use multiple' +\n ' short keyword queries for best coverage.' +\n ' Use recall to get full content.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Search query text',\n },\n mode: {\n type: 'string',\n enum: ['sections', 'documents', 'stats'],\n description: 'Search mode (default: sections)',\n },\n limit: {\n type: 'number',\n description: 'Maximum results (default: 20)',\n },\n offset: {\n type: 'number',\n description:\n 'Number of results to skip for' +\n ' pagination (default: 0)',\n },\n algo: {\n type: 'string',\n enum: ['lexical', 'vector', 'hybrid'],\n description: 'Search algorithm (default: lexical)',\n },\n relaxed: {\n type: 'boolean',\n description:\n 'Use relaxed (OR) matching when the' +\n ' strict query returns no results',\n },\n },\n required: ['query'],\n },\n annotations: {\n title: 'Search KB',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'learn',\n description:\n 'Import content into the knowledge base.' +\n ' Use for durable facts, decisions, and' +\n ' corrections. Use replace when updating' +\n ' existing knowledge. Attach tags for scoping.',\n inputSchema: {\n type: 'object',\n properties: {\n content: {\n type: 'string',\n description:\n 'Raw text or Markdown content to' +\n ' index. Do not wrap in JSON.',\n },\n type: {\n type: 'string',\n description:\n 'MIME type (default: text/markdown).' +\n ' Use image/* for images.',\n },\n title: {\n type: 'string',\n description:\n 'Section title.' + ' Required for image/* types.',\n },\n description: {\n type: 'string',\n description: 'Optional section description',\n },\n docid: {\n type: 'string',\n description: 'Document ID to group under',\n },\n tags: {\n type: 'array',\n items: { type: 'string' },\n description: 'Tags for scoping and filtering',\n },\n replace: {\n type: 'boolean',\n description:\n 'Replace existing section with same' +\n ' source key (supersession)',\n },\n },\n required: ['content'],\n },\n annotations: {\n title: 'Import Content',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'unlearn',\n description:\n 'Remove a section from the knowledge base' +\n ' by its kb-id.',\n inputSchema: {\n type: 'object',\n properties: {\n kbid: {\n type: 'string',\n description: 'Knowledge base ID of the section',\n },\n },\n required: ['kbid'],\n },\n annotations: {\n title: 'Remove Section',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'retrieve',\n description:\n 'Low-level fetch of a section or document' +\n ' by identifier. For AI agent workflows,' +\n ' prefer `recall` which includes metadata,' +\n ' context, and back-references.',\n inputSchema: {\n type: 'object',\n properties: {\n kbid: {\n type: 'string',\n description: 'Section kb-id',\n },\n docid: {\n type: 'string',\n description: 'Document ID',\n },\n },\n },\n annotations: {\n title: 'Fetch Content',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'recall',\n description:\n 'Retrieve full content and context for sections' +\n ' by identifier. Use after search to read relevant' +\n ' results. Returns section text, metadata,' +\n ' references, and back-references.',\n inputSchema: {\n type: 'object',\n properties: {\n kbid: {\n type: 'string',\n description: 'Single section identifier',\n },\n kbids: {\n type: 'array',\n items: { type: 'string' },\n description: 'Batch section identifiers',\n },\n depth: {\n type: 'number',\n description: 'Expansion depth (0-3, default: 0)',\n },\n },\n },\n annotations: {\n title: 'Recall Context',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'status',\n description:\n 'Get database metadata including document count,' +\n ' section count, index size, and cache statistics.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'DB Status',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'content',\n description:\n 'Compose a rendered Markdown document from one or' +\n ' more kbid or docid identifiers.',\n inputSchema: {\n type: 'object',\n properties: {\n ids: {\n type: 'array',\n items: { type: 'string' },\n description:\n 'One or more kbid or docid identifiers' +\n ' (may be mixed)',\n },\n },\n required: ['ids'],\n },\n annotations: {\n title: 'Compose Content',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'check',\n description:\n 'Verify the integrity of the knowledge base.' +\n ' Reports checksum mismatches, orphan sections,' +\n ' broken references, and circular reference chains.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'Integrity Check',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'gc',\n description:\n 'Remove unreferenced sections from the knowledge' +\n ' base. A section is eligible when no document' +\n ' manifest references it.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'Garbage Collect',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n {\n name: 'rebuild',\n description:\n 'Reconstruct all index files from section files' +\n ' and document manifests on disk. Use this to' +\n ' recover from index corruption.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'Rebuild Indexes',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: false,\n openWorldHint: false,\n },\n },\n {\n name: 'export',\n description:\n 'Export the database as a self-contained' +\n ' directory snapshot (sections, documents,' +\n ' catalog -- no indexes).',\n inputSchema: {\n type: 'object',\n properties: {\n path: {\n type: 'string',\n description:\n 'Export destination path' +\n ' (default: ./kbdb-export/)',\n },\n },\n },\n annotations: {\n title: 'Export Snapshot',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'skill-learn',\n description:\n 'Create or update a skill definition.' +\n ' Skills are reusable AI agent capabilities' +\n ' with template placeholders.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Skill name',\n },\n description: {\n type: 'string',\n description: 'Skill description',\n },\n body: {\n type: 'string',\n description:\n 'Skill body template as raw text.' +\n ' Use {{argName}} for placeholders.' +\n ' Do not wrap in JSON.',\n },\n },\n required: ['name', 'body'],\n },\n annotations: {\n title: 'Create Skill',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'skill-list',\n description: 'List all skills in the knowledge base.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'List Skills',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'skill-get',\n description: 'Get a skill definition by name or kbid.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Skill name',\n },\n kbid: {\n type: 'string',\n description: 'Knowledge base ID',\n },\n },\n },\n annotations: {\n title: 'Get Skill',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'skill-delete',\n description: 'Delete a skill by its kbid.',\n inputSchema: {\n type: 'object',\n properties: {\n kbid: {\n type: 'string',\n description: 'Knowledge base ID',\n },\n },\n required: ['kbid'],\n },\n annotations: {\n title: 'Delete Skill',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'agent-create',\n description:\n 'Create an AI agent with a persona and' +\n ' optional skill references.',\n inputSchema: {\n type: 'object',\n properties: {\n name: {\n type: 'string',\n description: 'Agent name',\n },\n description: {\n type: 'string',\n description: 'Agent description',\n },\n persona: {\n type: 'string',\n description:\n 'Agent persona as raw text.' +\n ' Do not wrap in JSON.',\n },\n skills: {\n type: 'array',\n items: { type: 'string' },\n description: 'Skill kbid references to attach',\n },\n },\n required: ['name', 'persona'],\n },\n annotations: {\n title: 'Create Agent',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'agent-list',\n description: 'List all agents in the knowledge base.',\n inputSchema: {\n type: 'object',\n properties: {},\n },\n annotations: {\n title: 'List Agents',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'agent-get',\n description: 'Get an agent definition by document ID.',\n inputSchema: {\n type: 'object',\n properties: {\n docid: {\n type: 'string',\n description: 'Document ID of the agent',\n },\n },\n required: ['docid'],\n },\n annotations: {\n title: 'Get Agent',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'agent-delete',\n description:\n 'Delete an agent by its document ID.' +\n ' Skill sections are not removed.',\n inputSchema: {\n type: 'object',\n properties: {\n docid: {\n type: 'string',\n description: 'Document ID of the agent',\n },\n },\n required: ['docid'],\n },\n annotations: {\n title: 'Delete Agent',\n readOnlyHint: false,\n destructiveHint: true,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'skill-search',\n description:\n 'Search for skills by keyword.' +\n ' Returns ranked skill definitions' +\n ' matching the query.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Search query text',\n },\n limit: {\n type: 'number',\n description: 'Maximum results (default: 20)',\n },\n },\n required: ['query'],\n },\n annotations: {\n title: 'Search Skills',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'agent-search',\n description:\n 'Search for agents by keyword.' +\n ' Returns ranked agent profiles' +\n ' matching the query.',\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Search query text',\n },\n limit: {\n type: 'number',\n description: 'Maximum results (default: 20)',\n },\n },\n required: ['query'],\n },\n annotations: {\n title: 'Search Agents',\n readOnlyHint: true,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n {\n name: 'auto-capture-review',\n description:\n 'Review and approve pending auto-captured' +\n ' knowledge before storage.',\n inputSchema: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['list', 'approve', 'reject'],\n description: 'Action to perform on pending captures',\n },\n },\n },\n annotations: {\n title: 'Auto-Capture Review',\n readOnlyHint: false,\n destructiveHint: false,\n idempotentHint: true,\n openWorldHint: false,\n },\n },\n ];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpResourceTemplate } from '../typings/mcp-types.interface.ts';\n\n/**\n * Returns the list of MCP resource URI templates served by the\n * knowledge-base server. Each template describes the URI pattern,\n * human-readable metadata, and the MIME type of the resource body.\n */\nexport function createResourceTemplates(): McpResourceTemplate[] {\n return [\n {\n uriTemplate: 'kbdb://section/{kb_id}',\n name: 'Section',\n description: 'A knowledge base section by its kb-id.',\n mimeType: 'text/plain',\n },\n {\n uriTemplate: 'kbdb://document/{doc_id}',\n name: 'Document',\n description: 'A document with its ordered sections.',\n mimeType: 'application/json',\n },\n ];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/** A single search result item, as needed for text formatting. */\ninterface FormattableSearchItem {\n readonly kbid: string;\n readonly heading: string | null;\n readonly type: string;\n readonly snippet: string;\n readonly matched_terms: readonly string[];\n}\n\n/** A page of search results, as needed for text formatting. */\ninterface FormattableSearchPage {\n readonly items: readonly FormattableSearchItem[];\n readonly total: number;\n readonly offset: number;\n readonly limit?: number;\n readonly has_more?: boolean;\n}\n\n/**\n * Formats a search results page as human-readable text for an MCP\n * `text` content block.\n *\n * @param query - the original query string, echoed in the summary\n * @param results - the search results page to format\n */\nexport function formatSearchResults(\n query: string,\n results: FormattableSearchPage,\n): string {\n if (results.items.length === 0) {\n return `No results found for \"${query}\"`;\n }\n const lines = results.items.map((item, index) =>\n formatItem(item, results.offset + index + 1),\n );\n const start = results.offset + 1;\n const end = results.offset + results.items.length;\n const total = String(results.total);\n return [\n `Found ${total} results for \"${query}\"`,\n '',\n ...lines,\n '',\n `Showing ${String(start)}-${String(end)} of ${total} results`,\n ].join('\\n');\n}\n\n/** Formats a single result item as a numbered text entry. */\nfunction formatItem(\n item: FormattableSearchItem,\n position: number,\n): string {\n const heading = item.heading ?? '(untitled)';\n const terms = item.matched_terms.join(', ');\n return (\n `${String(position)}. [${item.kbid}] ${heading}\\n` +\n ` ${item.snippet}\\n` +\n ` type: ${item.type} terms: ${terms}`\n );\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically `'text'`. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by the agent-create tool handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/**\n * Narrows an `unknown` value to a string, returning the fallback\n * when the value is not already a string.\n */\nfunction asString(value: unknown, fallback: string): string {\n return typeof value === 'string' ? value : fallback;\n}\n\n/**\n * Narrows an `unknown` value to a `string[]`, returning an empty\n * array when the value is not an array of strings.\n */\nfunction asStringArray(value: unknown): string[] {\n if (\n Array.isArray(value) &&\n value.every((item) => typeof item === 'string')\n ) {\n return value;\n }\n return [];\n}\n\n/**\n * Handles the `agent:create` MCP tool call.\n *\n * Validates required arguments, verifies that referenced skill kbids\n * exist, stores agent metadata as a JSON section, groups all sections\n * into a single document, and returns the resulting document\n * identifier.\n *\n * @param client - the worker client used to execute operations\n * @param args - tool arguments from the MCP request\n * @returns content items with optional `isError` flag\n */\nexport async function handleAgentCreate(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const name = asString(args['name'], '');\n const description = asString(args['description'], '');\n const persona = asString(args['persona'], '');\n const skills = asStringArray(args['skills']);\n\n if (!name) {\n return {\n content: [{ type: 'text', text: 'name is required' }],\n isError: true,\n };\n }\n if (!persona) {\n return {\n content: [{ type: 'text', text: 'persona is required' }],\n isError: true,\n };\n }\n\n if (skills.length > 0) {\n const sections = await client.readSections(skills);\n const found = new Set(sections.map((s) => s.kbid));\n const missing = skills.filter((k) => !found.has(k));\n if (missing.length > 0) {\n return {\n content: [\n {\n type: 'text',\n text: `skill not found: ${missing.join(', ')}`,\n },\n ],\n isError: true,\n };\n }\n }\n\n const metadata = JSON.stringify({ name, description, persona });\n\n const metaResult = await client.addSection({\n sectionType: 'text',\n content: metadata,\n title: name,\n description,\n });\n\n const allKbids = [metaResult.items[0], ...skills];\n const docid = await client.groupSections(name, allKbids, 'agent');\n\n return {\n content: [\n {\n type: 'text',\n text:\n `Created agent \"${name}\" (docid: ${docid})\\n` +\n `Skills: ${String(skills.length)} attached`,\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically `'text'`. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by the agent-list tool handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/**\n * Reads the `description` field from an agent's metadata section,\n * which is always the first section of an agent document.\n *\n * @param client - the worker client used to read sections\n * @param sections - the agent document's ordered section list\n * @returns the description, or `''` when absent or unparseable\n */\nasync function readAgentDescription(\n client: McpWorkerClient,\n sections: readonly { readonly kbid: string }[],\n): Promise<string> {\n const metaKbid = sections[0]?.kbid;\n if (!metaKbid) return '';\n const metaSections = await client.readSections([metaKbid]);\n const first = metaSections.at(0);\n if (!first) return '';\n try {\n const meta = JSON.parse(first.content) as Record<string, unknown>;\n return typeof meta['description'] === 'string'\n ? meta['description']\n : '';\n } catch {\n return '';\n }\n}\n\n/**\n * Handles the `agent:list` MCP tool call.\n *\n * Retrieves all documents with `doc_type: 'agent'` and returns a\n * numbered, human-readable list of each agent's name and\n * description.\n *\n * @param client - the worker client used to execute operations\n * @returns content items with the formatted agent list\n */\nexport async function handleAgentList(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const docs = await client.listDocumentsByType('agent');\n const items = await Promise.all(\n docs.map(async (d) => ({\n name: d.title,\n description: await readAgentDescription(client, d.sections),\n })),\n );\n const lines = items.map(\n (item, index) =>\n `${String(index + 1)}. ${item.name}` +\n (item.description ? ` -- ${item.description}` : ''),\n );\n const text = [`${String(items.length)} agents:`, ...lines].join(\n '\\n',\n );\n return {\n content: [\n {\n type: 'text',\n text,\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type { AgentDefinition } from '../typings/agent-types.interface.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically `'text'`. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by the agent-get tool handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/** Parsed shape of an agent document section list entry. */\ninterface DocumentSection {\n /** Knowledge-base identifier of the section. */\n readonly kbid: string;\n /** Zero-based position of the section within the document. */\n readonly position: number;\n}\n\n/** Parsed shape of a retrieved agent document. */\ninterface AgentDocument {\n /** Document identifier. */\n readonly docid: string;\n /** Document title used as agent name fallback. */\n readonly title: string;\n /** Ordered list of sections in the document. */\n readonly sections: DocumentSection[];\n}\n\n/**\n * Reads the metadata JSON stored in the first section of an agent\n * document and extracts `name`, `description`, and `persona`.\n */\nasync function readAgentMeta(\n client: McpWorkerClient,\n metaKbid: string,\n fallbackName: string,\n): Promise<{ name: string; description: string; persona: string }> {\n const metaSections = await client.readSections([metaKbid]);\n const first = metaSections.at(0);\n if (!first) {\n return { name: fallbackName, description: '', persona: '' };\n }\n try {\n const meta = JSON.parse(first.content) as Record<string, unknown>;\n return {\n name:\n typeof meta['name'] === 'string'\n ? meta['name']\n : fallbackName,\n description:\n typeof meta['description'] === 'string'\n ? meta['description']\n : '',\n persona:\n typeof meta['persona'] === 'string' ? meta['persona'] : '',\n };\n } catch {\n return { name: fallbackName, description: '', persona: '' };\n }\n}\n\n/**\n * Resolves skill names for a list of section references by reading\n * each section's JSON content and extracting the `name` field.\n * Returns `null` for skill references where the section no longer\n * exists (dangling references).\n */\nasync function resolveSkillRefs(\n client: McpWorkerClient,\n skillRefs: DocumentSection[],\n): Promise<{ kbid: string; name: string | null; position: number }[]> {\n if (skillRefs.length === 0) {\n return [];\n }\n const skillKbids = skillRefs.map((s) => s.kbid);\n const skillSections = await client.readSections(skillKbids);\n const sectionMap = new Map(skillSections.map((s) => [s.kbid, s]));\n return skillRefs.map((ref) => {\n const sec = sectionMap.get(ref.kbid);\n if (!sec) {\n return { kbid: ref.kbid, name: null, position: ref.position };\n }\n try {\n const parsed = JSON.parse(sec.content) as Record<\n string,\n unknown\n >;\n const skillName =\n typeof parsed['name'] === 'string' ? parsed['name'] : null;\n return {\n kbid: ref.kbid,\n name: skillName,\n position: ref.position,\n };\n } catch {\n return { kbid: ref.kbid, name: null, position: ref.position };\n }\n });\n}\n\n/**\n * Formats an `AgentDefinition` as human-readable text, listing the\n * agent's name, description, persona, and numbered skills. Dangling\n * skill references (sections that no longer exist) are shown with a\n * `(missing)` marker.\n */\nfunction formatAgent(agent: AgentDefinition): string {\n const skillLines =\n agent.skills.length > 0\n ? agent.skills\n .map(\n (s, index) =>\n `${String(index + 1)}. ${\n s.name ?? `(missing: ${s.kbid})`\n }`,\n )\n .join('\\n')\n : 'none';\n return [\n `Agent: ${agent.name} (docid: ${agent.docid})`,\n `Description: ${agent.description}`,\n `Persona: ${agent.persona}`,\n '',\n 'Skills:',\n skillLines,\n ].join('\\n');\n}\n\n/**\n * Handles the `agent:get` MCP tool call.\n *\n * Retrieves an agent document by its `docid`, reads the metadata\n * section and skill references, and returns the agent's definition\n * as human-readable text. Dangling skill references (sections that\n * no longer exist) are marked as missing in the skills list.\n *\n * @param client - the worker client used to execute operations\n * @param args - tool arguments; must include a `docid` string\n * @returns content items containing the formatted agent definition\n */\nexport async function handleAgentGet(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const docid = typeof args['docid'] === 'string' ? args['docid'] : '';\n if (!docid) {\n return {\n content: [{ type: 'text', text: 'docid is required' }],\n isError: true,\n };\n }\n\n const doc = (await client.retrieveDocument(docid)) as AgentDocument;\n const metaKbid = doc.sections[0]?.kbid;\n const skillRefs = doc.sections.slice(1);\n\n const { name, description, persona } = metaKbid\n ? await readAgentMeta(client, metaKbid, doc.title)\n : { name: doc.title, description: '', persona: '' };\n\n const skills = await resolveSkillRefs(client, skillRefs);\n\n const agent: AgentDefinition = {\n docid,\n name,\n description,\n persona,\n skills,\n };\n\n return {\n content: [\n {\n type: 'text',\n text: formatAgent(agent),\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically `'text'`. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by the agent-delete tool handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/**\n * Handles the `agent:delete` MCP tool call.\n *\n * Removes the document grouping identified by `docid`. The skill\n * sections referenced by the agent are not deleted; only the grouping\n * record is removed.\n *\n * @param client - the worker client used to execute operations\n * @param args - tool arguments; must include a `docid` string\n * @returns content items confirming removal, or an error item\n */\nexport async function handleAgentDelete(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const docid = typeof args['docid'] === 'string' ? args['docid'] : '';\n if (!docid) {\n return {\n content: [{ type: 'text', text: 'docid is required' }],\n isError: true,\n };\n }\n await client.removeGrouping(docid);\n return {\n content: [\n {\n type: 'text',\n text: `Deleted agent (docid: ${docid})`,\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically `'text'`. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by a tool call handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/** Narrows an unknown value to a plain record, or `undefined`. */\nfunction asRecord(value: unknown): Record<string, unknown> | undefined {\n return typeof value === 'object' && value !== null\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\n/** Reads a string field from a record, or returns `fallback`. */\nfunction strField(\n record: Record<string, unknown>,\n key: string,\n fallback: string,\n): string {\n const value = record[key];\n return typeof value === 'string' ? value : fallback;\n}\n\n/** Formats a labelled bullet list from a record's array field. */\nfunction formatList(\n label: string,\n items: unknown,\n line: (item: Record<string, unknown>) => string,\n): string {\n if (items === undefined || items === null) {\n return '';\n }\n const list = Array.isArray(items) ? items : [];\n const rows = list\n .map((raw) => asRecord(raw))\n .filter((r): r is Record<string, unknown> => r !== undefined)\n .map((r) => ` - ${line(r)}`);\n if (rows.length > 0) {\n return `\\n\\n${label}:\\n${rows.join('\\n')}`;\n }\n return `\\n\\n${label}: (none)`;\n}\n\n/** Formats a single recall result as human-readable text. */\nfunction formatRecallItem(raw: unknown): string {\n const item = asRecord(raw) ?? {};\n const kbid = strField(item, 'kbid', '?');\n const heading = strField(item, 'heading', '(untitled)');\n const type = strField(item, 'type', 'unknown');\n const content = strField(item, 'content', '');\n const refLine = (r: Record<string, unknown>): string =>\n `${strField(r, 'heading', strField(r, 'kbid', '?'))} (${strField(r, 'kbid', '?')})`;\n const text =\n `${heading} [${type}] (${kbid})\\n\\n${content}` +\n formatList(\n 'Documents',\n item['documents'],\n (d) =>\n `${strField(d, 'title', '?')} (${strField(d, 'docid', '?')})`,\n ) +\n formatList('Back references', item['back_references'], refLine) +\n formatList('Siblings', item['siblings'], refLine) +\n formatList('References', item['references'], refLine);\n return text;\n}\n\n/** Builds a placeholder recall result for a missing section. */\nfunction buildNotFoundResult(\n id: string,\n depth: number,\n): Record<string, unknown> {\n const base: Record<string, unknown> = {\n kbid: id,\n heading: '(not found)',\n type: 'unknown',\n content: '',\n docids: [],\n };\n if (depth >= 1) {\n base['documents'] = [];\n base['back_references'] = [];\n }\n if (depth >= 2) {\n base['siblings'] = [];\n base['references'] = [];\n }\n return base;\n}\n\n/**\n * Handles the MCP `recall` tool call.\n *\n * Retrieves full content and context for one or more knowledge-base\n * sections by identifier. At least one of `kbid` or `kbids` must be\n * present in `args`; omitting both returns an error result.\n *\n * @param client - the worker client used to execute the operation\n * @param args - tool arguments from the MCP request\n * @returns content with human-readable recall text, or an error\n * content item when required arguments are missing\n */\nexport async function handleRecall(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const kbid =\n typeof args['kbid'] === 'string' ? args['kbid'] : undefined;\n const kbids =\n Array.isArray(args['kbids']) &&\n args['kbids'].every((item: unknown) => typeof item === 'string')\n ? args['kbids']\n : undefined;\n\n if (!kbid && (!kbids || kbids.length === 0)) {\n return {\n content: [\n {\n type: 'text',\n text: 'Provide kbid or kbids',\n },\n ],\n isError: true,\n };\n }\n\n const depth = typeof args['depth'] === 'number' ? args['depth'] : 0;\n\n let result: unknown;\n try {\n result = await client.recall({ kbid, kbids, depth });\n } catch {\n const ids = kbid ? [kbid] : (kbids ?? []);\n const items = ids.map((id) => buildNotFoundResult(id, depth));\n result = items.length === 1 ? items[0] : items;\n }\n const text = Array.isArray(result)\n ? result.map(formatRecallItem).join('\\n\\n---\\n\\n')\n : formatRecallItem(result);\n\n return {\n content: [\n {\n type: 'text',\n text,\n },\n ],\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type { ToolCallResult } from '../typings/tool-call-result.model.ts';\nimport { formatSearchResults } from './format-search-results.function.ts';\n\n/**\n * Handles the `skill-search` MCP tool call.\n *\n * Performs a search then filters to skill-type results.\n *\n * @param args - tool arguments from the MCP request\n * @param client - the worker client\n */\nexport async function handleSkillSearch(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const query = typeof args['query'] === 'string' ? args['query'] : '';\n const results = await client.search({\n query,\n limit: args['limit'] as number | undefined,\n });\n\n const filtered = {\n ...results,\n items: results.items.filter(\n (item: { type: string }) => item.type === 'skill',\n ),\n total: 0,\n };\n filtered.total = filtered.items.length;\n\n const text = formatSearchResults(query, filtered);\n return { content: [{ type: 'text', text }] };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type { ToolCallResult } from '../typings/tool-call-result.model.ts';\nimport { formatSearchResults } from './format-search-results.function.ts';\n\n/**\n * Handles the `agent-search` MCP tool call.\n *\n * Performs a search then filters to agent-type results.\n *\n * @param args - tool arguments from the MCP request\n * @param client - the worker client\n */\nexport async function handleAgentSearch(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const query = typeof args['query'] === 'string' ? args['query'] : '';\n const results = await client.search({\n query,\n limit: args['limit'] as number | undefined,\n });\n\n const filtered = {\n ...results,\n items: results.items.filter(\n (item: { type: string }) => item.type === 'agent',\n ),\n total: 0,\n };\n filtered.total = filtered.items.length;\n\n const text = formatSearchResults(query, filtered);\n return { content: [{ type: 'text', text }] };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type { SkillDefinition } from '../typings/skill-types.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport { extractSkillArguments } from './extract-skill-arguments.function.ts';\nimport { parseSkillContent } from './parse-skill-content.function.ts';\nimport { serializeSkillContent } from './serialize-skill-content.function.ts';\nimport { formatSearchResults } from './format-search-results.function.ts';\nimport { handleAgentCreate } from './handle-agent-create.function.ts';\nimport { handleAgentList } from './handle-agent-list.function.ts';\nimport { handleAgentGet } from './handle-agent-get.function.ts';\nimport { handleAgentDelete } from './handle-agent-delete.function.ts';\nimport { handleRecall } from './handle-recall.function.ts';\nimport { handleSkillSearch as handleSkillSearchTool } from './handle-skill-search.function.ts';\nimport { handleAgentSearch as handleAgentSearchTool } from './handle-agent-search.function.ts';\n\n/** Shape of a content item in an MCP tool call response. */\ninterface ToolContent {\n /** Content type identifier, typically 'text'. */\n readonly type: string;\n /** The text payload. */\n readonly text: string;\n}\n\n/** Result returned by a tool call handler. */\ninterface ToolCallResult {\n /** One or more content items describing the result. */\n readonly content: ToolContent[];\n /** Set to `true` when the tool encountered an error. */\n readonly isError?: boolean;\n}\n\n/**\n * Narrows an `unknown` value to a string, returning the fallback\n * when the value is not already a string.\n */\nfunction asString(value: unknown, fallback: string): string {\n return typeof value === 'string' ? value : fallback;\n}\n\n/**\n * Narrows an `unknown` value to a boolean, returning `undefined`\n * when the value is not a boolean.\n */\nfunction asBooleanOrUndefined(value: unknown): boolean | undefined {\n return typeof value === 'boolean' ? value : undefined;\n}\n\n/**\n * Narrows an `unknown` value to a `string[]`, returning `undefined`\n * when the value is not an array of strings.\n */\nfunction asStringArrayOrUndefined(\n value: unknown,\n): string[] | undefined {\n if (\n Array.isArray(value) &&\n value.every((item) => typeof item === 'string')\n ) {\n return value;\n }\n return undefined;\n}\n\n/**\n * Narrows an `unknown` value to a `string[]`, returning an empty\n * array when the value is not an array of strings.\n */\nfunction asStringArray(value: unknown): string[] {\n if (\n Array.isArray(value) &&\n value.every((item) => typeof item === 'string')\n ) {\n return value;\n }\n return [];\n}\n\n/**\n * Unwraps content that AI clients accidentally wrap in a\n * JSON object. If the string starts with `{` and parses\n * as JSON with a `content` or `text` field, returns that\n * inner field value. Otherwise returns the original string.\n */\nfunction unwrapJsonContent(raw: string): string {\n const trimmed = raw.trim();\n if (!trimmed.startsWith('{')) return raw;\n try {\n const parsed = JSON.parse(trimmed) as Record<string, unknown>;\n if (typeof parsed['content'] === 'string')\n return parsed['content'];\n if (typeof parsed['text'] === 'string') return parsed['text'];\n } catch {\n // Not valid JSON -- return as-is\n }\n return raw;\n}\n\n/**\n * Dispatches an MCP tool call to the appropriate knowledge-base\n * operation and returns the result formatted as MCP content.\n *\n * @param client - the worker client used to execute operations\n * @param name - the tool name to invoke\n * @param args - tool arguments from the MCP request\n * @returns content items with optional isError flag\n */\nexport async function handleToolCall(\n client: McpWorkerClient,\n name: string,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n log('tool call: ' + name, LogLevel.DEBUG);\n try {\n switch (name) {\n case 'search':\n return await handleSearch(client, args);\n case 'learn':\n return await handleLearn(client, args);\n case 'unlearn':\n return await handleUnlearn(client, args);\n case 'retrieve':\n return await handleRetrieve(client, args);\n case 'recall':\n return await handleRecall(client, args);\n case 'status':\n return await handleStatus(client);\n case 'content':\n return await handleContent(client, args);\n case 'check':\n return await handleCheck(client);\n case 'gc':\n return await handleGc(client);\n case 'rebuild':\n return await handleRebuild(client);\n case 'export':\n return await handleExport(client, args);\n case 'skill-learn':\n return await handleSkillLearn(client, args);\n case 'skill-list':\n return await handleSkillList(client);\n case 'skill-get':\n return await handleSkillGet(client, args);\n case 'skill-delete':\n return await handleSkillDelete(client, args);\n case 'agent-create':\n return await handleAgentCreate(client, args);\n case 'agent-list':\n return await handleAgentList(client);\n case 'agent-get':\n return await handleAgentGet(client, args);\n case 'agent-delete':\n return await handleAgentDelete(client, args);\n case 'skill-search':\n return await handleSkillSearchTool(client, args);\n case 'agent-search':\n return await handleAgentSearchTool(client, args);\n case 'auto-capture-review':\n return handleAutoCaptureReview();\n default:\n log('unknown tool: ' + name, LogLevel.WARNING);\n return {\n content: [\n {\n type: 'text',\n text: `Unknown tool: ${name}`,\n },\n ],\n isError: true,\n };\n }\n } catch (err) {\n log(\n 'tool call failed: ' +\n name +\n ': ' +\n (err instanceof Error ? err.message : String(err)),\n LogLevel.ERROR,\n );\n return {\n content: [\n {\n type: 'text',\n text: err instanceof Error ? err.message : String(err),\n },\n ],\n isError: true,\n };\n }\n}\n\nasync function handleSearch(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const query = asString(args['query'], '');\n const results = await client.search({\n query,\n mode: args['mode'] as string | undefined,\n limit: args['limit'] as number | undefined,\n offset: args['offset'] as number | undefined,\n algo: args['algo'] as string | undefined,\n relaxed: args['relaxed'] as boolean | undefined,\n });\n\n return {\n content: [\n { type: 'text', text: formatSearchResults(query, results) },\n ],\n };\n}\n\nasync function handleLearn(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const sectionType = asString(args['type'], 'text/markdown');\n const title =\n typeof args['title'] === 'string' ? args['title'] : undefined;\n const description =\n typeof args['description'] === 'string'\n ? args['description']\n : undefined;\n const docid =\n typeof args['docid'] === 'string' ? args['docid'] : undefined;\n const tags = asStringArrayOrUndefined(args['tags']);\n const replace = asBooleanOrUndefined(args['replace']);\n if (sectionType.startsWith('image/') && !title) {\n return {\n content: [\n {\n type: 'text',\n text: 'title is required for image/* types',\n },\n ],\n isError: true,\n };\n }\n const rawContent = asString(args['content'], '');\n const content = unwrapJsonContent(rawContent);\n const result = await client.addSection({\n sectionType,\n content,\n title,\n description,\n docid,\n tags,\n replace,\n });\n const payload = {\n items: result.items,\n total: result.total,\n offset: result.offset,\n superseded: result.superseded ?? null,\n warnings: result.warnings ?? [],\n near_duplicates: result.near_duplicates ?? [],\n };\n return {\n content: [{ type: 'text', text: JSON.stringify(payload) }],\n };\n}\n\nasync function handleUnlearn(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const kbid = asString(args['kbid'], '');\n await client.removeSection(kbid);\n return {\n content: [{ type: 'text', text: `Removed section ${kbid}` }],\n };\n}\n\nasync function handleRetrieve(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n if (typeof args['kbid'] === 'string') {\n const sections = await client.readSections([args['kbid']]);\n return {\n content: [{ type: 'text', text: formatSections(sections) }],\n };\n }\n if (typeof args['docid'] === 'string') {\n const doc = await client.retrieveDocument(args['docid']);\n return {\n content: [{ type: 'text', text: formatDocument(doc) }],\n };\n }\n return {\n content: [\n {\n type: 'text',\n text: 'Provide kbid or docid',\n },\n ],\n isError: true,\n };\n}\n\n/** Formats a list of sections as human-readable heading and content. */\nfunction formatSections(\n sections: readonly {\n readonly kbid: string;\n readonly sectionType: string;\n readonly content: string;\n }[],\n): string {\n if (sections.length === 0) {\n return 'No sections found';\n }\n return sections\n .map((s) => `${s.kbid} (${s.sectionType})\\n${s.content}`)\n .join('\\n\\n');\n}\n\n/** Formats a document's metadata fields as human-readable text. */\nfunction formatDocument(doc: unknown): string {\n if (typeof doc !== 'object' || doc === null) {\n return String(doc);\n }\n return Object.entries(doc as Record<string, unknown>)\n .map(([key, value]) => {\n if (Array.isArray(value)) {\n const items = value\n .map((item) => formatDocValue(item))\n .map((s) => ` - ${s}`);\n return items.length > 0\n ? `${key}:\\n${items.join('\\n')}`\n : `${key}: (none)`;\n }\n return `${key}: ${formatDocValue(value)}`;\n })\n .join('\\n');\n}\n\n/** Formats a single document field value as readable text. */\nfunction formatDocValue(value: unknown): string {\n if (typeof value !== 'object' || value === null) {\n return String(value);\n }\n const rec = value as Record<string, unknown>;\n return Object.entries(rec)\n .map(([k, v]) => `${k}=${String(v)}`)\n .join(', ');\n}\n\nasync function handleStatus(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const status = await client.dbStatus();\n const cs = status.cacheStats;\n const lines = [\n `Database: ${status.contextPath}`,\n `Initialized: ${status.initialized ? 'yes' : 'no'}`,\n ];\n if (cs) {\n lines.push(\n `Cached content entries: ${String(cs.contentCount)}`,\n `Cached index entries: ${String(cs.indexCount)}`,\n );\n }\n return { content: [{ type: 'text', text: lines.join('\\n') }] };\n}\n\nasync function handleContent(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const ids = asStringArray(args['ids']);\n const result = await client.content(ids);\n const text = result.data || '(no content found)';\n return {\n content: [{ type: 'text', text }],\n };\n}\n\nasync function handleCheck(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const report = await client.integrityCheck();\n const status = report.ok ? 'OK' : 'FAIL';\n const lines = [\n `Integrity check: ${status}. ` +\n `${String(report.sections_checked)} sections checked.`,\n ];\n for (const error of report.errors) {\n lines.push(`- ${error.type}: ${error.entity} (${error.detail})`);\n }\n return { content: [{ type: 'text', text: lines.join('\\n') }] };\n}\n\nasync function handleGc(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const report = await client.gc();\n const lines = [\n `GC complete: removed ${String(report.removed_sections)} sections, ` +\n `freed ${String(report.removed_bytes)} bytes.`,\n ];\n if (report.stale_sources !== undefined) {\n lines.push(`stale sources: ${String(report.stale_sources)}`);\n }\n return { content: [{ type: 'text', text: lines.join('\\n') }] };\n}\n\nasync function handleRebuild(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const report = await client.rebuildIndexes();\n const text =\n `Rebuild complete: ${String(report.sections_reindexed)} sections ` +\n `reindexed, ${String(report.terms_indexed)} terms indexed.`;\n return { content: [{ type: 'text', text }] };\n}\n\nasync function handleSkillLearn(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const name = asString(args['name'], '');\n if (!name) {\n return {\n content: [{ type: 'text', text: 'name is required' }],\n isError: true,\n };\n }\n const body = asString(args['body'], '');\n if (!body) {\n return {\n content: [{ type: 'text', text: 'body is required' }],\n isError: true,\n };\n }\n const description =\n typeof args['description'] === 'string'\n ? args['description']\n : undefined;\n const skillArgs = extractSkillArguments(body);\n const skill = {\n name,\n description,\n arguments: skillArgs.length > 0 ? skillArgs : undefined,\n body,\n };\n const json = serializeSkillContent(skill);\n const result = await client.addSection({\n sectionType: 'skill',\n content: json,\n title: name,\n description,\n });\n return {\n content: [\n {\n type: 'text',\n text: `Created skill \"${name}\" (kbid: ${result.items[0]})`,\n },\n ],\n };\n}\n\nasync function handleSkillList(\n client: McpWorkerClient,\n): Promise<ToolCallResult> {\n const records = await client.listByType('skill');\n const lines = records.map((r, index) => {\n const desc = r.description ? ` -- ${r.description}` : '';\n const label = r.title ?? '(untitled)';\n return `${String(index + 1)}. ${label} (${r.kbid})${desc}`;\n });\n const text = [`${String(records.length)} skills:`, ...lines].join(\n '\\n',\n );\n return { content: [{ type: 'text', text }] };\n}\n\nasync function handleSkillGet(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const kbid =\n typeof args['kbid'] === 'string' ? args['kbid'] : undefined;\n const name =\n typeof args['name'] === 'string' ? args['name'] : undefined;\n if (!kbid && !name) {\n return {\n content: [\n {\n type: 'text',\n text: 'name or kbid is required',\n },\n ],\n isError: true,\n };\n }\n let content: string | undefined;\n if (kbid) {\n const sections = await client.readSections([kbid]);\n if (sections.length > 0) {\n content = sections[0]?.content;\n }\n }\n if (content === undefined && name) {\n const records = await client.listByType('skill');\n const match = records.filter((r) => r.title === name).pop();\n if (match) {\n content = match.content;\n }\n }\n if (content === undefined) {\n const identifier = kbid ?? name ?? '';\n return {\n content: [\n {\n type: 'text',\n text: `skill not found: ${identifier}`,\n },\n ],\n isError: true,\n };\n }\n const skill = parseSkillContent(content);\n return {\n content: [{ type: 'text', text: formatSkill(skill) }],\n };\n}\n\n/** Formats a skill definition's name, description, arguments, body. */\nfunction formatSkill(skill: SkillDefinition): string {\n const lines = [`name: ${skill.name}`];\n if (skill.description) {\n lines.push(`description: ${skill.description}`);\n }\n if (skill.arguments && skill.arguments.length > 0) {\n lines.push('arguments:');\n for (const arg of skill.arguments) {\n const details = [\n ...(arg.type ? [arg.type] : []),\n ...(arg.required ? ['required'] : []),\n ];\n lines.push(\n details.length > 0\n ? `- ${arg.name}: ${details.join(', ')}`\n : `- ${arg.name}`,\n );\n }\n }\n lines.push('body:', skill.body);\n return lines.join('\\n');\n}\n\nasync function handleSkillDelete(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const kbid = asString(args['kbid'], '');\n if (!kbid) {\n return {\n content: [{ type: 'text', text: 'kbid is required' }],\n isError: true,\n };\n }\n await client.removeSection(kbid);\n return {\n content: [{ type: 'text', text: `Deleted skill ${kbid}` }],\n };\n}\n\nfunction handleAutoCaptureReview(): ToolCallResult {\n return {\n content: [\n {\n type: 'text',\n text: 'No pending auto-captured knowledge entries.',\n },\n ],\n };\n}\n\nasync function handleExport(\n client: McpWorkerClient,\n args: Record<string, unknown>,\n): Promise<ToolCallResult> {\n const path =\n typeof args['path'] === 'string' ? args['path'] : undefined;\n const result = await client.export(\n path !== undefined ? { path } : {},\n );\n const lines = [\n `Exported to ${result.path}`,\n `sections: ${String(result.sections_exported)}`,\n `documents: ${String(result.documents_exported)}`,\n `elapsed: ${String(result.elapsed_ms)}ms`,\n ];\n return { content: [{ type: 'text', text: lines.join('\\n') }] };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** A single content item in an MCP resource read response. */\ninterface ResourceContent {\n /** The resource URI that was read. */\n readonly uri: string;\n /** MIME type of the content body. */\n readonly mimeType: string;\n /** Text body of the resource. */\n readonly text: string;\n}\n\n/** Result returned by a resource read operation. */\ninterface ResourceReadResult {\n /** One or more content items for the requested URI. */\n readonly contents: ResourceContent[];\n}\n\n/**\n * Handles an MCP `resources/read` request by dispatching to the\n * appropriate knowledge-base operation based on the resource URI.\n *\n * @param client - the worker client used to fetch the resource\n * @param uri - the resource URI from the MCP request\n * @returns contents array for the MCP response\n * @throws {Error} when the URI does not match any known pattern\n */\nexport async function handleResourceRead(\n client: McpWorkerClient,\n uri: string,\n): Promise<ResourceReadResult> {\n const sectionMatch = uri.match(/^kbdb:\\/\\/section\\/(.+)$/);\n if (sectionMatch) {\n const sections = await client.readSections([sectionMatch[1]]);\n const text = sections.length > 0 ? sections[0].content : '';\n return {\n contents: [{ uri, mimeType: 'text/plain', text }],\n };\n }\n\n const docMatch = uri.match(/^kbdb:\\/\\/document\\/(.+)$/);\n if (docMatch) {\n const doc = await client.retrieveDocument(docMatch[1]);\n return {\n contents: [\n {\n uri,\n mimeType: 'application/json',\n text: JSON.stringify(doc, null, 2),\n },\n ],\n };\n }\n\n log(`Unknown resource URI: ${uri}`, LogLevel.ERROR);\n throw new Error(`Unknown resource URI: ${uri}`);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpPrompt } from '../typings/prompt-types.interface.ts';\nimport type { McpPromptArgument } from '../typings/prompt-types.interface.ts';\n\n/** Minimal skill section record shape required by this function. */\ninterface SkillSectionRecord {\n /** Knowledge-base identifier of the section. */\n readonly kbid: string;\n /** Human-readable section title used as the prompt name. */\n readonly title: string | null;\n /** JSON-encoded skill definition content. */\n readonly content: string;\n /** Optional human-readable section description. */\n readonly description?: string | null;\n}\n\n/** Minimal document manifest shape required by this function. */\ninterface AgentDocumentRecord {\n /** Unique document identifier. */\n readonly docid: string;\n /** Human-readable document title used in the prompt name. */\n readonly title: string;\n /** Ordered section references belonging to the document. */\n readonly sections: readonly {\n readonly kbid: string;\n readonly position: number;\n }[];\n}\n\n/**\n * Parses the `arguments` field from a skill's JSON content string.\n *\n * Returns the array of prompt argument definitions when the content\n * is valid JSON with an `arguments` array, or `undefined` when JSON\n * parsing fails or the field is absent.\n */\nfunction parseSkillArguments(\n content: string,\n): readonly McpPromptArgument[] | undefined {\n try {\n const parsed = JSON.parse(content) as Record<string, unknown>;\n if (!Array.isArray(parsed['arguments'])) {\n return undefined;\n }\n return (parsed['arguments'] as Record<string, unknown>[]).map(\n (arg) => ({\n name: typeof arg['name'] === 'string' ? arg['name'] : '',\n description:\n typeof arg['description'] === 'string'\n ? arg['description']\n : undefined,\n required:\n typeof arg['required'] === 'boolean'\n ? arg['required']\n : undefined,\n }),\n );\n } catch {\n return undefined;\n }\n}\n\n/**\n * Builds the list of MCP prompt definitions from skill sections and\n * agent document manifests stored in the knowledge base.\n *\n * Skills are mapped first (in input order), followed by agents.\n * Each skill becomes a prompt whose name is the section title and\n * whose arguments are extracted from the JSON content. Each agent\n * becomes a prompt prefixed with `\"agent:\"` and carries an empty\n * arguments array.\n *\n * @param skills - skill section records from `listByType('skill')`\n * @param agents - agent document manifests from\n * `listDocumentsByType('agent')`\n * @returns ordered list of MCP prompt definitions\n */\nexport function createPromptDefinitions(\n skills: readonly SkillSectionRecord[],\n agents: readonly AgentDocumentRecord[],\n): McpPrompt[] {\n const skillPrompts: McpPrompt[] = skills\n .filter(\n (r): r is SkillSectionRecord & { title: string } =>\n r.title !== null,\n )\n .map((record) => {\n const args = parseSkillArguments(record.content);\n const prompt: McpPrompt = {\n name: record.title,\n description: record.description ?? undefined,\n arguments: args,\n };\n return prompt;\n });\n\n const agentPrompts: McpPrompt[] = agents.map((doc) => ({\n name: `agent:${doc.title}`,\n arguments: [],\n }));\n\n return [...skillPrompts, ...agentPrompts];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type { McpPromptMessage } from '../typings/prompt-types.interface.ts';\n\n/** Parsed shape of an agent metadata section. */\ninterface AgentMeta {\n /** Agent persona text. */\n readonly persona: string;\n}\n\n/** Minimal section shape returned by readSections. */\ninterface ReadSection {\n /** Knowledge-base identifier. */\n readonly kbid: string;\n /** Raw text content. */\n readonly content: string;\n}\n\n/** Minimal agent document shape from listDocumentsByType. */\ninterface AgentDocument {\n /** Document title. */\n readonly title: string;\n /** Ordered section references. */\n readonly sections: readonly {\n readonly kbid: string;\n readonly position: number;\n }[];\n}\n\n/**\n * Parses agent metadata from a raw JSON content string.\n *\n * Returns default values when parsing fails or required fields are\n * absent.\n */\nfunction parseAgentMeta(content: string): AgentMeta {\n try {\n const parsed = JSON.parse(content) as Record<string, unknown>;\n return {\n persona:\n typeof parsed['persona'] === 'string'\n ? parsed['persona']\n : '',\n };\n } catch {\n return { persona: '' };\n }\n}\n\n/**\n * Builds the skills listing user message text from an array of\n * skill section content strings. Sections whose JSON is not parseable\n * or whose name cannot be determined are omitted silently.\n *\n * Returns `null` when no valid skills remain after filtering.\n */\nfunction buildSkillsText(skillSections: ReadSection[]): string | null {\n const lines: string[] = [];\n for (const sec of skillSections) {\n try {\n const parsed = JSON.parse(sec.content) as Record<\n string,\n unknown\n >;\n const name =\n typeof parsed['name'] === 'string' ? parsed['name'] : null;\n if (name === null) {\n continue;\n }\n const description =\n typeof parsed['description'] === 'string'\n ? parsed['description']\n : '';\n lines.push(`- ${name}: ${description}`);\n } catch {\n // skip unparseable sections\n }\n }\n if (lines.length === 0) {\n return null;\n }\n return `Available skills:\\n${lines.join('\\n')}`;\n}\n\n/**\n * Handles an MCP `prompts/get` request for an agent prompt.\n *\n * Looks up the agent by title via `listDocumentsByType('agent')`,\n * extracts its persona from the metadata section, then reads all\n * skill sections and composes the response. Returns an assistant\n * message with the persona and, when skills exist, a user message\n * listing them.\n */\nasync function handleAgentPrompt(\n name: string,\n client: McpWorkerClient,\n): Promise<McpPromptMessage[]> {\n const agentName = name.slice(6);\n const agents = await client.listDocumentsByType('agent');\n const doc = agents.find((a) => a.title === agentName) as\n | AgentDocument\n | undefined;\n if (!doc) {\n log('agent not found: ' + agentName, LogLevel.ERROR);\n throw new Error('agent not found: ' + agentName);\n }\n const sections = doc.sections;\n\n const metaSection = sections.at(0);\n const skillRefs = sections.slice(1);\n\n let persona = '';\n if (metaSection !== undefined) {\n const metaSections = await client.readSections([\n metaSection.kbid,\n ]);\n const metaContent = metaSections.at(0);\n if (metaContent !== undefined) {\n persona = parseAgentMeta(metaContent.content).persona;\n }\n }\n\n const messages: McpPromptMessage[] = [\n {\n role: 'assistant',\n content: { type: 'text', text: persona },\n },\n ];\n\n if (skillRefs.length === 0) {\n return messages;\n }\n\n const skillKbids = skillRefs.map((s) => s.kbid);\n const skillSections = await client.readSections(skillKbids);\n const skillsText = buildSkillsText(skillSections);\n\n if (skillsText !== null) {\n messages.push({\n role: 'user',\n content: { type: 'text', text: skillsText },\n });\n }\n\n return messages;\n}\n\n/**\n * Handles an MCP `prompts/get` request for a skill prompt.\n *\n * Looks up the skill by name in the `listByType('skill')` results,\n * picks the most recent match (last occurrence), parses its body,\n * and substitutes `{{argName}}` placeholders from `promptArgs`.\n * Unresolved placeholders are left as-is.\n *\n * @throws {Error} when no skill with the given name is found\n */\nasync function handleSkillPrompt(\n name: string,\n promptArgs: Record<string, string>,\n client: McpWorkerClient,\n): Promise<McpPromptMessage[]> {\n const sections = await client.listByType('skill');\n let matchContent: string | undefined;\n for (const sec of sections) {\n if (sec.title === name) {\n matchContent = sec.content;\n }\n }\n if (matchContent === undefined) {\n log(`Prompt not found: ${name}`, LogLevel.ERROR);\n throw new Error(`Prompt not found: ${name}`);\n }\n\n const parsed = JSON.parse(matchContent) as Record<string, unknown>;\n const body =\n typeof parsed['body'] === 'string' ? parsed['body'] : '';\n\n const rendered = body.replace(\n /\\{\\{(\\w+)\\}\\}/g,\n (_match, key: string) =>\n key in promptArgs ? (promptArgs[key] ?? _match) : _match,\n );\n\n return [\n {\n role: 'user',\n content: { type: 'text', text: rendered },\n },\n ];\n}\n\n/**\n * Handles an MCP `prompts/get` request.\n *\n * Dispatches to the agent handler when `name` starts with `\"agent:\"`,\n * otherwise treats the name as a skill prompt.\n *\n * For skill prompts: looks up by title using `listByType('skill')`,\n * substitutes `{{argName}}` placeholders in the body, and returns a\n * single user message.\n *\n * For agent prompts: looks up the agent by title via\n * `listDocumentsByType('agent')`, builds an assistant message from\n * the persona section, and (when skills exist) a user message\n * listing their names and descriptions.\n *\n * @param name - prompt name from the MCP request\n * @param promptArgs - argument key-value map from the MCP request\n * @param client - worker client used to access the knowledge base\n * @returns ordered list of prompt messages to return to the caller\n * @throws {Error} when a skill prompt name is not found in the store\n */\nexport async function handlePromptGet(\n name: string,\n promptArgs: Record<string, string>,\n client: McpWorkerClient,\n): Promise<McpPromptMessage[]> {\n if (name.startsWith('agent:')) {\n return handleAgentPrompt(name, client);\n }\n return handleSkillPrompt(name, promptArgs, client);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/**\n * Discriminated reference used in MCP completion requests.\n * Identifies whether the completion target is a prompt or a resource.\n */\nexport interface McpCompletionRef {\n /**\n * The reference type: `'ref/prompt'` for named prompts (skills\n * and agents) or `'ref/resource'` for resource URIs.\n */\n readonly type: 'ref/prompt' | 'ref/resource';\n /** Prompt name, present when `type` is `'ref/prompt'`. */\n readonly name?: string;\n /** Resource URI, present when `type` is `'ref/resource'`. */\n readonly uri?: string;\n}\n\n/**\n * Completion argument supplied by the client, describing which\n * argument is being completed and the current partial value.\n */\nexport interface McpCompletionArgument {\n /** The argument name being completed. */\n readonly name: string;\n /** The partial value typed so far; used for prefix filtering. */\n readonly value: string;\n}\n\n/**\n * Result returned by `handleCompletion`, containing the list of\n * matching completion values and pagination metadata.\n */\nexport interface McpCompletionResult {\n /** Completion payload. */\n readonly completion: {\n /** Matching completion strings for the given prefix. */\n readonly values: string[];\n /**\n * Whether more results are available beyond what is returned.\n * Always `false` in this implementation.\n */\n readonly hasMore: boolean;\n /** Total number of values returned. */\n readonly total: number;\n };\n}\n\n/**\n * Handles an MCP `completion/complete` request.\n *\n * For `ref/prompt` references, builds a list of all skill titles and\n * agent titles (prefixed with `agent:`) and filters by the supplied\n * argument value prefix. For `ref/resource` references, returns an\n * empty result \u2014 resource completion is not implemented.\n *\n * @param ref - discriminated reference identifying the completion target\n * @param argument - current argument name and partial value\n * @param client - worker client used to fetch skills and agents\n * @returns matching completion values with pagination metadata\n */\nexport async function handleCompletion(\n ref: McpCompletionRef,\n argument: McpCompletionArgument,\n client: McpWorkerClient,\n): Promise<McpCompletionResult> {\n if (ref.type !== 'ref/prompt') {\n return { completion: { values: [], hasMore: false, total: 0 } };\n }\n\n const [skills, agents] = await Promise.all([\n client.listByType('skill'),\n client.listDocumentsByType('agent'),\n ]);\n\n const names: string[] = [];\n\n for (const skill of skills) {\n if (skill.title !== null) {\n names.push(skill.title);\n }\n }\n\n for (const agent of agents) {\n names.push(`agent:${agent.title}`);\n }\n\n const prefix = argument.value;\n\n function matchesPrefix(candidate: string): boolean {\n if (prefix.length === 0) {\n return true;\n }\n if (candidate.startsWith(prefix)) {\n return true;\n }\n // For agent-prefixed names, also match against the title portion.\n const AGENT_PREFIX = 'agent:';\n if (candidate.startsWith(AGENT_PREFIX)) {\n return candidate.slice(AGENT_PREFIX.length).startsWith(prefix);\n }\n return false;\n }\n\n const values = names.filter(matchesPrefix);\n\n return {\n completion: {\n values,\n hasMore: false,\n total: values.length,\n },\n };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Represents a single file-system root entry advertised to MCP\n * clients via the `roots/list` response.\n */\nexport interface McpRoot {\n /** Absolute file URI for the root directory. */\n readonly uri: string;\n /** Human-readable label for the root. */\n readonly name: string;\n}\n\n/**\n * Returns the list of MCP roots for the given database context path.\n *\n * Produces a single root entry whose URI is `file://` concatenated\n * with the supplied `contextPath`. This tells MCP clients which\n * file-system directory the server is authoritative for.\n *\n * @param contextPath - absolute path to the kbdb database directory\n * @returns array containing a single root for the context path\n */\nexport function handleRootsList(contextPath: string): McpRoot[] {\n return [\n {\n uri: `file://${contextPath}`,\n name: 'kbdb database',\n },\n ];\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { McpLogLevel } from '../typings/log-types.interface.ts';\n\n/**\n * Ordered list of MCP log severity levels, from least severe\n * (`debug`) to most severe (`emergency`). Used to compare levels\n * when filtering log output.\n */\nexport const LOG_LEVEL_ORDER: McpLogLevel[] = [\n 'debug',\n 'info',\n 'notice',\n 'warning',\n 'error',\n 'critical',\n 'alert',\n 'emergency',\n];\n\n/**\n * Determines whether a log message at `messageLevel` should be\n * emitted when the server's log threshold is `threshold`.\n *\n * Returns `true` when `messageLevel` is at the same severity as\n * `threshold` or higher. Returns `false` when the message level is\n * below the threshold.\n *\n * @param messageLevel - severity of the log message to evaluate\n * @param threshold - minimum severity level required to emit\n * @returns `true` if the message meets or exceeds the threshold\n */\nexport function shouldEmitLog(\n messageLevel: McpLogLevel,\n threshold: McpLogLevel,\n): boolean {\n const messageIndex = LOG_LEVEL_ORDER.indexOf(messageLevel);\n const thresholdIndex = LOG_LEVEL_ORDER.indexOf(threshold);\n return messageIndex >= thresholdIndex;\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Builds the MCP sampling prompt for knowledge extraction.\n *\n * Instructs the host LLM to identify durable factual knowledge\n * from the recent conversation context, filter out ephemeral or\n * task-specific information, and format the result for storage\n * following memory-protocol criteria.\n *\n * @param recentContext - the conversation excerpt to analyse\n */\nexport function buildCapturePrompt(recentContext: string): string {\n return (\n 'Review the following conversation context and identify' +\n ' factual knowledge worth storing in the knowledge base.\\n\\n' +\n 'Rules:\\n' +\n '- Include durable facts, decisions, preferences, and' +\n ' corrections that would be useful in future sessions.\\n' +\n '- Exclude ephemeral, task-specific, or temporary information' +\n ' that has no lasting value.\\n' +\n '- Format each piece of extracted knowledge as a concise' +\n ' statement suitable for direct storage.\\n' +\n '- If no durable knowledge is found, respond with an empty' +\n ' list.\\n\\n' +\n 'Conversation context:\\n' +\n recentContext\n );\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * Returns `true` when the host advertised the `sampling` capability\n * during MCP initialization.\n *\n * @param hostCapabilities - capabilities object from the MCP\n * `initialize` request, or `null` when not yet set\n */\nexport function hasSamplingCapability(\n hostCapabilities: Record<string, unknown> | null,\n): boolean {\n if (hostCapabilities === null) return false;\n return Boolean(hostCapabilities['sampling']);\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { AutoCaptureController } from '../../auto-capture/classes/auto-capture-controller.class.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\nimport type { AutoCaptureConfig } from '../../auto-capture/typings/auto-capture-config.interface.ts';\nimport { buildCapturePrompt } from '../../auto-capture/functions/build-capture-prompt.function.ts';\nimport { hasSamplingCapability } from './has-sampling-capability.function.ts';\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\n\n/** Sampling request callback matching McpServer.sendRequest. */\ntype RequestSampling = (\n messages: {\n role: string;\n content: { type: string; text: string };\n }[],\n maxTokens: number,\n) => Promise<unknown>;\n\n/** Shape of a successful sampling response. */\ninterface SamplingResponse {\n readonly content: { readonly type: string; readonly text: string };\n}\n\nfunction isSamplingResponse(v: unknown): v is SamplingResponse {\n if (typeof v !== 'object' || v === null) return false;\n const obj = v as Record<string, unknown>;\n const content = obj['content'];\n if (typeof content !== 'object' || content === null) return false;\n return (\n typeof (content as Record<string, unknown>)['text'] === 'string'\n );\n}\n\n/**\n * Evaluates the auto-capture trigger and, when it fires, sends an\n * MCP sampling request to the host and stores any returned knowledge.\n *\n * Silently ignores all errors so a capture failure never disrupts\n * the MCP server's normal operation.\n *\n * @param controller - tracks session state and evaluates the trigger\n * @param config - auto-capture configuration (provides dryRun flag)\n * @param client - worker client used to persist captured knowledge\n * @param hostCapabilities - capabilities from the MCP host\n * @param requestSampling - sends a sampling request to the host\n */\nexport async function runAutoCapture(\n controller: AutoCaptureController,\n config: AutoCaptureConfig,\n client: McpWorkerClient,\n hostCapabilities: Record<string, unknown> | null,\n requestSampling: RequestSampling,\n): Promise<void> {\n try {\n const trigger = controller.evaluate();\n log('auto-capture trigger evaluated', LogLevel.DEBUG);\n if (!trigger.shouldCapture) return;\n if (!hasSamplingCapability(hostCapabilities)) return;\n\n const prompt = buildCapturePrompt('recent conversation context');\n const messages = [\n { role: 'user', content: { type: 'text', text: prompt } },\n ];\n const raw = await requestSampling(messages, 1024);\n\n if (!isSamplingResponse(raw)) return;\n const text = raw.content.text.trim();\n if (!text) return;\n if (config.dryRun) return;\n\n log('auto-capture storing knowledge', LogLevel.DEBUG);\n await client.addSection({\n sectionType: 'text/markdown',\n content: text,\n title: 'Auto-captured knowledge',\n });\n } catch {\n log('auto-capture error (non-fatal)', LogLevel.DEBUG);\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { AutoCaptureConfig } from '../typings/auto-capture-config.interface.ts';\nimport type { AutoCaptureState } from '../typings/auto-capture-state.interface.ts';\nimport type { AutoCaptureTrigger } from '../typings/auto-capture-trigger.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Evaluates whether auto-capture should fire given the current\n * configuration and runtime state.\n *\n * Checks (in order): feature flag, session cap, rate limit,\n * and tool-call count threshold. Returns the first failing\n * condition as the reason.\n */\nexport function evaluateTrigger(\n config: AutoCaptureConfig,\n state: AutoCaptureState,\n): AutoCaptureTrigger {\n log('evaluating auto-capture trigger conditions', LogLevel.DEBUG);\n if (!config.enabled) {\n return {\n shouldCapture: false,\n reason: 'auto-capture is disabled',\n };\n }\n\n if (state.totalCapturesThisSession >= config.maxCapturesPerSession) {\n return {\n shouldCapture: false,\n reason: 'session capture limit reached',\n };\n }\n\n const elapsed = state.lastCaptureTimestamp\n ? Date.now() - state.lastCaptureTimestamp\n : Infinity;\n\n if (elapsed < config.minIntervalMs) {\n return {\n shouldCapture: false,\n reason: 'within minimum interval',\n };\n }\n\n if (state.toolCallsSinceLastCapture < config.triggerAfterToolCalls) {\n return {\n shouldCapture: false,\n reason: 'tool call threshold not yet reached',\n };\n }\n\n return { shouldCapture: true, reason: 'trigger threshold met' };\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport type { AutoCaptureConfig } from '../typings/auto-capture-config.interface.ts';\nimport type { AutoCaptureState } from '../typings/auto-capture-state.interface.ts';\nimport type { AutoCaptureTrigger } from '../typings/auto-capture-trigger.interface.ts';\nimport { evaluateTrigger } from '../functions/evaluate-trigger.function.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Controls the auto-capture lifecycle.\n *\n * Tracks tool call counts, evaluates trigger conditions, and\n * advances session state when a capture fires. Reset state on\n * disconnect or session end via `reset()`.\n */\nexport class AutoCaptureController {\n private toolCallsSinceLastCapture = 0;\n private lastCaptureTimestamp = 0;\n private totalCapturesThisSession = 0;\n private readonly config: AutoCaptureConfig;\n\n /** @param config - the auto-capture configuration to use */\n constructor(config: AutoCaptureConfig) {\n this.config = config;\n }\n\n /** Record one tool call for trigger counting. */\n recordToolCall(): void {\n this.toolCallsSinceLastCapture += 1;\n }\n\n /**\n * Evaluates the current state against the trigger criteria.\n *\n * When the trigger fires, advances the session counters so the\n * next evaluation respects rate limiting and the session cap.\n *\n * @returns the trigger decision with a human-readable reason\n */\n evaluate(): AutoCaptureTrigger {\n log('evaluating auto-capture trigger', LogLevel.DEBUG);\n const trigger = evaluateTrigger(this.config, this.state());\n if (trigger.shouldCapture) {\n this.totalCapturesThisSession += 1;\n this.lastCaptureTimestamp = Date.now();\n this.toolCallsSinceLastCapture = 0;\n }\n return trigger;\n }\n\n /** Reset all counters, e.g. on client disconnect. */\n reset(): void {\n log('resetting auto-capture controller', LogLevel.DEBUG);\n this.toolCallsSinceLastCapture = 0;\n this.lastCaptureTimestamp = 0;\n this.totalCapturesThisSession = 0;\n }\n\n /** Returns a snapshot of the current controller state. */\n state(): AutoCaptureState {\n return {\n toolCallsSinceLastCapture: this.toolCallsSinceLastCapture,\n lastCaptureTimestamp: this.lastCaptureTimestamp,\n totalCapturesThisSession: this.totalCapturesThisSession,\n };\n }\n}\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\n/**\n * JSON-RPC 2.0 parse error code. Returned when the\n * server receives malformed JSON.\n */\nexport const PARSE_ERROR = -32700;\n\n/**\n * JSON-RPC 2.0 method not found error code. Returned\n * when the requested method does not exist.\n */\nexport const METHOD_NOT_FOUND = -32601;\n\n/**\n * JSON-RPC 2.0 invalid params error code. Returned\n * when method parameters are invalid or missing.\n */\nexport const INVALID_PARAMS = -32602;\n\n/**\n * JSON-RPC 2.0 internal error code. Returned when an\n * unexpected server-side error occurs.\n */\nexport const INTERNAL_ERROR = -32603;\n\n/**\n * MCP-specific resource not found error code. Returned\n * when a well-formed URI does not match any resource\n * in the knowledge base.\n */\nexport const RESOURCE_NOT_FOUND = -32002;\n", "// SPDX-License-Identifier: AGPL-3.0-only\n// Copyright (C) 2026 Diko Tech Slave\n\nimport { McpServer } from '../classes/mcp-server.class.ts';\nimport type { McpWorkerClient } from '../typings/mcp-client.interface.ts';\nimport type { AutoCaptureConfig } from '../../auto-capture/typings/auto-capture-config.interface.ts';\nimport { log } from '../../log/functions/log.function.ts';\nimport { LogLevel } from '../../log/typings/log-level.type.ts';\n\n/**\n * Factory that constructs a new `McpServer` bound to the given\n * worker client. Call `server.listen()` on the returned instance\n * to start processing stdio input.\n *\n * @param client - worker client providing knowledge-base operations\n * @param contextPath - absolute path to the `.kbdb` directory\n * @param autoCaptureConfig - optional auto-capture configuration;\n * when provided, the server activates auto-capture on client\n * connection and stops it on disconnect\n * @returns a configured `McpServer` ready to listen\n */\nexport function createMcpServer(\n client: McpWorkerClient,\n contextPath?: string,\n autoCaptureConfig?: AutoCaptureConfig,\n clientFactory?: (() => Promise<McpWorkerClient>) | null,\n maxRetries?: number,\n): McpServer {\n log('creating MCP server', LogLevel.DEBUG);\n return new McpServer(\n client,\n contextPath,\n autoCaptureConfig,\n clientFactory,\n maxRetries,\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["readFileSync", "join", "resolve", "join", "resolve", "candidate", "existsSync", "mkdirSync", "writeFileSync", "join", "resolve", "existsSync", "join", "mkdirSync", "join", "writeFileSync", "resolve", "existsSync", "resolve", "resolve", "resolve", "desc", "findDb", "findDb", "existsSync", "readFileSync", "join", "join", "existsSync", "readFileSync", "resolve", "existsSync", "join", "resolve", "resolve", "join", "existsSync", "existsSync", "join", "tmpdir", "join", "tmpdir", "existsSync", "elapsed", "existsSync", "readFileSync", "unlinkSync", "join", "tmpdir", "dirname", "resolve", "dirname", "resolve", "deps", "createInterface", "readAgentMeta", "handleRecall", "asString", "asStringArray", "handleSearch", "handleLearn", "handleUnlearn", "handleRecall", "handleStatus", "handleContent", "handleCheck", "handleGc", "handleRebuild", "handleExport", "createInterface", "resolve", "join", "readFileSync"]
|
|
7
7
|
}
|