@dikolab/kbdb 0.6.1 → 0.6.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/README.md +33 -6
  2. package/README.md.bak +33 -6
  3. package/dist/README.md +33 -6
  4. package/dist/cli.cjs +663 -218
  5. package/dist/cli.cjs.map +3 -3
  6. package/dist/cli.mjs +663 -218
  7. package/dist/cli.mjs.map +3 -3
  8. package/dist/kbdb-worker.cjs +71 -12
  9. package/dist/kbdb-worker.cjs.map +3 -3
  10. package/dist/mod.cjs +1 -1
  11. package/dist/mod.cjs.map +1 -1
  12. package/dist/mod.mjs +1 -1
  13. package/dist/mod.mjs.map +1 -1
  14. package/dist/src/shared/cli/constants/recfile-field-maps.constant.d.ts +3 -1
  15. package/dist/src/shared/cli/functions/format-command-output.function.d.ts +0 -4
  16. package/dist/src/shared/cli/functions/format-command-text.function.d.ts +1 -0
  17. package/dist/src/shared/cli/functions/format-mcp-output.function.d.ts +5 -4
  18. package/dist/src/shared/cli/functions/format-output.function.d.ts +3 -7
  19. package/dist/src/shared/cli/functions/format-text-output.function.d.ts +3 -2
  20. package/dist/src/shared/cli/functions/run-agent-search.function.d.ts +13 -0
  21. package/dist/src/shared/cli/functions/run-check.function.d.ts +1 -1
  22. package/dist/src/shared/cli/functions/run-content.function.d.ts +18 -14
  23. package/dist/src/shared/cli/functions/run-learn.function.d.ts +6 -11
  24. package/dist/src/shared/cli/functions/run-skill-search.function.d.ts +13 -0
  25. package/dist/src/shared/cli/functions/wrap-mcp-envelope.function.d.ts +8 -0
  26. package/dist/src/shared/cli/typings/cli-options.interface.d.ts +6 -0
  27. package/dist/src/shared/cli/typings/learn-client.interface.d.ts +6 -2
  28. package/dist/src/shared/cli/typings/learn-result.model.d.ts +4 -0
  29. package/dist/src/shared/cli/typings/search-display.model.d.ts +2 -2
  30. package/dist/src/shared/mcp/constants/tool-agent-search.constant.d.ts +3 -0
  31. package/dist/src/shared/mcp/constants/tool-skill-search.constant.d.ts +3 -0
  32. package/dist/src/shared/mcp/functions/format-search-results.function.d.ts +25 -0
  33. package/dist/src/shared/mcp/functions/handle-agent-get.function.d.ts +4 -4
  34. package/dist/src/shared/mcp/functions/handle-agent-list.function.d.ts +3 -7
  35. package/dist/src/shared/mcp/functions/handle-agent-search.function.d.ts +11 -0
  36. package/dist/src/shared/mcp/functions/handle-recall.function.d.ts +1 -1
  37. package/dist/src/shared/mcp/functions/handle-skill-search.function.d.ts +11 -0
  38. package/dist/src/shared/mcp/functions/handle-tool-search.function.d.ts +3 -3
  39. package/dist/src/shared/mcp/typings/mcp-client.interface.d.ts +2 -2
  40. package/dist/src/shared/mcp/typings/mcp-worker-client.interface.d.ts +2 -2
  41. package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
  42. package/dist/src/shared/worker-client/typings/add-section-result.model.d.ts +6 -12
  43. package/dist/src/shared/worker-client/typings/status-result.model.d.ts +2 -2
  44. package/dist/src/shared/worker-daemon/functions/strip-recall-by-depth.function.d.ts +22 -0
  45. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  46. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  47. package/dist/worker.mjs +71 -12
  48. package/dist/worker.mjs.map +3 -3
  49. package/package.json +1 -1
@@ -2,10 +2,6 @@ import type { OutputFormat } from '../typings/cli-options.interface.ts';
2
2
  /**
3
3
  * Formats a command result for the given output format.
4
4
  *
5
- * `'rec'` output is routed through the recfile field map
6
- * registered for `command`; commands without a registered map
7
- * fall back to pretty-printed JSON.
8
- *
9
5
  * @param data - the command result to render
10
6
  * @param format - target output format
11
7
  * @param command - dispatch command name used to look up the
@@ -0,0 +1 @@
1
+ export declare function formatCommandText(data: unknown, command: string): string;
@@ -1,9 +1,10 @@
1
1
  import type { PagedSearchDisplay } from '../typings/search-display.model.ts';
2
2
  /**
3
- * Formats a paged search result as a JSON string compatible
4
- * with the MCP (Model Context Protocol) `text` content block.
3
+ * Formats paged search results as a JSON-RPC 2.0 envelope
4
+ * with a human-readable `text` content block.
5
5
  *
6
6
  * @param paged - paginated search results to serialise
7
- * @returns MCP-compatible JSON string ready for stdout
7
+ * @param content - when true, use full content (preview)
8
+ * instead of snippet
8
9
  */
9
- export declare function formatMcpOutput(paged: PagedSearchDisplay): string;
10
+ export declare function formatMcpOutput(paged: PagedSearchDisplay, content?: boolean): string;
@@ -4,13 +4,9 @@ import type { PagedSearchDisplay } from '../typings/search-display.model.ts';
4
4
  * Serialises a paged search result into the requested output
5
5
  * format string.
6
6
  *
7
- * - `'json'` -- pretty-printed JSON envelope
8
- * - `'text'` -- numbered human-readable list with paging footer
9
- * - `'rec'` -- recfile field records, one per result
10
- * - `'mcp'` -- JSON envelope compatible with MCP protocol
11
- *
12
7
  * @param paged - paginated search results to format
13
8
  * @param format - target output format
14
- * @returns formatted string ready for stdout
9
+ * @param content - when true, display full content instead
10
+ * of snippet
15
11
  */
16
- export declare function formatOutput(paged: PagedSearchDisplay, format: OutputFormat): string;
12
+ export declare function formatOutput(paged: PagedSearchDisplay, format: OutputFormat, content?: boolean): string;
@@ -4,6 +4,7 @@ import type { PagedSearchDisplay } from '../typings/search-display.model.ts';
4
4
  * text list with a paging footer and optional "more" hint.
5
5
  *
6
6
  * @param paged - paginated search results to render
7
- * @returns formatted string ready for stdout
7
+ * @param content - when true, show full content (preview)
8
+ * instead of snippet
8
9
  */
9
- export declare function formatTextOutput(paged: PagedSearchDisplay): string;
10
+ export declare function formatTextOutput(paged: PagedSearchDisplay, content?: boolean): string;
@@ -0,0 +1,13 @@
1
+ import type { CliOptions } from '../typings/cli-options.interface.ts';
2
+ import type { PagedSearchDisplay } from '../typings/search-display.model.ts';
3
+ import type { SearchClient } from './run-search.function.ts';
4
+ /**
5
+ * Runs a search scoped to agent documents.
6
+ *
7
+ * Executes a regular search, then filters results to
8
+ * only include items whose type is `'agent'`.
9
+ *
10
+ * @param client - search client to delegate to
11
+ * @param options - parsed CLI options
12
+ */
13
+ export declare function runAgentSearch(client: SearchClient, options: CliOptions): Promise<PagedSearchDisplay>;
@@ -11,7 +11,7 @@ interface IntegrityError {
11
11
  * - `'type_mismatch'` -- stored MIME type conflicts with content
12
12
  * - `'circular_reference'` -- marker chain contains a cycle
13
13
  */
14
- readonly type: 'checksum_mismatch' | 'orphan_section' | 'orphan_document' | 'broken_reference' | 'type_mismatch' | 'circular_reference';
14
+ readonly type: 'checksum_mismatch' | 'orphan_section' | 'orphan_document' | 'broken_reference' | 'type_mismatch' | 'circular_reference' | 'divergent_content';
15
15
  /** Identifier of the entity (kbid or docid) that has the issue. */
16
16
  readonly entity: string;
17
17
  /** Human-readable description of the specific problem. */
@@ -9,6 +9,14 @@ interface ContentResult {
9
9
  /** Character count of `data` (not byte count). */
10
10
  readonly total: number;
11
11
  }
12
+ /** Minimal search result shape needed to extract kbids. */
13
+ interface SearchHit {
14
+ readonly kbid: string;
15
+ }
16
+ /** Paged search result with items array. */
17
+ interface SearchResult {
18
+ readonly items: readonly SearchHit[];
19
+ }
12
20
  /**
13
21
  * Minimal client interface required by `runContent`.
14
22
  *
@@ -18,28 +26,24 @@ interface ContentResult {
18
26
  * before the content call is made.
19
27
  */
20
28
  export interface ContentClient extends PrefixResolver {
21
- /**
22
- * Composes a rendered Markdown document from one or more kbid
23
- * or docid identifiers.
24
- *
25
- * @param ids - list of kbid or docid identifiers (may be mixed)
26
- * @returns composed Markdown result with character count
27
- */
29
+ /** Composes rendered Markdown from identifiers. */
28
30
  content(ids: string[]): Promise<ContentResult>;
31
+ /** Searches the knowledge base by query. */
32
+ search(params: {
33
+ query: string;
34
+ limit?: number;
35
+ }): Promise<SearchResult>;
29
36
  }
30
37
  /**
31
38
  * Composes and returns a rendered Markdown document from the
32
39
  * identifiers listed in `options.args`.
33
40
  *
34
- * Short kbid prefixes in `options.args` are resolved to full
35
- * identifiers before calling `client.content`. The caller is
36
- * responsible for writing the result to stdout.
41
+ * When `options.search` is set, the args are joined as a
42
+ * search query and results are resolved to kbids before
43
+ * composing content.
37
44
  *
38
45
  * @param client - content client to delegate composition to
39
- * @param options - parsed CLI options whose `args` list the kbid or
40
- * docid identifiers to compose
41
- * @returns the composed content result from the daemon
42
- * @throws when a prefix matches no section or is ambiguous
46
+ * @param options - parsed CLI options
43
47
  */
44
48
  export declare function runContent(client: ContentClient, options: CliOptions): Promise<ContentResult>;
45
49
  export {};
@@ -2,8 +2,12 @@ import type { CliOptions } from '../typings/cli-options.interface.ts';
2
2
  import type { LearnResult } from '../typings/learn-result.model.ts';
3
3
  /** Enriched add-section result returned by the daemon. */
4
4
  interface AddSectionResult {
5
- /** Knowledge-base identifier assigned to the new section. */
6
- readonly kbid: string;
5
+ /** List of knowledge-base identifiers assigned. */
6
+ readonly items: string[];
7
+ /** Number of items in the result set. */
8
+ readonly total: number;
9
+ /** Offset into the result set (always 0 for learn). */
10
+ readonly offset: number;
7
11
  /**
8
12
  * Kbid of the section superseded via `--replace`,
9
13
  * or `null` / `undefined` when none.
@@ -45,16 +49,7 @@ export interface LearnClient {
45
49
  docid?: string;
46
50
  tags?: string[];
47
51
  replace?: boolean;
48
- /**
49
- * Absolute path to the source file. Required for supersession
50
- * via source key when `replace` is `true`.
51
- */
52
52
  sourcePath?: string;
53
- /**
54
- * Hierarchical level (1-6). Explicitly set via `--level`, or
55
- * auto-detected from directory depth. `undefined` means no
56
- * level (the engine defaults to 1).
57
- */
58
53
  level?: number;
59
54
  }): Promise<AddSectionResult>;
60
55
  }
@@ -0,0 +1,13 @@
1
+ import type { CliOptions } from '../typings/cli-options.interface.ts';
2
+ import type { PagedSearchDisplay } from '../typings/search-display.model.ts';
3
+ import type { SearchClient } from './run-search.function.ts';
4
+ /**
5
+ * Runs a search scoped to skill sections.
6
+ *
7
+ * Executes a regular search, then filters results to
8
+ * only include items whose type is `'skill'`.
9
+ *
10
+ * @param client - search client to delegate to
11
+ * @param options - parsed CLI options
12
+ */
13
+ export declare function runSkillSearch(client: SearchClient, options: CliOptions): Promise<PagedSearchDisplay>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Wraps a non-search command result in a JSON-RPC 2.0
3
+ * envelope with a human-readable `text` content block.
4
+ *
5
+ * @param data - raw command result
6
+ * @param command - dispatch command name
7
+ */
8
+ export declare function wrapMcpEnvelope(data: unknown, command: string): string;
@@ -94,6 +94,12 @@ export interface CliOptions {
94
94
  logLevel?: LogLevel;
95
95
  /** Suppresses interactive prompts; uses defaults instead. */
96
96
  nonInteractive?: boolean;
97
+ /**
98
+ * When `true`, the content command resolves identifiers
99
+ * by searching the knowledge base instead of direct
100
+ * kbid/docid lookup.
101
+ */
102
+ search?: boolean;
97
103
  /** Positional arguments following the sub-command. */
98
104
  args: string[];
99
105
  }
@@ -29,8 +29,12 @@ export interface LearnClient {
29
29
  }
30
30
  /** Enriched add-section result returned by the daemon. */
31
31
  export interface LearnAddSectionResult {
32
- /** Knowledge-base identifier assigned to the new section. */
33
- readonly kbid: string;
32
+ /** List of knowledge-base identifiers assigned. */
33
+ readonly items: string[];
34
+ /** Number of items in the result set. */
35
+ readonly total: number;
36
+ /** Offset into the result set (always 0 for learn). */
37
+ readonly offset: number;
34
38
  /**
35
39
  * Kbid of the section superseded via `--replace`,
36
40
  * or `null` / `undefined` when none.
@@ -2,6 +2,10 @@
2
2
  export interface LearnResult {
3
3
  /** Knowledge-base identifier assigned to the ingested section. */
4
4
  kbid: string;
5
+ /** Number of unique terms indexed for this section. */
6
+ indexed_terms_count: number;
7
+ /** Section type used for ingestion. */
8
+ type: string;
5
9
  /** Absolute path to the source file that was ingested. */
6
10
  path: string;
7
11
  /** Size of the file content in bytes (UTF-8 character count). */
@@ -2,8 +2,8 @@
2
2
  export interface SearchDisplay {
3
3
  /** Knowledge-base identifier of the matched section. */
4
4
  kbid: string;
5
- /** Section heading, or null when untitled. */
6
- heading: string | null;
5
+ /** Section heading; falls back to `'(untitled)'`. */
6
+ heading: string;
7
7
  /** MIME type of the section content. */
8
8
  type: string;
9
9
  /** Document IDs this section belongs to. */
@@ -0,0 +1,3 @@
1
+ import type { McpToolDefinition } from '../typings/mcp-types.interface.ts';
2
+ /** MCP tool definition for `agent-search`. */
3
+ export declare const TOOL_AGENT_SEARCH: McpToolDefinition;
@@ -0,0 +1,3 @@
1
+ import type { McpToolDefinition } from '../typings/mcp-types.interface.ts';
2
+ /** MCP tool definition for `skill-search`. */
3
+ export declare const TOOL_SKILL_SEARCH: McpToolDefinition;
@@ -0,0 +1,25 @@
1
+ /** A single search result item, as needed for text formatting. */
2
+ interface FormattableSearchItem {
3
+ readonly kbid: string;
4
+ readonly heading: string | null;
5
+ readonly type: string;
6
+ readonly snippet: string;
7
+ readonly matched_terms: readonly string[];
8
+ }
9
+ /** A page of search results, as needed for text formatting. */
10
+ interface FormattableSearchPage {
11
+ readonly items: readonly FormattableSearchItem[];
12
+ readonly total: number;
13
+ readonly offset: number;
14
+ readonly limit?: number;
15
+ readonly has_more?: boolean;
16
+ }
17
+ /**
18
+ * Formats a search results page as human-readable text for an MCP
19
+ * `text` content block.
20
+ *
21
+ * @param query - the original query string, echoed in the summary
22
+ * @param results - the search results page to format
23
+ */
24
+ export declare function formatSearchResults(query: string, results: FormattableSearchPage): string;
25
+ export {};
@@ -17,13 +17,13 @@ interface ToolCallResult {
17
17
  * Handles the `agent:get` MCP tool call.
18
18
  *
19
19
  * Retrieves an agent document by its `docid`, reads the metadata
20
- * section and skill references, and returns a full `AgentDefinition`.
21
- * Dangling skill references (sections that no longer exist) appear
22
- * with `name: null` in the skills list.
20
+ * section and skill references, and returns the agent's definition
21
+ * as human-readable text. Dangling skill references (sections that
22
+ * no longer exist) are marked as missing in the skills list.
23
23
  *
24
24
  * @param client - the worker client used to execute operations
25
25
  * @param args - tool arguments; must include a `docid` string
26
- * @returns content items containing the serialised `AgentDefinition`
26
+ * @returns content items containing the formatted agent definition
27
27
  */
28
28
  export declare function handleAgentGet(client: McpWorkerClient, args: Record<string, unknown>): Promise<ToolCallResult>;
29
29
  export {};
@@ -17,15 +17,11 @@ interface ToolCallResult {
17
17
  * Handles the `agent:list` MCP tool call.
18
18
  *
19
19
  * Retrieves all documents with `doc_type: 'agent'` and returns a
20
- * summary list containing each agent's document identifier, name,
21
- * and skill count.
22
- *
23
- * The `skillCount` is `Math.max(0, sections.length - 1)` because
24
- * the first section of an agent document always holds the metadata
25
- * JSON and does not count as a skill reference.
20
+ * numbered, human-readable list of each agent's name and
21
+ * description.
26
22
  *
27
23
  * @param client - the worker client used to execute operations
28
- * @returns content items with the serialised agent list
24
+ * @returns content items with the formatted agent list
29
25
  */
30
26
  export declare function handleAgentList(client: McpWorkerClient): Promise<ToolCallResult>;
31
27
  export {};
@@ -0,0 +1,11 @@
1
+ import type { McpWorkerClient } from '../typings/mcp-client.interface.ts';
2
+ import type { ToolCallResult } from '../typings/tool-call-result.model.ts';
3
+ /**
4
+ * Handles the `agent-search` MCP tool call.
5
+ *
6
+ * Performs a search then filters to agent-type results.
7
+ *
8
+ * @param args - tool arguments from the MCP request
9
+ * @param client - the worker client
10
+ */
11
+ export declare function handleAgentSearch(client: McpWorkerClient, args: Record<string, unknown>): Promise<ToolCallResult>;
@@ -22,7 +22,7 @@ interface ToolCallResult {
22
22
  *
23
23
  * @param client - the worker client used to execute the operation
24
24
  * @param args - tool arguments from the MCP request
25
- * @returns content with JSON-stringified recall result, or an error
25
+ * @returns content with human-readable recall text, or an error
26
26
  * content item when required arguments are missing
27
27
  */
28
28
  export declare function handleRecall(client: McpWorkerClient, args: Record<string, unknown>): Promise<ToolCallResult>;
@@ -0,0 +1,11 @@
1
+ import type { McpWorkerClient } from '../typings/mcp-client.interface.ts';
2
+ import type { ToolCallResult } from '../typings/tool-call-result.model.ts';
3
+ /**
4
+ * Handles the `skill-search` MCP tool call.
5
+ *
6
+ * Performs a search then filters to skill-type results.
7
+ *
8
+ * @param args - tool arguments from the MCP request
9
+ * @param client - the worker client
10
+ */
11
+ export declare function handleSkillSearch(client: McpWorkerClient, args: Record<string, unknown>): Promise<ToolCallResult>;
@@ -3,9 +3,9 @@ import type { ToolCallResult } from '../typings/tool-call-result.model.ts';
3
3
  /**
4
4
  * Handles the `search` MCP tool call.
5
5
  *
6
- * Forwards query parameters to the worker client and strips internal
7
- * scoring fields (`score`, `confidence`) from each result item before
8
- * returning.
6
+ * Forwards query parameters to the worker client and renders the
7
+ * results as human-readable text, omitting internal scoring fields
8
+ * (`score`, `confidence`) from the output.
9
9
  *
10
10
  * @param client - the worker client used to execute operations
11
11
  * @param args - tool arguments from the MCP request
@@ -193,8 +193,8 @@ export interface McpWorkerClient {
193
193
  initialized: boolean;
194
194
  /** Absolute path to the context directory the daemon serves. */
195
195
  contextPath: string;
196
- /** In-memory cache statistics. */
197
- cacheStats: {
196
+ /** In-memory cache statistics (absent when not initialized). */
197
+ cacheStats?: {
198
198
  /** Number of content entries currently cached. */
199
199
  contentCount: number;
200
200
  /** Number of index entries currently cached. */
@@ -133,8 +133,8 @@ export interface McpWorkerClient {
133
133
  initialized: boolean;
134
134
  /** Absolute path to the context directory the daemon serves. */
135
135
  contextPath: string;
136
- /** In-memory cache statistics. */
137
- cacheStats: {
136
+ /** In-memory cache statistics (absent when not initialized). */
137
+ cacheStats?: {
138
138
  /** Number of content entries currently cached. */
139
139
  contentCount: number;
140
140
  /** Number of index entries currently cached. */
@@ -1,2 +1,2 @@
1
1
  /** Current package version, kept in sync with package.json. */
2
- export declare const VERSION = "0.6.1";
2
+ export declare const VERSION = "0.6.3";
@@ -11,18 +11,12 @@ export interface NearDuplicateEntry {
11
11
  }
12
12
  /** Result returned by the daemon after adding a new section. */
13
13
  export interface AddSectionResult {
14
- /** Knowledge-base identifier assigned to the section. */
15
- readonly kbid: string;
16
- /**
17
- * Number of unique terms indexed for the section.
18
- * Present in the current binary-decoded response format.
19
- */
20
- readonly indexed_terms_count?: number;
21
- /**
22
- * Wall-clock time the add operation took, in milliseconds.
23
- * Present in the current binary-decoded response format.
24
- */
25
- readonly elapsed_ms?: number;
14
+ /** List of knowledge-base identifiers assigned. */
15
+ readonly items: string[];
16
+ /** Number of items in the result set. */
17
+ readonly total: number;
18
+ /** Offset into the result set (always 0 for learn). */
19
+ readonly offset: number;
26
20
  /**
27
21
  * Knowledge-base identifier of the section that was superseded,
28
22
  * or `null` if no supersession occurred.
@@ -4,8 +4,8 @@ export interface StatusResult {
4
4
  readonly initialized: boolean;
5
5
  /** Absolute path to the context directory the daemon serves. */
6
6
  readonly contextPath: string;
7
- /** In-memory cache statistics. */
8
- readonly cacheStats: {
7
+ /** In-memory cache statistics (absent when daemon is not initialized). */
8
+ readonly cacheStats?: {
9
9
  /** Number of content entries currently cached. */
10
10
  readonly contentCount: number;
11
11
  /** Number of index entries currently cached. */
@@ -0,0 +1,22 @@
1
+ import type { RecallResult } from '../../worker-client/typings/recall-result.model.ts';
2
+ /**
3
+ * Strips depth-dependent fields from a recall result.
4
+ *
5
+ * Depth 0 returns only `kbid`, `heading`, `type`, `content`,
6
+ * and `docids`. Depth 1 adds `documents` and
7
+ * `back_references`. Depth 2+ keeps all fields.
8
+ *
9
+ * @param result - decoded recall result from WASM
10
+ * @param depth - requested recall depth (0-3)
11
+ * @returns recall result with omitted fields removed
12
+ */
13
+ export declare function stripRecallByDepth(result: RecallResult, depth: number): Record<string, unknown>;
14
+ /**
15
+ * Applies depth-based stripping to a single or batch
16
+ * recall result.
17
+ *
18
+ * @param decoded - result from `decodeRecallResult`
19
+ * @param depth - requested recall depth (0-3)
20
+ * @returns the stripped result(s)
21
+ */
22
+ export declare function applyRecallDepth(decoded: RecallResult | RecallResult[], depth: number): unknown;
package/dist/worker.mjs CHANGED
@@ -1743,6 +1743,33 @@ function decodeAddSectionResult(bytes) {
1743
1743
  };
1744
1744
  }
1745
1745
 
1746
+ // src/shared/worker-daemon/functions/strip-recall-by-depth.function.ts
1747
+ function stripRecallByDepth(result, depth) {
1748
+ const base = {
1749
+ kbid: result.kbid,
1750
+ heading: result.heading,
1751
+ type: result.type,
1752
+ content: result.content,
1753
+ docids: result.docids
1754
+ };
1755
+ if (depth >= 1) {
1756
+ base["documents"] = result.documents;
1757
+ base["back_references"] = result.back_references;
1758
+ }
1759
+ if (depth >= 2) {
1760
+ base["siblings"] = result.siblings;
1761
+ base["references"] = result.references;
1762
+ }
1763
+ return base;
1764
+ }
1765
+ function applyRecallDepth(decoded, depth) {
1766
+ if (Array.isArray(decoded)) {
1767
+ const items = decoded.map((r) => stripRecallByDepth(r, depth));
1768
+ return items.length === 1 ? items[0] : items;
1769
+ }
1770
+ return stripRecallByDepth(decoded, depth);
1771
+ }
1772
+
1746
1773
  // src/shared/worker-daemon/classes/worker-daemon.class.ts
1747
1774
  var WASM_METHOD_MAP = {
1748
1775
  search: "worker_search",
@@ -2330,13 +2357,16 @@ var WorkerDaemon = class {
2330
2357
  const semanticType = sectionType === "text" || sectionType === "code" || sectionType === "image" ? sectionType : "text";
2331
2358
  const typeName = sectionType !== semanticType ? sectionType : null;
2332
2359
  const tags = Array.isArray(params["tags"]) ? params["tags"] : [];
2360
+ const title = params["title"] ?? null;
2361
+ const explicitDocid = params["docid"] ?? null;
2362
+ const docid = explicitDocid ?? (typeName && title ? `${typeName}:${title}` : null);
2333
2363
  const input = {
2334
2364
  sectionType: semanticType,
2335
2365
  mimeType: params["mimeType"],
2336
2366
  content: params["content"] ?? "",
2337
- title: params["title"] ?? null,
2367
+ title,
2338
2368
  description: params["description"] ?? null,
2339
- docid: params["docid"] ?? null,
2369
+ docid,
2340
2370
  typeName,
2341
2371
  sourcePath: typeof params["sourcePath"] === "string" ? params["sourcePath"] : void 0,
2342
2372
  sourceMtime: typeof params["sourceMtime"] === "string" ? params["sourceMtime"] : void 0,
@@ -2353,9 +2383,9 @@ var WorkerDaemon = class {
2353
2383
  (d) => ({ ...d, method: "jaccard" })
2354
2384
  );
2355
2385
  return {
2356
- kbid: decoded.kbid,
2357
- indexed_terms_count: decoded.indexedTermsCount,
2358
- elapsed_ms: decoded.elapsedMs,
2386
+ items: [decoded.kbid],
2387
+ total: 1,
2388
+ offset: 0,
2359
2389
  superseded: decoded.superseded,
2360
2390
  warnings: decoded.warnings,
2361
2391
  near_duplicates: nearDups
@@ -2402,6 +2432,7 @@ var WorkerDaemon = class {
2402
2432
  const bytes = this.callWasmSync("worker_compose", encoded);
2403
2433
  const output = decodeComposeOutput(bytes);
2404
2434
  return {
2435
+ type: "text/markdown",
2405
2436
  data: output.markdown,
2406
2437
  total: Number(output.totalChars)
2407
2438
  };
@@ -2469,7 +2500,8 @@ var WorkerDaemon = class {
2469
2500
  const depth = Number(params["depth"] ?? 0);
2470
2501
  const encoded = encodeRecallParams({ kbid, kbids, depth });
2471
2502
  const bytes = this.callWasmSync("worker_recall", encoded);
2472
- return decodeRecallResult(bytes);
2503
+ const decoded = decodeRecallResult(bytes);
2504
+ return applyRecallDepth(decoded, depth);
2473
2505
  }
2474
2506
  // -- Zero-arg methods --
2475
2507
  handleInvalidateAll() {
@@ -2481,17 +2513,44 @@ var WorkerDaemon = class {
2481
2513
  const bytes = this.readReturnSlot();
2482
2514
  const text = new TextDecoder().decode(bytes);
2483
2515
  const kv = decodeKeyValueText(text);
2484
- const mem = this._wasmModules?.memory;
2485
- if (mem) {
2486
- kv["wasm_memory_bytes"] = String(mem.buffer.byteLength);
2487
- }
2488
- return kv;
2516
+ const ctxPath = kv["ctx_path"] || kv["context_path"] || "";
2517
+ return {
2518
+ initialized: kv["initialized"] === "true",
2519
+ context_path: ctxPath,
2520
+ contextPath: ctxPath,
2521
+ document_count: Number(
2522
+ kv["document_count"] || kv["documents"] || 0
2523
+ ),
2524
+ section_count: Number(
2525
+ kv["section_count"] || kv["sections"] || 0
2526
+ ),
2527
+ wasm_memory_bytes: this._wasmModules?.memory.buffer.byteLength ?? 0
2528
+ };
2489
2529
  }
2490
2530
  handleIntegrityCheck() {
2491
2531
  this.callWasmZeroArg("worker_check_integrity");
2492
2532
  const bytes = this.readReturnSlot();
2493
2533
  const text = new TextDecoder().decode(bytes);
2494
- return decodeKeyValueText(text);
2534
+ const kv = decodeKeyValueText(text);
2535
+ const divContent = kv["divergent_content"] || "";
2536
+ const errors = [];
2537
+ if (divContent) {
2538
+ errors.push({
2539
+ type: "divergent_content",
2540
+ entity: divContent,
2541
+ detail: "sections share source key with different content"
2542
+ });
2543
+ }
2544
+ return {
2545
+ type: "integrity",
2546
+ ok: kv["ok"] === "true",
2547
+ sections_checked: Number(kv["sections_checked"] || 0),
2548
+ documents_checked: Number(kv["documents_checked"] || 0),
2549
+ references_checked: Number(kv["references_checked"] || 0),
2550
+ elapsed_ms: Number(kv["elapsed_ms"] || 0),
2551
+ errors,
2552
+ divergent_content: divContent
2553
+ };
2495
2554
  }
2496
2555
  handleGc() {
2497
2556
  const start = Date.now();