@dikolab/kbdb 0.1.6 → 0.2.0

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 (193) hide show
  1. package/README.md +30 -9
  2. package/dist/cli.cjs +181 -50
  3. package/dist/cli.cjs.map +3 -3
  4. package/dist/cli.mjs +181 -50
  5. package/dist/cli.mjs.map +3 -3
  6. package/dist/kbdb-worker.cjs +283 -29
  7. package/dist/kbdb-worker.cjs.map +4 -4
  8. package/dist/mod.cjs +13 -2
  9. package/dist/mod.cjs.map +2 -2
  10. package/dist/mod.mjs +13 -2
  11. package/dist/mod.mjs.map +2 -2
  12. package/dist/src/shared/cli/functions/format-output.function.d.ts +7 -7
  13. package/dist/src/shared/cli/functions/run-search.function.d.ts +25 -16
  14. package/dist/src/shared/cli/index.d.ts +1 -1
  15. package/dist/src/shared/cli/typings/cli-options.interface.d.ts +2 -0
  16. package/dist/src/shared/cli/typings/search-display.model.d.ts +25 -7
  17. package/dist/src/shared/mcp/functions/handle-recall.function.d.ts +29 -0
  18. package/dist/src/shared/mcp/typings/mcp-client.interface.d.ts +30 -11
  19. package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
  20. package/dist/src/shared/wasm-codec/functions/decode-recall-result.function.d.ts +28 -0
  21. package/dist/src/shared/wasm-codec/functions/decode-scored-results.function.d.ts +14 -7
  22. package/dist/src/shared/wasm-codec/functions/encode-recall-params.function.d.ts +21 -0
  23. package/dist/src/shared/wasm-codec/functions/encode-search-params.function.d.ts +1 -1
  24. package/dist/src/shared/wasm-codec/index.d.ts +5 -2
  25. package/dist/src/shared/worker-client/classes/worker-client.class.d.ts +13 -3
  26. package/dist/src/shared/worker-client/index.d.ts +2 -1
  27. package/dist/src/shared/worker-client/typings/recall-result.model.d.ts +94 -0
  28. package/dist/src/shared/worker-client/typings/search-params.model.d.ts +2 -0
  29. package/dist/src/shared/worker-client/typings/search-result.model.d.ts +23 -7
  30. package/dist/src/shared/worker-daemon/classes/worker-daemon.class.d.ts +1 -0
  31. package/dist/wasm/fs-database/kbdb_fs_database.d.ts +18 -0
  32. package/dist/wasm/fs-database/kbdb_fs_database.js +30 -0
  33. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  34. package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm.d.ts +2 -0
  35. package/dist/wasm/kb-worker/kbdb_worker.d.ts +38 -0
  36. package/dist/wasm/kb-worker/kbdb_worker.js +56 -0
  37. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  38. package/dist/wasm/kb-worker/kbdb_worker_bg.wasm.d.ts +3 -0
  39. package/dist/worker.mjs +283 -29
  40. package/dist/worker.mjs.map +4 -4
  41. package/docs/details/README.md +26 -0
  42. package/docs/details/cli.md +608 -0
  43. package/docs/details/library-api.md +406 -0
  44. package/docs/details/mcp-server.md +430 -0
  45. package/docs/details/search-and-ranking.md +457 -0
  46. package/docs/details/storage.md +529 -0
  47. package/docs/goals/agents.md +751 -0
  48. package/docs/goals/architecture.svg +198 -0
  49. package/docs/goals/cli.md +2308 -0
  50. package/docs/goals/content-composer.md +609 -0
  51. package/docs/goals/content-parser.md +279 -0
  52. package/docs/goals/database.md +1452 -0
  53. package/docs/goals/document.md +368 -0
  54. package/docs/goals/mcp.md +1467 -0
  55. package/docs/goals/overview.md +124 -0
  56. package/docs/goals/query-parser.md +271 -0
  57. package/docs/goals/query-result.md +693 -0
  58. package/docs/goals/skills.md +738 -0
  59. package/docs/goals/worker-client.md +944 -0
  60. package/docs/goals/worker-daemon.md +1447 -0
  61. package/docs/modules/overview.md +298 -0
  62. package/docs/modules/rust/fs-database/functions/document.md +48 -0
  63. package/docs/modules/rust/fs-database/functions/integrity.md +68 -0
  64. package/docs/modules/rust/fs-database/functions/io.md +87 -0
  65. package/docs/modules/rust/fs-database/functions/module.md +22 -0
  66. package/docs/modules/rust/fs-database/functions/query-exec.md +44 -0
  67. package/docs/modules/rust/fs-database/functions/section.md +59 -0
  68. package/docs/modules/rust/fs-database/indexes/btree.md +35 -0
  69. package/docs/modules/rust/fs-database/indexes/corpus.md +61 -0
  70. package/docs/modules/rust/fs-database/indexes/inverted.md +60 -0
  71. package/docs/modules/rust/fs-database/indexes/module.md +64 -0
  72. package/docs/modules/rust/fs-database/indexes/positional.md +39 -0
  73. package/docs/modules/rust/fs-database/module.md +149 -0
  74. package/docs/modules/rust/fs-database/types/catalog.md +53 -0
  75. package/docs/modules/rust/fs-database/types/module.md +12 -0
  76. package/docs/modules/rust/fs-database/types/section.md +101 -0
  77. package/docs/modules/rust/kb-worker/functions/compose.md +57 -0
  78. package/docs/modules/rust/kb-worker/functions/module.md +20 -0
  79. package/docs/modules/rust/kb-worker/functions/retrieve.md +194 -0
  80. package/docs/modules/rust/kb-worker/functions/search.md +173 -0
  81. package/docs/modules/rust/kb-worker/functions/write.md +172 -0
  82. package/docs/modules/rust/kb-worker/module.md +171 -0
  83. package/docs/modules/rust/kb-worker/types/cache.md +90 -0
  84. package/docs/modules/rust/kb-worker/types/context.md +26 -0
  85. package/docs/modules/rust/kb-worker/types/module.md +16 -0
  86. package/docs/modules/rust/kb-worker/types/status.md +29 -0
  87. package/docs/modules/rust/kb-worker/types/token.md +50 -0
  88. package/docs/modules/rust/overview.md +495 -0
  89. package/docs/modules/rust/query-parser/functions/extract.md +56 -0
  90. package/docs/modules/rust/query-parser/functions/module.md +16 -0
  91. package/docs/modules/rust/query-parser/functions/parse.md +33 -0
  92. package/docs/modules/rust/query-parser/functions/pipeline.md +103 -0
  93. package/docs/modules/rust/query-parser/functions/rank.md +85 -0
  94. package/docs/modules/rust/query-parser/module.md +136 -0
  95. package/docs/modules/rust/query-parser/types/cache.md +39 -0
  96. package/docs/modules/rust/query-parser/types/keyphrase.md +60 -0
  97. package/docs/modules/rust/query-parser/types/module.md +17 -0
  98. package/docs/modules/rust/query-parser/types/token.md +42 -0
  99. package/docs/modules/rust/shared/content-composer/functions.md +114 -0
  100. package/docs/modules/rust/shared/content-composer/module.md +147 -0
  101. package/docs/modules/rust/shared/content-composer/types.md +93 -0
  102. package/docs/modules/rust/shared/content-parser/functions.md +72 -0
  103. package/docs/modules/rust/shared/content-parser/module.md +99 -0
  104. package/docs/modules/rust/shared/content-parser/types.md +71 -0
  105. package/docs/modules/rust/shared/corpus/module.md +24 -0
  106. package/docs/modules/rust/shared/corpus/types.md +141 -0
  107. package/docs/modules/rust/shared/document/module.md +25 -0
  108. package/docs/modules/rust/shared/document/types.md +154 -0
  109. package/docs/modules/rust/shared/encode/module.md +22 -0
  110. package/docs/modules/rust/shared/encode/traits.md +304 -0
  111. package/docs/modules/rust/shared/error/module.md +28 -0
  112. package/docs/modules/rust/shared/error/types.md +302 -0
  113. package/docs/modules/rust/shared/kbid/module.md +24 -0
  114. package/docs/modules/rust/shared/kbid/types.md +147 -0
  115. package/docs/modules/rust/shared/memory/functions.md +209 -0
  116. package/docs/modules/rust/shared/memory/module.md +24 -0
  117. package/docs/modules/rust/shared/module.md +168 -0
  118. package/docs/modules/rust/shared/query/module.md +27 -0
  119. package/docs/modules/rust/shared/query/types.md +236 -0
  120. package/docs/modules/rust/shared/section/module.md +25 -0
  121. package/docs/modules/rust/shared/section/types.md +294 -0
  122. package/docs/modules/rust/shared/term/module.md +25 -0
  123. package/docs/modules/rust/shared/term/types.md +139 -0
  124. package/docs/modules/typescript/cli.md +129 -0
  125. package/docs/modules/typescript/kbdb-worker.md +135 -0
  126. package/docs/modules/typescript/overview.md +378 -0
  127. package/docs/modules/typescript/shared/cli/constants.md +23 -0
  128. package/docs/modules/typescript/shared/cli/functions.md +630 -0
  129. package/docs/modules/typescript/shared/cli/module.md +125 -0
  130. package/docs/modules/typescript/shared/cli/typings.md +172 -0
  131. package/docs/modules/typescript/shared/hash/functions.md +20 -0
  132. package/docs/modules/typescript/shared/hash/module.md +21 -0
  133. package/docs/modules/typescript/shared/mcp/classes.md +179 -0
  134. package/docs/modules/typescript/shared/mcp/functions.md +386 -0
  135. package/docs/modules/typescript/shared/mcp/module.md +160 -0
  136. package/docs/modules/typescript/shared/mcp/typings.md +522 -0
  137. package/docs/modules/typescript/shared/module.md +94 -0
  138. package/docs/modules/typescript/shared/platform/functions.md +42 -0
  139. package/docs/modules/typescript/shared/platform/module.md +25 -0
  140. package/docs/modules/typescript/shared/runtime/functions.md +26 -0
  141. package/docs/modules/typescript/shared/runtime/module.md +27 -0
  142. package/docs/modules/typescript/shared/runtime/typings.md +13 -0
  143. package/docs/modules/typescript/shared/version/module.md +27 -0
  144. package/docs/modules/typescript/shared/wasm-codec/functions.md +391 -0
  145. package/docs/modules/typescript/shared/wasm-codec/module.md +98 -0
  146. package/docs/modules/typescript/shared/worker-client/classes.md +264 -0
  147. package/docs/modules/typescript/shared/worker-client/functions.md +175 -0
  148. package/docs/modules/typescript/shared/worker-client/module.md +84 -0
  149. package/docs/modules/typescript/shared/worker-client/typings.md +508 -0
  150. package/docs/modules/typescript/shared/worker-daemon/classes.md +239 -0
  151. package/docs/modules/typescript/shared/worker-daemon/constants.md +37 -0
  152. package/docs/modules/typescript/shared/worker-daemon/functions.md +221 -0
  153. package/docs/modules/typescript/shared/worker-daemon/module.md +112 -0
  154. package/docs/modules/typescript/shared/worker-daemon/typings.md +126 -0
  155. package/docs/overview.md +188 -0
  156. package/docs/release-notes/0.1.0.md +189 -0
  157. package/docs/release-notes/0.1.1.md +46 -0
  158. package/docs/release-notes/0.1.2.md +38 -0
  159. package/docs/release-notes/0.1.3.md +42 -0
  160. package/docs/release-notes/0.2.0.md +147 -0
  161. package/docs/release-notes/README.md +9 -0
  162. package/package.json +8 -2
  163. package/src/shared/cli/functions/dispatch-command.function.ts +3 -3
  164. package/src/shared/cli/functions/format-output.function.ts +41 -34
  165. package/src/shared/cli/functions/parse-args.function.ts +7 -0
  166. package/src/shared/cli/functions/run-search.function.ts +53 -27
  167. package/src/shared/cli/index.ts +4 -1
  168. package/src/shared/cli/typings/cli-options.interface.ts +2 -0
  169. package/src/shared/cli/typings/search-display.model.ts +26 -7
  170. package/src/shared/mcp/functions/create-tool-definitions.function.ts +64 -4
  171. package/src/shared/mcp/functions/handle-recall.function.ts +66 -0
  172. package/src/shared/mcp/functions/handle-tool-call.function.ts +11 -1
  173. package/src/shared/mcp/typings/mcp-client.interface.ts +33 -15
  174. package/src/shared/version/constants/version.constant.ts +1 -1
  175. package/src/shared/wasm-codec/functions/decode-recall-result.function.ts +267 -0
  176. package/src/shared/wasm-codec/functions/decode-scored-results.function.ts +81 -27
  177. package/src/shared/wasm-codec/functions/encode-recall-params.function.ts +68 -0
  178. package/src/shared/wasm-codec/functions/encode-search-params.function.ts +4 -1
  179. package/src/shared/wasm-codec/index.ts +11 -3
  180. package/src/shared/worker-client/classes/worker-client.class.ts +24 -4
  181. package/src/shared/worker-client/index.ts +11 -1
  182. package/src/shared/worker-client/typings/recall-result.model.ts +98 -0
  183. package/src/shared/worker-client/typings/search-params.model.ts +2 -0
  184. package/src/shared/worker-client/typings/search-result.model.ts +24 -7
  185. package/src/shared/worker-daemon/classes/worker-daemon.class.ts +25 -4
  186. package/src/wasm/fs-database/kbdb_fs_database.d.ts +18 -0
  187. package/src/wasm/fs-database/kbdb_fs_database.js +30 -0
  188. package/src/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
  189. package/src/wasm/fs-database/kbdb_fs_database_bg.wasm.d.ts +2 -0
  190. package/src/wasm/kb-worker/kbdb_worker.d.ts +38 -0
  191. package/src/wasm/kb-worker/kbdb_worker.js +56 -0
  192. package/src/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
  193. package/src/wasm/kb-worker/kbdb_worker_bg.wasm.d.ts +3 -0
@@ -0,0 +1,114 @@
1
+ # content-composer -- Functions
2
+
3
+ ## `compose_content`
4
+
5
+ ```rust
6
+ pub fn compose_content(
7
+ request: &ComposeRequest,
8
+ ) -> ComposeResult
9
+ ```
10
+
11
+ Takes a fully resolved request (all sections and
12
+ documents pre-fetched, content markers pre-extracted)
13
+ and returns the composed Markdown string. The
14
+ function is pure -- no I/O, no database access.
15
+ Resolution and fetching are the caller's
16
+ responsibility (`kb-worker`).
17
+
18
+ ### Composition Flow
19
+
20
+ 1. Initialize `renderedSections` and
21
+ `renderedDocuments` tracking sets.
22
+ 2. For each `ResolvedId` in `main_ids` (in order):
23
+ - If `Section(kbid)`: render as a section (anchor
24
+ + heading + content with marker processing), add
25
+ to `renderedSections`.
26
+ - If `Document(docid)`: render as a document
27
+ section (see Document Rendering below), add to
28
+ `renderedDocuments`.
29
+ 3. Traverse the full references set and render any
30
+ entities not yet in `renderedSections` or
31
+ `renderedDocuments` (remaining references, placed
32
+ at the bottom of the output).
33
+ 4. Return `ComposeResult` with the composed Markdown
34
+ and character count.
35
+
36
+ ### Content Marker Rendering
37
+
38
+ Each `$(type: value)` content marker in a section's
39
+ body is replaced by its rendered form:
40
+
41
+ | Marker | Rendered output |
42
+ |--------------------|-----------------------------------|
43
+ | `$(image: {kbid})` | Inline image (base64-decoded content from referenced `image/*` section) |
44
+ | `$(code: {kbid})` | Fenced code block with language tag derived from MIME type |
45
+ | `$(text: {kbid})` | Inline expansion of referenced section content (recursive, with cycle detection) |
46
+ | `$(document: {docid})` | Document section rendering (heading + subsections, recursive) |
47
+ | `$(link: {kbid})` | Markdown link `[{kbid}](#{kbid})` (no inline expansion) |
48
+ | `$(doc-link: {docid})` | Markdown link `[{docid}](#{docid})` (no inline expansion) |
49
+
50
+ Cyclic `$(text:)` and `$(document:)` embeds (entity
51
+ already in the render stack) are rendered as Markdown
52
+ links to the entity's anchor instead of expanding
53
+ inline.
54
+
55
+ ### MIME-to-Language Mapping
56
+
57
+ For `$(code:)` markers, the fenced code block
58
+ language tag is derived from the referenced section's
59
+ MIME type:
60
+
61
+ | MIME type | Language tag |
62
+ |------------------------|-------------|
63
+ | `text/typescript` | `ts` |
64
+ | `text/javascript` | `js` |
65
+ | `text/html` | `html` |
66
+ | `text/css` | `css` |
67
+ | `text/xml` | `xml` |
68
+ | `text/plain` | *(none)* |
69
+ | `application/json` | `json` |
70
+ | other `text/*` | subtype |
71
+
72
+ ### Document Rendering
73
+
74
+ When a document is rendered (from `$(document:)`
75
+ marker, `$(doc-link:)` target, or main docid input):
76
+
77
+ 1. Emit document anchor: `<a id="{docid}"></a>`
78
+ 2. Emit heading with document title.
79
+ 3. For each section in the document (position order):
80
+ - Emit section anchor: `<a id="{kbid}"></a>`
81
+ - Emit sub-heading.
82
+ - Render section content with marker processing.
83
+ - Add kbid to `renderedSections`.
84
+ 4. Add docid to `renderedDocuments`.
85
+
86
+ ### Tests
87
+
88
+ Unit tests in
89
+ `engine/crates/shared/src/content-composer/compose.rs`
90
+ and `render.rs`:
91
+
92
+ - Empty request returns empty markdown.
93
+ - Single text section with no markers.
94
+ - Single section with `$(image:)` marker.
95
+ - Single section with `$(code:)` marker and correct
96
+ language tag.
97
+ - Recursive `$(text:)` embedding.
98
+ - `$(document:)` renders document heading with
99
+ section subsections.
100
+ - Cyclic `$(text:)` embed becomes link to anchor.
101
+ - Cyclic `$(document:)` embed becomes link to
102
+ document anchor.
103
+ - `$(link:)` renders as Markdown link, target
104
+ rendered at bottom.
105
+ - `$(doc-link:)` renders as Markdown link pointing
106
+ to document anchor.
107
+ - Mixed kbids and docids in main list.
108
+ - Named anchors assigned correctly to all entities.
109
+ - `renderedSections` prevents duplicate rendering.
110
+ - `renderedDocuments` prevents duplicate document
111
+ rendering.
112
+ - Remaining references rendered at bottom only for
113
+ unrendered entities.
114
+ - Unicode content preserved through composition.
@@ -0,0 +1,147 @@
1
+ # content-composer -- Content Composition
2
+
3
+ *Composition engine that resolves sections and
4
+ documents from identifiers, processes content markers
5
+ recursively, and produces a single rendered Markdown
6
+ document.*
7
+
8
+ ## Module
9
+
10
+ | Field | Value |
11
+ |-------------|----------------------------------------------|
12
+ | Rust module | `content_composer` |
13
+ | Source path | `engine/crates/shared/src/content-composer/` |
14
+ | Crate | `kbdb-shared` (rlib) |
15
+
16
+ The module is declared in `lib.rs` with a path
17
+ attribute because the source directory uses a
18
+ hyphenated name:
19
+
20
+ ```rust
21
+ #[path = "content-composer/mod.rs"]
22
+ pub mod content_composer;
23
+ ```
24
+
25
+ ## Directory Layout
26
+
27
+ ```
28
+ engine/crates/shared/src/content-composer/
29
+ mod.rs -- re-exports
30
+ types.rs -- ComposeRequest, ComposeResult,
31
+ RenderedSection
32
+ compose.rs -- compose_content()
33
+ render.rs -- section and marker rendering
34
+ ```
35
+
36
+ ## Purpose
37
+
38
+ The content creator takes one or more identifiers
39
+ (kbids or docids, mixed) and produces a composed
40
+ Markdown document. It resolves each identifier to its
41
+ sections, follows embedding and link content markers
42
+ recursively, and renders everything into a single
43
+ UTF-8 Markdown string with named anchors for
44
+ cross-referencing.
45
+
46
+ The rendering logic is **pure composition** -- no
47
+ I/O, no database access. Resolution and fetching of
48
+ sections from the database is handled by `kb-worker`
49
+ before calling into this module.
50
+
51
+ ## Two-Phase Composition
52
+
53
+ ### Phase 1 -- Resolve and Gather (kb-worker)
54
+
55
+ 1. Resolve identifiers (try kbid, then docid)
56
+ 2. Expand documents to section kbids
57
+ 3. Deduplicate while preserving order
58
+ 4. Fetch main sections from fs-database
59
+ 5. Extract content markers recursively using
60
+ `extract_content_markers()` from content-parser
61
+ 6. Fetch reference content
62
+ 7. Assign HTML named anchors
63
+
64
+ ### Phase 2 -- Content Composition (this module)
65
+
66
+ Takes the pre-fetched `ComposeRequest` and produces
67
+ a Markdown string. Processes content markers in
68
+ section bodies, rendering each by type (see
69
+ [functions.md](functions.md) for rendering rules).
70
+
71
+ ## Cycle Detection
72
+
73
+ Two distinct mechanisms prevent infinite loops:
74
+
75
+ - **Resolution cycle detection** (Phase 1): a visited
76
+ set tracks which kbids and docids have been
77
+ processed during recursive marker extraction.
78
+ - **Render cycle detection** (Phase 2): a render
79
+ stack tracks which entities are currently being
80
+ expanded. If a `$(text:)` or `$(document:)` marker
81
+ references an entity already in the render stack,
82
+ it is a cyclic embed -- rendered as a Markdown link
83
+ to the entity's anchor instead of expanding inline.
84
+
85
+ The render stack is distinct from the
86
+ `renderedSections` / `renderedDocuments` tracking
87
+ sets. An entity in the render stack is currently
88
+ being expanded (not yet complete). An entity in
89
+ `renderedSections` has been fully rendered and will
90
+ not be rendered again.
91
+
92
+ ## Dependencies
93
+
94
+ Sibling modules within `kbdb-shared`:
95
+
96
+ - `content_parser::extract_content_markers()` -- for
97
+ processing markers within referenced content during
98
+ recursive rendering.
99
+ - `content_parser::ContentMarkerType` -- for
100
+ dispatching marker rendering by type.
101
+ - `section::SectionType` -- for type-specific
102
+ rendering (text vs code vs image).
103
+
104
+ ## Integration Points
105
+
106
+ ### Worker Orchestration
107
+
108
+ The `kb-worker` crate orchestrates the full flow:
109
+ receives a `compose` IPC request, resolves
110
+ identifiers via `fs-database`, fetches content,
111
+ extracts content markers recursively, builds a
112
+ `ComposeRequest`, and calls `compose_content()`.
113
+ See [compose](../../kb-worker/functions/compose.md).
114
+
115
+ ### Worker Client
116
+
117
+ `WorkerClient.content(ids)` sends the `compose` IPC
118
+ method to the daemon and returns a `ContentResult`.
119
+
120
+ ### CLI
121
+
122
+ `runContent(client, options)` calls
123
+ `client.content(ids)` and writes the composed
124
+ Markdown to stdout. Command: `kbdb content <id>...`
125
+
126
+ ### MCP
127
+
128
+ The `content` MCP tool routes to
129
+ `client.content(ids)` and wraps the result in the
130
+ MCP tool response format.
131
+
132
+ ## Sub-documents
133
+
134
+ - [types.md](types.md) -- `ComposeRequest`,
135
+ `ComposeResult`, `ResolvedId`, `SectionData`,
136
+ `DocumentData`, `RenderedSection`
137
+ - [functions.md](functions.md) --
138
+ `compose_content()`
139
+
140
+ ## Testing
141
+
142
+ Tests live inline in
143
+ `engine/crates/shared/src/content-composer/compose.rs`
144
+ and
145
+ `engine/crates/shared/src/content-composer/render.rs`
146
+ (`#[cfg(test)]` modules). See
147
+ [functions.md](functions.md) for test descriptions.
@@ -0,0 +1,93 @@
1
+ # content-composer -- Types
2
+
3
+ ## `ComposeRequest`
4
+
5
+ Input to the composition engine. Contains all
6
+ pre-fetched data needed to produce the composed
7
+ Markdown -- no I/O occurs during composition.
8
+
9
+ ```rust
10
+ pub struct ComposeRequest {
11
+ pub main_ids: Vec<ResolvedId>,
12
+ pub sections: HashMap<String, SectionData>,
13
+ pub documents: HashMap<String, DocumentData>,
14
+ }
15
+ ```
16
+
17
+ | Field | Description |
18
+ |-------------|------------------------------------------|
19
+ | `main_ids` | Ordered list of resolved identifiers forming the primary content |
20
+ | `sections` | All pre-fetched sections, keyed by kbid |
21
+ | `documents` | All pre-fetched documents, keyed by docid|
22
+
23
+ ## `ResolvedId`
24
+
25
+ Discriminated identifier from the resolution phase.
26
+
27
+ ```rust
28
+ pub enum ResolvedId {
29
+ Section(String),
30
+ Document(String),
31
+ }
32
+ ```
33
+
34
+ ## `SectionData`
35
+
36
+ Pre-fetched section content with extracted content
37
+ markers.
38
+
39
+ ```rust
40
+ pub struct SectionData {
41
+ pub kbid: String,
42
+ pub section_type: SectionType,
43
+ pub content: String,
44
+ pub markers: Vec<ExtractedContentMarker>,
45
+ }
46
+ ```
47
+
48
+ | Field | Description |
49
+ |----------------|---------------------------------------|
50
+ | `kbid` | Content-addressed section identifier |
51
+ | `section_type` | MIME-based type (`SectionType` from `section` module) |
52
+ | `content` | Raw section body text |
53
+ | `markers` | Pre-extracted content markers from `extract_content_markers()` |
54
+
55
+ ## `DocumentData`
56
+
57
+ Pre-fetched document manifest.
58
+
59
+ ```rust
60
+ pub struct DocumentData {
61
+ pub docid: String,
62
+ pub title: String,
63
+ pub section_kbids: Vec<String>,
64
+ }
65
+ ```
66
+
67
+ | Field | Description |
68
+ |----------------|---------------------------------------|
69
+ | `docid` | Document identifier |
70
+ | `title` | Document title for heading rendering |
71
+ | `section_kbids`| Ordered section kbids in this document|
72
+
73
+ ## `ComposeResult`
74
+
75
+ Output of the composition engine.
76
+
77
+ ```rust
78
+ pub struct ComposeResult {
79
+ pub markdown: String,
80
+ pub total_chars: usize,
81
+ }
82
+ ```
83
+
84
+ | Field | Description |
85
+ |--------------|-----------------------------------------|
86
+ | `markdown` | Composed Markdown string |
87
+ | `total_chars` | Character count of `markdown` (not byte count) |
88
+
89
+ ## `RenderedSection`
90
+
91
+ Internal rendering type used by `render.rs` during
92
+ Phase 2 composition. Tracks per-section rendering
93
+ state.
@@ -0,0 +1,72 @@
1
+ # content-parser -- Functions
2
+
3
+ ## `extract_content_markers`
4
+
5
+ ```rust
6
+ pub fn extract_content_markers(text: &str)
7
+ -> Vec<ExtractedContentMarker>
8
+ ```
9
+
10
+ Scans the input text and returns all recognized
11
+ content markers in document order (lowest to highest
12
+ byte offset). Does not modify the input. Returns an
13
+ empty `Vec` if no markers are found.
14
+
15
+ The function performs a single left-to-right scan.
16
+ It is non-recursive -- it does not follow references
17
+ or read other sections.
18
+
19
+ ### Tests
20
+
21
+ Unit tests in
22
+ `engine/crates/shared/src/content-parser/extract.rs`:
23
+
24
+ - Empty input returns empty vec.
25
+ - Single `$(image: {kbid})` returns one marker with
26
+ correct type, value, offset, and length.
27
+ - All six content marker types recognized
28
+ individually.
29
+ - Multiple markers in sequence, returned in document
30
+ order.
31
+ - Adjacent markers with no space between them.
32
+ - Unrecognized `$(formula: ...)` produces no marker.
33
+ - Unclosed marker (no `)`) produces no marker.
34
+ - Unicode text surrounding markers -- offsets are
35
+ byte-accurate.
36
+ - Marker-only input (no surrounding text).
37
+ - Whitespace variations inside markers (e.g. extra
38
+ spaces after colon).
39
+
40
+ ## `strip_content_markers`
41
+
42
+ ```rust
43
+ pub fn strip_content_markers(text: &str) -> String
44
+ ```
45
+
46
+ Returns a new string with all recognized content
47
+ markers removed. Whitespace left by marker removal
48
+ is preserved; the caller should normalise whitespace
49
+ if needed.
50
+
51
+ This function replaces the earlier implementation in
52
+ `query-parser/src/pipeline/markers.rs`, which only
53
+ recognized `$(image:)` and `$(code:)`. The shared
54
+ version recognizes all six content marker types.
55
+
56
+ Both functions share the same scanning logic
57
+ internally. `strip_content_markers` is equivalent to
58
+ removing every character range identified by
59
+ `extract_content_markers`.
60
+
61
+ ### Tests
62
+
63
+ Unit tests in
64
+ `engine/crates/shared/src/content-parser/strip.rs`:
65
+
66
+ - Empty input returns empty string.
67
+ - Plain text with no markers returns unchanged.
68
+ - All six content marker types stripped.
69
+ - Multiple markers stripped in one pass.
70
+ - Unrecognized markers left untouched.
71
+ - Unclosed markers left untouched.
72
+ - Unicode text preserved around stripped markers.
@@ -0,0 +1,99 @@
1
+ # content-parser -- Content Marker Extraction
2
+
3
+ *Format-agnostic parser that extracts `$(type: value)`
4
+ embedding and link markers from section content,
5
+ producing structured reference lists for result set
6
+ resolution.*
7
+
8
+ ## Module
9
+
10
+ | Field | Value |
11
+ |-------------|-------------------------------------------|
12
+ | Rust module | `content_parser` |
13
+ | Source path | `engine/crates/shared/src/content-parser/`|
14
+ | Crate | `kbdb-shared` (rlib) |
15
+
16
+ The module is declared in `lib.rs` with a path
17
+ attribute because the source directory uses a
18
+ hyphenated name:
19
+
20
+ ```rust
21
+ #[path = "content-parser/mod.rs"]
22
+ pub mod content_parser;
23
+ ```
24
+
25
+ ## Directory Layout
26
+
27
+ ```
28
+ engine/crates/shared/src/content-parser/
29
+ mod.rs -- re-exports
30
+ types.rs -- ContentMarkerType,
31
+ ExtractedContentMarker
32
+ extract.rs -- extract_content_markers()
33
+ strip.rs -- strip_content_markers()
34
+ ```
35
+
36
+ ## Purpose
37
+
38
+ The content parser scans any UTF-8 text for
39
+ `$(type: value)` markers and returns a structured
40
+ list of extracted references. It is format-agnostic
41
+ -- the marker syntax is independent of the
42
+ surrounding text format (markdown, source code,
43
+ plain text).
44
+
45
+ The parser performs a **single left-to-right scan**
46
+ of the input. It is **non-recursive** -- it does not
47
+ follow references or read other sections. Recursive
48
+ reference resolution is the caller's responsibility
49
+ (typically `kb-worker`).
50
+
51
+ ## Integration Points
52
+
53
+ ### Query Parser
54
+
55
+ The `query-parser` crate imports
56
+ `strip_content_markers()` from
57
+ `kbdb_shared::content_parser` for tokenization
58
+ Pipeline Stage 1. This replaces the crate's earlier
59
+ local regex that only recognized `$(image:)` and
60
+ `$(code:)`. The shared version recognizes all six
61
+ content marker types.
62
+
63
+ ### Filesystem Database
64
+
65
+ The `fs-database` crate imports
66
+ `extract_content_markers()` from
67
+ `kbdb_shared::content_parser` for integrity
68
+ checking. The integrity checker extracts all markers
69
+ and verifies that each referenced kb-id or doc-id
70
+ exists and has the expected type.
71
+
72
+ ### Worker Orchestration
73
+
74
+ The `kb-worker` crate imports
75
+ `extract_content_markers()` from
76
+ `kbdb_shared::content_parser` to build the
77
+ `references` array in result sets. When a search
78
+ or retrieval request returns sections, `kb-worker`
79
+ scans each section's content, follows `$(text:)` and
80
+ `$(document:)` references recursively using a visited
81
+ set, and returns a flat deduplicated `references`
82
+ array alongside the primary result data.
83
+
84
+ ## Sub-documents
85
+
86
+ - [types.md](types.md) -- `ContentMarkerType`,
87
+ `ExtractedContentMarker`
88
+ - [functions.md](functions.md) --
89
+ `extract_content_markers()`,
90
+ `strip_content_markers()`
91
+
92
+ ## Testing
93
+
94
+ Tests live inline in
95
+ `engine/crates/shared/src/content-parser/extract.rs`
96
+ and
97
+ `engine/crates/shared/src/content-parser/strip.rs`
98
+ (`#[cfg(test)]` modules). See
99
+ [functions.md](functions.md) for test descriptions.
@@ -0,0 +1,71 @@
1
+ # content-parser -- Types
2
+
3
+ ## `ContentMarkerType`
4
+
5
+ Enum identifying the six recognized content marker
6
+ types.
7
+
8
+ ```rust
9
+ pub enum ContentMarkerType {
10
+ /// `$(image: {kbid})` -- image section embedding.
11
+ Image,
12
+ /// `$(code: {kbid})` -- code section embedding.
13
+ Code,
14
+ /// `$(text: {kbid})` -- text section embedding.
15
+ Text,
16
+ /// `$(document: {docid})` -- document embedding.
17
+ Document,
18
+ /// `$(link: {kbid})` -- section cross-reference.
19
+ Link,
20
+ /// `$(doc-link: {docid})` -- document
21
+ /// cross-reference.
22
+ DocLink,
23
+ }
24
+ ```
25
+
26
+ Each variant maps to a `$(type:` prefix:
27
+
28
+ | Variant | Prefix | Value type |
29
+ |------------|----------------|------------|
30
+ | `Image` | `$(image:` | kbid |
31
+ | `Code` | `$(code:` | kbid |
32
+ | `Text` | `$(text:` | kbid |
33
+ | `Document` | `$(document:` | docid |
34
+ | `Link` | `$(link:` | kbid |
35
+ | `DocLink` | `$(doc-link:` | docid |
36
+
37
+ ## `ExtractedContentMarker`
38
+
39
+ A single marker extracted from text content.
40
+
41
+ ```rust
42
+ pub struct ExtractedContentMarker {
43
+ /// The marker category.
44
+ pub marker_type: ContentMarkerType,
45
+ /// The value inside the marker (kb-id or doc-id).
46
+ pub value: String,
47
+ /// Byte offset of the marker start (`$`) in the
48
+ /// original text.
49
+ pub offset: usize,
50
+ /// Byte length of the entire marker, including
51
+ /// the `$(` and `)` delimiters.
52
+ pub length: usize,
53
+ }
54
+ ```
55
+
56
+ ## Syntax Rules
57
+
58
+ Content markers follow these parsing rules:
59
+
60
+ 1. A marker starts with `$(` and ends with the next
61
+ `)`.
62
+ 2. The type identifier is matched against the six
63
+ recognized prefixes listed above.
64
+ 3. Unrecognized prefixes (e.g. `$(formula:`) are
65
+ **skipped** -- no `ExtractedContentMarker` is
66
+ produced.
67
+ 4. Unclosed markers (no closing `)` before end of
68
+ input) are **skipped**.
69
+ 5. The value is the text between the colon-space and
70
+ the closing `)`, trimmed of leading and trailing
71
+ whitespace.
@@ -0,0 +1,24 @@
1
+ # corpus -- Corpus Statistics
2
+
3
+ *Lightweight corpus statistics passed between modules
4
+ for IDF computation and BM25F length normalization.*
5
+
6
+ ## Source
7
+
8
+ `engine/crates/shared/src/corpus/`
9
+
10
+ ## Responsibility
11
+
12
+ Defines the lightweight `CorpusStats` view passed
13
+ from `fs-database` to `query-parser` via `kb-worker`
14
+ for ranking computations. Contains only the scalar
15
+ values needed for BM25F -- the full document
16
+ frequency map stays private to `fs-database`.
17
+
18
+ See [Query Parser -- Ranking](
19
+ ../../../../goals/query-parser.md) for how these
20
+ values are used in BM25F scoring.
21
+
22
+ ## Exports
23
+
24
+ - **[types.md](types.md)** -- `CorpusStats`.