@dikolab/kbdb 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLA.md +68 -0
- package/LICENSE +676 -12
- package/LICENSING.md +58 -0
- package/README.md +50 -25
- package/README.md.bak +322 -0
- package/dist/README.md +322 -0
- package/dist/{chunk-BJXEVALU.mjs → chunk-QLJ33C74.mjs} +44 -44
- package/dist/chunk-QLJ33C74.mjs.map +7 -0
- package/dist/cli.cjs +550 -232
- package/dist/cli.cjs.map +4 -4
- package/dist/cli.d.ts +0 -8
- package/dist/cli.mjs +483 -154
- package/dist/cli.mjs.map +4 -4
- package/dist/kbdb-worker.cjs +36 -5
- package/dist/kbdb-worker.cjs.map +3 -3
- package/dist/mod.cjs +89 -30
- package/dist/mod.cjs.map +4 -4
- package/dist/mod.mjs +88 -30
- package/dist/mod.mjs.map +4 -4
- package/dist/src/cli.d.ts +0 -8
- package/dist/src/shared/cli/constants/defaults.constant.d.ts +1 -1
- package/dist/src/shared/cli/constants/recfile-command-field-map.constant.d.ts +8 -0
- package/dist/src/shared/cli/constants/recfile-field-maps.constant.d.ts +21 -0
- package/dist/src/shared/cli/functions/compute-directory-level.function.d.ts +14 -0
- package/dist/src/shared/cli/functions/dispatch-command.function.d.ts +2 -28
- package/dist/src/shared/cli/functions/format-command-output.function.d.ts +14 -0
- package/dist/src/shared/cli/functions/format-db-not-found.function.d.ts +20 -0
- package/dist/src/shared/cli/functions/format-output.function.d.ts +1 -0
- package/dist/src/shared/cli/functions/format-recfile-output.function.d.ts +11 -0
- package/dist/src/shared/cli/functions/render-recfile-value.function.d.ts +11 -0
- package/dist/src/shared/cli/functions/resolve-db-dir.function.d.ts +24 -0
- package/dist/src/shared/cli/functions/resolve-recfile-key.function.d.ts +9 -0
- package/dist/src/shared/cli/functions/run-db-path.function.d.ts +10 -0
- package/dist/src/shared/cli/functions/run-export.function.d.ts +8 -4
- package/dist/src/shared/cli/functions/run-import.function.d.ts +4 -0
- package/dist/src/shared/cli/functions/run-learn.function.d.ts +12 -0
- package/dist/src/shared/cli/index.d.ts +4 -1
- package/dist/src/shared/cli/typings/cli-options.interface.d.ts +9 -2
- package/dist/src/shared/cli/typings/db-resolution.interface.d.ts +9 -0
- package/dist/src/shared/cli/typings/recfile-field-map.type.d.ts +10 -0
- package/dist/src/shared/version/constants/version.constant.d.ts +1 -1
- package/dist/src/shared/wasm-codec/functions/decode-option-u8.function.d.ts +9 -0
- package/dist/src/shared/wasm-codec/functions/decode-section-records.function.d.ts +4 -0
- package/dist/src/shared/wasm-codec/functions/encode-add-section-params.function.d.ts +2 -45
- package/dist/src/shared/wasm-codec/functions/encode-update-section-params.function.d.ts +10 -1
- package/dist/src/shared/wasm-codec/index.d.ts +1 -1
- package/dist/src/shared/wasm-codec/typings/add-section-input.model.d.ts +6 -0
- package/dist/src/shared/wasm-codec/typings/section-record-trailing.model.d.ts +5 -0
- package/dist/src/shared/wasm-codec/typings/section-record.model.d.ts +5 -0
- package/dist/src/shared/worker-client/functions/build-deno-permissions.function.d.ts +11 -0
- package/dist/src/shared/worker-client/functions/read-crash-reason.function.d.ts +9 -0
- package/dist/src/shared/worker-client/functions/resolve-spawn-script.function.d.ts +6 -0
- package/dist/src/shared/worker-client/functions/spawn-daemon.function.d.ts +1 -1
- package/dist/src/shared/worker-client/typings/section.model.d.ts +5 -0
- package/dist/src/shared/worker-client/typings/worker-client-options.interface.d.ts +0 -6
- package/dist/src/shared/worker-daemon/functions/count-files.function.d.ts +12 -0
- package/dist/src/shared/worker-daemon/functions/handle-import.function.d.ts +2 -0
- package/dist/src/shared/worker-daemon/functions/handle-read-ops.function.d.ts +8 -0
- package/dist/src/shared/worker-daemon/functions/validate-daemon-path.function.d.ts +15 -0
- package/dist/src/worker.d.ts +0 -7
- package/dist/wasm/default-embedding/kbdb_default_embedding_bg.wasm +0 -0
- package/dist/wasm/default-embedding/package.json +1 -1
- package/dist/wasm/fs-database/kbdb_fs_database_bg.wasm +0 -0
- package/dist/wasm/fs-database/package.json +1 -1
- package/dist/wasm/fs-migration/package.json +1 -1
- package/dist/wasm/kb-worker/kbdb_worker_bg.wasm +0 -0
- package/dist/wasm/kb-worker/package.json +1 -1
- package/dist/wasm/query-parser/kbdb_query_parser_bg.wasm +0 -0
- package/dist/wasm/query-parser/package.json +1 -1
- package/dist/worker.d.ts +0 -7
- package/dist/worker.mjs +37 -6
- package/dist/worker.mjs.map +3 -3
- package/package.json +11 -10
- package/dist/chunk-BJXEVALU.mjs.map +0 -7
- package/dist/src/shared/cli/functions/resolve-raw-db-path.function.d.ts +0 -10
- package/docs/details/README.md +0 -30
- package/docs/details/agent-tooling.md +0 -132
- package/docs/details/cli.md +0 -777
- package/docs/details/knowledge-base.md +0 -180
- package/docs/details/library-api.md +0 -495
- package/docs/details/mcp-server.md +0 -482
- package/docs/details/search-and-ranking.md +0 -575
- package/docs/details/storage.md +0 -531
- package/docs/goals/agents.md +0 -751
- package/docs/goals/architecture.svg +0 -198
- package/docs/goals/auto-capture.md +0 -378
- package/docs/goals/benchmarking.md +0 -296
- package/docs/goals/cli.md +0 -2654
- package/docs/goals/concurrency.md +0 -259
- package/docs/goals/content-composer.md +0 -609
- package/docs/goals/content-parser.md +0 -279
- package/docs/goals/database.md +0 -1679
- package/docs/goals/document.md +0 -368
- package/docs/goals/hybrid-search.md +0 -465
- package/docs/goals/mcp.md +0 -1541
- package/docs/goals/overview.md +0 -124
- package/docs/goals/query-parser.md +0 -373
- package/docs/goals/query-result.md +0 -860
- package/docs/goals/semantic-dedup.md +0 -233
- package/docs/goals/skills.md +0 -810
- package/docs/goals/sync.md +0 -217
- package/docs/goals/worker-client.md +0 -1005
- package/docs/goals/worker-daemon.md +0 -1547
- package/docs/modules/overview.md +0 -319
- package/docs/modules/rust/embedding/module.md +0 -91
- package/docs/modules/rust/fs-database/functions/document.md +0 -48
- package/docs/modules/rust/fs-database/functions/integrity.md +0 -79
- package/docs/modules/rust/fs-database/functions/io.md +0 -87
- package/docs/modules/rust/fs-database/functions/module.md +0 -22
- package/docs/modules/rust/fs-database/functions/query-exec.md +0 -44
- package/docs/modules/rust/fs-database/functions/section.md +0 -76
- package/docs/modules/rust/fs-database/indexes/btree.md +0 -35
- package/docs/modules/rust/fs-database/indexes/corpus.md +0 -61
- package/docs/modules/rust/fs-database/indexes/inverted.md +0 -60
- package/docs/modules/rust/fs-database/indexes/module.md +0 -64
- package/docs/modules/rust/fs-database/indexes/positional.md +0 -39
- package/docs/modules/rust/fs-database/indexes/vectors.md +0 -110
- package/docs/modules/rust/fs-database/module.md +0 -150
- package/docs/modules/rust/fs-database/types/catalog.md +0 -53
- package/docs/modules/rust/fs-database/types/module.md +0 -12
- package/docs/modules/rust/fs-database/types/section.md +0 -127
- package/docs/modules/rust/kb-worker/functions/compose.md +0 -57
- package/docs/modules/rust/kb-worker/functions/module.md +0 -20
- package/docs/modules/rust/kb-worker/functions/retrieve.md +0 -194
- package/docs/modules/rust/kb-worker/functions/search.md +0 -173
- package/docs/modules/rust/kb-worker/functions/write.md +0 -172
- package/docs/modules/rust/kb-worker/module.md +0 -171
- package/docs/modules/rust/kb-worker/types/cache.md +0 -90
- package/docs/modules/rust/kb-worker/types/context.md +0 -26
- package/docs/modules/rust/kb-worker/types/module.md +0 -16
- package/docs/modules/rust/kb-worker/types/status.md +0 -29
- package/docs/modules/rust/kb-worker/types/token.md +0 -50
- package/docs/modules/rust/overview.md +0 -531
- package/docs/modules/rust/query-parser/functions/extract.md +0 -56
- package/docs/modules/rust/query-parser/functions/module.md +0 -18
- package/docs/modules/rust/query-parser/functions/parse.md +0 -33
- package/docs/modules/rust/query-parser/functions/pipeline.md +0 -9
- package/docs/modules/rust/query-parser/functions/rank.md +0 -85
- package/docs/modules/rust/query-parser/module.md +0 -131
- package/docs/modules/rust/query-parser/types/cache.md +0 -39
- package/docs/modules/rust/query-parser/types/keyphrase.md +0 -71
- package/docs/modules/rust/query-parser/types/module.md +0 -18
- package/docs/modules/rust/query-parser/types/token.md +0 -46
- package/docs/modules/rust/shared/content-composer/functions.md +0 -114
- package/docs/modules/rust/shared/content-composer/module.md +0 -147
- package/docs/modules/rust/shared/content-composer/types.md +0 -93
- package/docs/modules/rust/shared/content-parser/functions.md +0 -72
- package/docs/modules/rust/shared/content-parser/module.md +0 -99
- package/docs/modules/rust/shared/content-parser/types.md +0 -71
- package/docs/modules/rust/shared/corpus/module.md +0 -24
- package/docs/modules/rust/shared/corpus/types.md +0 -141
- package/docs/modules/rust/shared/document/module.md +0 -25
- package/docs/modules/rust/shared/document/types.md +0 -154
- package/docs/modules/rust/shared/encode/module.md +0 -22
- package/docs/modules/rust/shared/encode/traits.md +0 -304
- package/docs/modules/rust/shared/error/module.md +0 -28
- package/docs/modules/rust/shared/error/types.md +0 -302
- package/docs/modules/rust/shared/kbid/module.md +0 -24
- package/docs/modules/rust/shared/kbid/types.md +0 -147
- package/docs/modules/rust/shared/memory/functions.md +0 -209
- package/docs/modules/rust/shared/memory/module.md +0 -24
- package/docs/modules/rust/shared/module.md +0 -196
- package/docs/modules/rust/shared/pipeline/functions.md +0 -141
- package/docs/modules/rust/shared/pipeline/module.md +0 -62
- package/docs/modules/rust/shared/pipeline/types.md +0 -43
- package/docs/modules/rust/shared/query/module.md +0 -27
- package/docs/modules/rust/shared/query/types.md +0 -236
- package/docs/modules/rust/shared/section/module.md +0 -25
- package/docs/modules/rust/shared/section/types.md +0 -294
- package/docs/modules/rust/shared/term/module.md +0 -25
- package/docs/modules/rust/shared/term/types.md +0 -139
- package/docs/modules/typescript/cli.md +0 -131
- package/docs/modules/typescript/kbdb-worker.md +0 -150
- package/docs/modules/typescript/overview.md +0 -400
- package/docs/modules/typescript/shared/auto-capture/module.md +0 -73
- package/docs/modules/typescript/shared/cli/constants.md +0 -23
- package/docs/modules/typescript/shared/cli/functions.md +0 -809
- package/docs/modules/typescript/shared/cli/module.md +0 -138
- package/docs/modules/typescript/shared/cli/typings.md +0 -197
- package/docs/modules/typescript/shared/embedding/functions.md +0 -200
- package/docs/modules/typescript/shared/embedding/module.md +0 -77
- package/docs/modules/typescript/shared/embedding/typings.md +0 -124
- package/docs/modules/typescript/shared/hash/functions.md +0 -20
- package/docs/modules/typescript/shared/hash/module.md +0 -21
- package/docs/modules/typescript/shared/log/constants.md +0 -82
- package/docs/modules/typescript/shared/log/functions.md +0 -131
- package/docs/modules/typescript/shared/log/module.md +0 -153
- package/docs/modules/typescript/shared/log/typings.md +0 -82
- package/docs/modules/typescript/shared/mcp/classes.md +0 -179
- package/docs/modules/typescript/shared/mcp/functions.md +0 -386
- package/docs/modules/typescript/shared/mcp/module.md +0 -160
- package/docs/modules/typescript/shared/mcp/typings.md +0 -529
- package/docs/modules/typescript/shared/module.md +0 -110
- package/docs/modules/typescript/shared/platform/functions.md +0 -42
- package/docs/modules/typescript/shared/platform/module.md +0 -25
- package/docs/modules/typescript/shared/runtime/functions.md +0 -26
- package/docs/modules/typescript/shared/runtime/module.md +0 -27
- package/docs/modules/typescript/shared/runtime/typings.md +0 -13
- package/docs/modules/typescript/shared/version/module.md +0 -27
- package/docs/modules/typescript/shared/wasm-codec/functions.md +0 -391
- package/docs/modules/typescript/shared/wasm-codec/module.md +0 -98
- package/docs/modules/typescript/shared/worker-client/classes.md +0 -264
- package/docs/modules/typescript/shared/worker-client/functions.md +0 -175
- package/docs/modules/typescript/shared/worker-client/module.md +0 -92
- package/docs/modules/typescript/shared/worker-client/typings.md +0 -511
- package/docs/modules/typescript/shared/worker-daemon/classes.md +0 -239
- package/docs/modules/typescript/shared/worker-daemon/constants.md +0 -37
- package/docs/modules/typescript/shared/worker-daemon/functions.md +0 -234
- package/docs/modules/typescript/shared/worker-daemon/module.md +0 -118
- package/docs/modules/typescript/shared/worker-daemon/typings.md +0 -132
- package/docs/overview.md +0 -191
- package/docs/release-notes/0.1.0.md +0 -189
- package/docs/release-notes/0.1.1.md +0 -46
- package/docs/release-notes/0.1.2.md +0 -38
- package/docs/release-notes/0.1.3.md +0 -42
- package/docs/release-notes/0.2.0.md +0 -147
- package/docs/release-notes/0.3.0.md +0 -89
- package/docs/release-notes/0.3.1.md +0 -121
- package/docs/release-notes/0.3.2.md +0 -64
- package/docs/release-notes/0.4.0.md +0 -80
- package/docs/release-notes/0.4.1.md +0 -149
- package/docs/release-notes/0.4.3.md +0 -60
- package/docs/release-notes/0.5.0.md +0 -41
- package/docs/release-notes/README.md +0 -16
|
@@ -1,609 +0,0 @@
|
|
|
1
|
-
# Content Composer -- Content Composition
|
|
2
|
-
|
|
3
|
-
*A composition engine that resolves sections and
|
|
4
|
-
documents from identifiers, processes markers
|
|
5
|
-
recursively, and produces a single rendered Markdown
|
|
6
|
-
document.*
|
|
7
|
-
|
|
8
|
-
## Goal
|
|
9
|
-
|
|
10
|
-
The content composer takes one or more identifiers
|
|
11
|
-
(kbids or docids, mixed) and produces a composed
|
|
12
|
-
Markdown document. It resolves each identifier to
|
|
13
|
-
its sections, follows embedding and link markers
|
|
14
|
-
recursively, and renders everything into a single
|
|
15
|
-
UTF-8 Markdown string with named anchors for
|
|
16
|
-
cross-referencing.
|
|
17
|
-
|
|
18
|
-
This is the **rendering engine** -- it performs what
|
|
19
|
-
the marker descriptions in [Document](document.md)
|
|
20
|
-
specify as "at render time" behaviour. It is distinct
|
|
21
|
-
from the [Content Parser](content-parser.md) (which
|
|
22
|
-
extracts markers as structured data) and the
|
|
23
|
-
[Document](document.md) spec (which defines marker
|
|
24
|
-
syntax and semantics).
|
|
25
|
-
|
|
26
|
-
The rendering logic lives in the `content-composer`
|
|
27
|
-
module in the `kbdb-shared` Rust crate as pure
|
|
28
|
-
composition -- no I/O. Resolution and fetching of
|
|
29
|
-
sections from the database is handled by `kb-worker`.
|
|
30
|
-
|
|
31
|
-
## CLI Command
|
|
32
|
-
|
|
33
|
-
```
|
|
34
|
-
kbdb content <id>... [--db <path>]
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
Compose and output a rendered Markdown document from
|
|
38
|
-
one or more knowledge base identifiers.
|
|
39
|
-
|
|
40
|
-
**Arguments:**
|
|
41
|
-
- `<id>...` -- one or more kbid or docid identifiers.
|
|
42
|
-
The two types can be mixed freely. Each identifier
|
|
43
|
-
is resolved via trial-and-error: the system first
|
|
44
|
-
attempts to look up the identifier as a kbid
|
|
45
|
-
(section); if not found, it tries as a docid
|
|
46
|
-
(document). If neither matches, an error is
|
|
47
|
-
reported for that identifier.
|
|
48
|
-
|
|
49
|
-
**Output:**
|
|
50
|
-
- **stdout**: UTF-8 Markdown text. The composed
|
|
51
|
-
document contains all requested sections and
|
|
52
|
-
documents with markers rendered, named anchors
|
|
53
|
-
assigned, and cross-references linked.
|
|
54
|
-
- **stderr**: errors only.
|
|
55
|
-
|
|
56
|
-
**Exit code:** `0` on success, `1` on error.
|
|
57
|
-
|
|
58
|
-
**Delegation chain:**
|
|
59
|
-
```
|
|
60
|
-
src/cli.ts parseArgs()
|
|
61
|
-
-> ensureDb() / findDb()
|
|
62
|
-
-> createWorkerClient({ contextPath })
|
|
63
|
-
-> runContent(client, options)
|
|
64
|
-
-> client.content(ids)
|
|
65
|
-
-> IPC -> worker daemon
|
|
66
|
-
-> kb-worker.wasm
|
|
67
|
-
-> fs-database.wasm (fetch)
|
|
68
|
-
-> kbdb-shared content-composer
|
|
69
|
-
(compose_content)
|
|
70
|
-
-> stdout
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
## MCP Tool
|
|
74
|
-
|
|
75
|
-
### content
|
|
76
|
-
|
|
77
|
-
Compose a rendered Markdown document from one or
|
|
78
|
-
more kbid or docid identifiers.
|
|
79
|
-
|
|
80
|
-
**Parameters:**
|
|
81
|
-
|
|
82
|
-
| Name | Type | Required | Description |
|
|
83
|
-
|-------|----------|----------|-------------------|
|
|
84
|
-
| `ids` | string[] | yes | One or more kbid or docid identifiers (mixed) |
|
|
85
|
-
|
|
86
|
-
**Returns:** Tool result with text content containing
|
|
87
|
-
JSON:
|
|
88
|
-
|
|
89
|
-
```json
|
|
90
|
-
{
|
|
91
|
-
"type": "text/markdown",
|
|
92
|
-
"data": "<composed markdown>",
|
|
93
|
-
"total": 4567
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
The `total` field is the character count of `data`
|
|
98
|
-
(not byte count).
|
|
99
|
-
|
|
100
|
-
Maps to `client.content()`.
|
|
101
|
-
|
|
102
|
-
## Phase 1 -- Resolve and Gather
|
|
103
|
-
|
|
104
|
-
The resolution phase collects all sections needed
|
|
105
|
-
for composition. This phase runs in `kb-worker`,
|
|
106
|
-
which has access to `fs-database` for lookups.
|
|
107
|
-
|
|
108
|
-
### Step 1: Resolve identifiers
|
|
109
|
-
|
|
110
|
-
For each input identifier:
|
|
111
|
-
|
|
112
|
-
1. Try to find it as a **kbid** (section lookup via
|
|
113
|
-
`fs-database`).
|
|
114
|
-
2. If not found, try to find it as a **docid**
|
|
115
|
-
(document lookup via `fs-database`).
|
|
116
|
-
3. If neither matches, report an error for that
|
|
117
|
-
identifier and skip it.
|
|
118
|
-
|
|
119
|
-
Identifiers are processed in the order given. The
|
|
120
|
-
resolved identifiers form the **main list** -- the
|
|
121
|
-
ordered set of sections and documents that become
|
|
122
|
-
the primary content of the composed Markdown.
|
|
123
|
-
|
|
124
|
-
### Step 2: Expand documents
|
|
125
|
-
|
|
126
|
-
For each resolved docid in the main list, expand it
|
|
127
|
-
to its ordered section kbids. The docid itself is
|
|
128
|
-
retained as a document reference for rendering (see
|
|
129
|
-
Document Rendering below). Its sections join the
|
|
130
|
-
main kbid list in their document-defined order.
|
|
131
|
-
|
|
132
|
-
### Step 3: Deduplicate
|
|
133
|
-
|
|
134
|
-
Remove duplicate kbids from the main list while
|
|
135
|
-
preserving order. If the same kbid appears from
|
|
136
|
-
multiple sources (directly specified and also part
|
|
137
|
-
of a document), the first occurrence wins.
|
|
138
|
-
|
|
139
|
-
### Step 4: Fetch main sections
|
|
140
|
-
|
|
141
|
-
Fetch the content of all main kbids from
|
|
142
|
-
`fs-database`. Each section includes its kbid,
|
|
143
|
-
section type, content body, and optional docid.
|
|
144
|
-
|
|
145
|
-
### Step 5: Extract references recursively
|
|
146
|
-
|
|
147
|
-
For each main section, call `extract_content_markers()`
|
|
148
|
-
from the `content_parser` module to find all markers in
|
|
149
|
-
its
|
|
150
|
-
content. Build a **references** set of unique kbids
|
|
151
|
-
and docids:
|
|
152
|
-
|
|
153
|
-
- **All marker types** add their referenced kbid or
|
|
154
|
-
docid to the references set.
|
|
155
|
-
- **Recursive markers** -- `$(text: {kbid})` and
|
|
156
|
-
`$(document: {docid})` -- follow into the
|
|
157
|
-
referenced content and extract markers from it
|
|
158
|
-
too, recursing until no new references are found.
|
|
159
|
-
- A **visited set** tracks which kbids and docids
|
|
160
|
-
have already been processed to detect and break
|
|
161
|
-
circular references.
|
|
162
|
-
|
|
163
|
-
### Step 6: Fetch reference content
|
|
164
|
-
|
|
165
|
-
Fetch section content for all kbids in the references
|
|
166
|
-
set that are not already fetched (from step 4). For
|
|
167
|
-
docids in the references set, fetch the document
|
|
168
|
-
manifest and its section content.
|
|
169
|
-
|
|
170
|
-
### Step 7: Assign named anchors
|
|
171
|
-
|
|
172
|
-
Assign HTML anchors to every section and document:
|
|
173
|
-
|
|
174
|
-
- Sections: `<a id="{kbid}"></a>`
|
|
175
|
-
- Documents: `<a id="{docid}"></a>`
|
|
176
|
-
|
|
177
|
-
Anchors are assigned to all entities -- main sections,
|
|
178
|
-
reference sections, main documents, and reference
|
|
179
|
-
documents.
|
|
180
|
-
|
|
181
|
-
## Phase 2 -- Content Composition
|
|
182
|
-
|
|
183
|
-
The composition phase takes the pre-fetched sections
|
|
184
|
-
and documents from Phase 1 and produces a Markdown
|
|
185
|
-
string. This phase runs in the `content-composer`
|
|
186
|
-
module in `kbdb-shared` as pure logic -- no I/O.
|
|
187
|
-
|
|
188
|
-
### State
|
|
189
|
-
|
|
190
|
-
The composer maintains two tracking sets:
|
|
191
|
-
|
|
192
|
-
- **`renderedSections`** -- set of kbids that have
|
|
193
|
-
been rendered into the output.
|
|
194
|
-
- **`renderedDocuments`** -- set of docids that have
|
|
195
|
-
been rendered into the output.
|
|
196
|
-
|
|
197
|
-
### Main sections
|
|
198
|
-
|
|
199
|
-
For each kbid in the main list (in order):
|
|
200
|
-
|
|
201
|
-
1. Emit the section's anchor tag:
|
|
202
|
-
`<a id="{kbid}"></a>`
|
|
203
|
-
2. Emit a heading for the section.
|
|
204
|
-
3. Render the section's content body, processing
|
|
205
|
-
any markers found (see Marker Rendering below).
|
|
206
|
-
4. Add the kbid to `renderedSections`.
|
|
207
|
-
|
|
208
|
-
If a main list entry is a docid, render it as a
|
|
209
|
-
document section (see Document Rendering below).
|
|
210
|
-
|
|
211
|
-
### Marker Rendering
|
|
212
|
-
|
|
213
|
-
When processing a section's content body, each
|
|
214
|
-
`$(type: value)` marker is replaced by its rendered
|
|
215
|
-
form:
|
|
216
|
-
|
|
217
|
-
#### `$(image: {kbid})`
|
|
218
|
-
|
|
219
|
-
Replace with an inline image. The referenced section
|
|
220
|
-
must be of type `image/*`. The image data is the
|
|
221
|
-
base64-decoded content of the referenced section.
|
|
222
|
-
|
|
223
|
-
#### `$(code: {kbid})`
|
|
224
|
-
|
|
225
|
-
Replace with a fenced code block. The referenced
|
|
226
|
-
section must be of type `text/*` or
|
|
227
|
-
`application/json`. The language tag is derived from
|
|
228
|
-
the section's MIME type using the mapping in
|
|
229
|
-
[Document -- MIME-to-Language](
|
|
230
|
-
document.md#mime-to-language-mapping).
|
|
231
|
-
|
|
232
|
-
#### `$(text: {kbid})`
|
|
233
|
-
|
|
234
|
-
Render the referenced text section's content
|
|
235
|
-
**inline**. The referenced section's content body
|
|
236
|
-
replaces the marker, and any markers within the
|
|
237
|
-
referenced content are processed recursively.
|
|
238
|
-
|
|
239
|
-
If the kbid is already in the current **render
|
|
240
|
-
stack** (i.e. we are currently in the process of
|
|
241
|
-
rendering it), this is a **cyclic embed**. Instead of
|
|
242
|
-
expanding inline, emit a Markdown link to the
|
|
243
|
-
section's anchor:
|
|
244
|
-
|
|
245
|
-
```
|
|
246
|
-
[{kbid}](#{kbid})
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
The referenced section is added to `renderedSections`
|
|
250
|
-
after its content is fully rendered.
|
|
251
|
-
|
|
252
|
-
#### `$(document: {docid})`
|
|
253
|
-
|
|
254
|
-
Render the referenced document as a **document
|
|
255
|
-
section** (see Document Rendering below).
|
|
256
|
-
|
|
257
|
-
If the docid is already in the current render stack,
|
|
258
|
-
this is a cyclic embed. Emit a Markdown link to the
|
|
259
|
-
document's anchor:
|
|
260
|
-
|
|
261
|
-
```
|
|
262
|
-
[{docid}](#{docid})
|
|
263
|
-
```
|
|
264
|
-
|
|
265
|
-
#### `$(link: {kbid})`
|
|
266
|
-
|
|
267
|
-
Emit a Markdown link pointing to the section's named
|
|
268
|
-
anchor:
|
|
269
|
-
|
|
270
|
-
```
|
|
271
|
-
[{kbid}](#{kbid})
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
The link marker does **not** expand the referenced
|
|
275
|
-
content inline. If the linked section has not been
|
|
276
|
-
rendered yet, it will be rendered at the bottom of
|
|
277
|
-
the document in the remaining references pass.
|
|
278
|
-
|
|
279
|
-
#### `$(doc-link: {docid})`
|
|
280
|
-
|
|
281
|
-
Emit a Markdown link pointing to the document's
|
|
282
|
-
named anchor:
|
|
283
|
-
|
|
284
|
-
```
|
|
285
|
-
[{docid}](#{docid})
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
The link points to the document's container heading,
|
|
289
|
-
not to any individual section within the document.
|
|
290
|
-
If the document has not been rendered yet, it will
|
|
291
|
-
be rendered at the bottom in the remaining
|
|
292
|
-
references pass.
|
|
293
|
-
|
|
294
|
-
## Document Rendering
|
|
295
|
-
|
|
296
|
-
When a document is rendered -- whether from a
|
|
297
|
-
`$(document: {docid})` marker, as a `$(doc-link:)`
|
|
298
|
-
target, or as a main docid input -- it appears as a
|
|
299
|
-
**structural document section** in the Markdown
|
|
300
|
-
output.
|
|
301
|
-
|
|
302
|
-
Structure:
|
|
303
|
-
|
|
304
|
-
1. Emit the document's anchor tag:
|
|
305
|
-
`<a id="{docid}"></a>`
|
|
306
|
-
2. Emit a heading with the document title.
|
|
307
|
-
3. For each section in the document (in position
|
|
308
|
-
order):
|
|
309
|
-
- Emit the section's anchor tag:
|
|
310
|
-
`<a id="{kbid}"></a>`
|
|
311
|
-
- Emit a sub-heading for the section.
|
|
312
|
-
- Render the section's content body with marker
|
|
313
|
-
processing (same rules as Marker Rendering).
|
|
314
|
-
- Add the kbid to `renderedSections`.
|
|
315
|
-
4. Add the docid to `renderedDocuments`.
|
|
316
|
-
|
|
317
|
-
The document heading is the parent; its sections are
|
|
318
|
-
subsections beneath it. `$(doc-link:)` links point to
|
|
319
|
-
the document's anchor (the container heading), giving
|
|
320
|
-
the reader a view of the entire document rather than
|
|
321
|
-
an individual section.
|
|
322
|
-
|
|
323
|
-
If a section within the document contains markers,
|
|
324
|
-
they are processed recursively using the same
|
|
325
|
-
embed/link rules. Cyclic detection uses the same
|
|
326
|
-
render stack.
|
|
327
|
-
|
|
328
|
-
## Remaining References
|
|
329
|
-
|
|
330
|
-
After all main sections and documents have been
|
|
331
|
-
rendered, the composer traverses the references set
|
|
332
|
-
and renders any entities not yet in
|
|
333
|
-
`renderedSections` or `renderedDocuments`.
|
|
334
|
-
|
|
335
|
-
These are typically sections or documents referenced
|
|
336
|
-
by `$(link:)` or `$(doc-link:)` markers whose targets
|
|
337
|
-
were not directly requested or embedded. They appear
|
|
338
|
-
at the bottom of the composed document, each with its
|
|
339
|
-
own anchor and heading.
|
|
340
|
-
|
|
341
|
-
For each unrendered reference:
|
|
342
|
-
|
|
343
|
-
- If it is a kbid: render as a section (anchor +
|
|
344
|
-
heading + content with marker processing).
|
|
345
|
-
- If it is a docid: render as a document section
|
|
346
|
-
(see Document Rendering above).
|
|
347
|
-
|
|
348
|
-
## Cyclic Reference Handling
|
|
349
|
-
|
|
350
|
-
There are two distinct cycle-detection mechanisms:
|
|
351
|
-
|
|
352
|
-
### Resolution cycle detection (Phase 1)
|
|
353
|
-
|
|
354
|
-
During recursive marker extraction (step 5), a
|
|
355
|
-
**visited set** tracks which kbids and docids have
|
|
356
|
-
been processed. If `extract_content_markers()` encounters a
|
|
357
|
-
reference already in the visited set, it stops
|
|
358
|
-
recursing into that reference. This prevents infinite
|
|
359
|
-
loops during the gathering phase.
|
|
360
|
-
|
|
361
|
-
### Render cycle detection (Phase 2)
|
|
362
|
-
|
|
363
|
-
During content composition, a **render stack** tracks
|
|
364
|
-
which kbids and docids are currently being rendered
|
|
365
|
-
(i.e. their content is in the process of expanding).
|
|
366
|
-
If a `$(text:)` or `$(document:)` marker references
|
|
367
|
-
an entity already in the render stack, it is a cyclic
|
|
368
|
-
embed. Instead of expanding inline, the composer
|
|
369
|
-
emits a Markdown link to the entity's anchor.
|
|
370
|
-
|
|
371
|
-
The render stack is distinct from `renderedSections`
|
|
372
|
-
/ `renderedDocuments`. An entity in the render stack
|
|
373
|
-
is currently being expanded (not yet complete). An
|
|
374
|
-
entity in `renderedSections` has been fully rendered
|
|
375
|
-
and will not be rendered again.
|
|
376
|
-
|
|
377
|
-
## Rust Module
|
|
378
|
-
|
|
379
|
-
The composition logic lives in the `content-composer`
|
|
380
|
-
module in the `kbdb-shared` rlib crate.
|
|
381
|
-
|
|
382
|
-
### Module Path
|
|
383
|
-
|
|
384
|
-
```
|
|
385
|
-
engine/crates/shared/src/content-composer/
|
|
386
|
-
├── mod.rs -- re-exports
|
|
387
|
-
├── types.rs -- ComposeRequest, ComposeResult,
|
|
388
|
-
│ RenderedSection
|
|
389
|
-
├── compose.rs -- compose_content()
|
|
390
|
-
└── render.rs -- section and marker rendering
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
Added to `lib.rs`:
|
|
394
|
-
|
|
395
|
-
```rust
|
|
396
|
-
#[path = "content-composer/mod.rs"]
|
|
397
|
-
pub mod content_composer;
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
### Types
|
|
401
|
-
|
|
402
|
-
```rust
|
|
403
|
-
pub struct ComposeRequest {
|
|
404
|
-
pub main_ids: Vec<ResolvedId>,
|
|
405
|
-
pub sections: HashMap<String, SectionData>,
|
|
406
|
-
pub documents: HashMap<String, DocumentData>,
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
pub enum ResolvedId {
|
|
410
|
-
Section(String),
|
|
411
|
-
Document(String),
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
pub struct SectionData {
|
|
415
|
-
pub kbid: String,
|
|
416
|
-
pub section_type: SectionType,
|
|
417
|
-
pub content: String,
|
|
418
|
-
pub markers: Vec<ExtractedContentMarker>,
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
pub struct DocumentData {
|
|
422
|
-
pub docid: String,
|
|
423
|
-
pub title: String,
|
|
424
|
-
pub section_kbids: Vec<String>,
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
pub struct ComposeResult {
|
|
428
|
-
pub markdown: String,
|
|
429
|
-
pub total_chars: usize,
|
|
430
|
-
}
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
### API
|
|
434
|
-
|
|
435
|
-
```rust
|
|
436
|
-
pub fn compose_content(
|
|
437
|
-
request: &ComposeRequest,
|
|
438
|
-
) -> ComposeResult
|
|
439
|
-
```
|
|
440
|
-
|
|
441
|
-
Takes a fully resolved request (all sections and
|
|
442
|
-
documents pre-fetched, markers pre-extracted) and
|
|
443
|
-
returns the composed Markdown string. The function
|
|
444
|
-
is pure -- no I/O, no database access. Resolution
|
|
445
|
-
and fetching are the caller's responsibility
|
|
446
|
-
(`kb-worker`).
|
|
447
|
-
|
|
448
|
-
### Dependencies
|
|
449
|
-
|
|
450
|
-
The module uses sibling modules within `kbdb-shared`:
|
|
451
|
-
|
|
452
|
-
- `content_parser::extract_content_markers()` -- for
|
|
453
|
-
processing markers within referenced content during
|
|
454
|
-
recursive rendering.
|
|
455
|
-
- `content_parser::ContentMarkerType` -- for
|
|
456
|
-
dispatching marker rendering by type.
|
|
457
|
-
- `section::SectionType` -- for type-specific
|
|
458
|
-
rendering (text vs code vs image).
|
|
459
|
-
|
|
460
|
-
## Integration Points
|
|
461
|
-
|
|
462
|
-
### Worker Orchestration
|
|
463
|
-
|
|
464
|
-
The `kb-worker` crate orchestrates the full flow:
|
|
465
|
-
|
|
466
|
-
1. Receives a `content` request with identifiers.
|
|
467
|
-
2. Resolves identifiers via `fs-database` (Phase 1,
|
|
468
|
-
steps 1-3).
|
|
469
|
-
3. Fetches section and document content from
|
|
470
|
-
`fs-database` (steps 4, 6).
|
|
471
|
-
4. Extracts markers recursively using
|
|
472
|
-
`extract_content_markers()` (step 5).
|
|
473
|
-
5. Builds a `ComposeRequest` with all resolved data.
|
|
474
|
-
6. Calls `compose_content()` from `content-composer`.
|
|
475
|
-
7. Returns the `ComposeResult` to the daemon.
|
|
476
|
-
|
|
477
|
-
### Worker Client
|
|
478
|
-
|
|
479
|
-
The `WorkerClient` class exposes a `content()`
|
|
480
|
-
method:
|
|
481
|
-
|
|
482
|
-
```ts
|
|
483
|
-
content(ids: string[]): Promise<ContentResult>;
|
|
484
|
-
```
|
|
485
|
-
|
|
486
|
-
See [Worker Client](worker-client.md) for the full
|
|
487
|
-
interface.
|
|
488
|
-
|
|
489
|
-
### CLI
|
|
490
|
-
|
|
491
|
-
The `runContent()` function in `src/cli.ts` calls
|
|
492
|
-
`client.content(ids)` and writes the resulting
|
|
493
|
-
Markdown string to stdout.
|
|
494
|
-
|
|
495
|
-
See [CLI](cli.md) for the full command specification.
|
|
496
|
-
|
|
497
|
-
### MCP
|
|
498
|
-
|
|
499
|
-
The `handleToolCall()` function routes the `content`
|
|
500
|
-
tool to `client.content(ids)` and wraps the result
|
|
501
|
-
in the MCP tool response format.
|
|
502
|
-
|
|
503
|
-
See [MCP](mcp.md) for the full tool specification.
|
|
504
|
-
|
|
505
|
-
## Example
|
|
506
|
-
|
|
507
|
-
**Input:** `kbdb content abc12345 my-api-guide`
|
|
508
|
-
|
|
509
|
-
Where `abc12345` is a kbid (text section) and
|
|
510
|
-
`my-api-guide` is a docid with two sections
|
|
511
|
-
(`def67890` and `ghi11111`).
|
|
512
|
-
|
|
513
|
-
**Phase 1 resolves:**
|
|
514
|
-
- Main list: `[abc12345, def67890, ghi11111]`
|
|
515
|
-
- `my-api-guide` retained as document reference
|
|
516
|
-
- Markers extracted: `abc12345` contains
|
|
517
|
-
`$(code: jkl22222)` and
|
|
518
|
-
`$(link: mno33333)`
|
|
519
|
-
- References: `{jkl22222, mno33333}`
|
|
520
|
-
|
|
521
|
-
**Phase 2 composes:**
|
|
522
|
-
|
|
523
|
-
```markdown
|
|
524
|
-
<a id="abc12345"></a>
|
|
525
|
-
|
|
526
|
-
## abc12345
|
|
527
|
-
|
|
528
|
-
This section explains the API.
|
|
529
|
-
|
|
530
|
-
Here is the implementation:
|
|
531
|
-
|
|
532
|
-
` ` `ts
|
|
533
|
-
function greet(name: string) {
|
|
534
|
-
return `Hello, ${name}!`;
|
|
535
|
-
}
|
|
536
|
-
` ` `
|
|
537
|
-
|
|
538
|
-
See also: [mno33333](#mno33333).
|
|
539
|
-
|
|
540
|
-
---
|
|
541
|
-
|
|
542
|
-
<a id="my-api-guide"></a>
|
|
543
|
-
|
|
544
|
-
## my-api-guide
|
|
545
|
-
|
|
546
|
-
<a id="def67890"></a>
|
|
547
|
-
|
|
548
|
-
### def67890
|
|
549
|
-
|
|
550
|
-
First section of the API guide...
|
|
551
|
-
|
|
552
|
-
<a id="ghi11111"></a>
|
|
553
|
-
|
|
554
|
-
### ghi11111
|
|
555
|
-
|
|
556
|
-
Second section of the API guide...
|
|
557
|
-
|
|
558
|
-
---
|
|
559
|
-
|
|
560
|
-
<a id="mno33333"></a>
|
|
561
|
-
|
|
562
|
-
## mno33333
|
|
563
|
-
|
|
564
|
-
This section was referenced by a link marker. It
|
|
565
|
-
is rendered here because it was not part of the
|
|
566
|
-
main content or any embedded document.
|
|
567
|
-
```
|
|
568
|
-
|
|
569
|
-
In this example:
|
|
570
|
-
- `abc12345` is a main section with a code embed
|
|
571
|
-
(`jkl22222` rendered as a fenced code block) and
|
|
572
|
-
a link (`mno33333` rendered as a Markdown link).
|
|
573
|
-
- `my-api-guide` is rendered as a document section
|
|
574
|
-
with `def67890` and `ghi11111` as subsections.
|
|
575
|
-
- `mno33333` appears at the bottom as a remaining
|
|
576
|
-
reference (linked but not embedded).
|
|
577
|
-
|
|
578
|
-
## Testing
|
|
579
|
-
|
|
580
|
-
Unit tests for `compose_content()`:
|
|
581
|
-
|
|
582
|
-
- Empty request returns empty markdown.
|
|
583
|
-
- Single text section with no markers.
|
|
584
|
-
- Single section with `$(image:)` marker.
|
|
585
|
-
- Single section with `$(code:)` marker and correct
|
|
586
|
-
language tag.
|
|
587
|
-
- Recursive `$(text:)` embedding.
|
|
588
|
-
- `$(document:)` renders document heading with
|
|
589
|
-
section subsections.
|
|
590
|
-
- Cyclic `$(text:)` embed becomes link to anchor.
|
|
591
|
-
- Cyclic `$(document:)` embed becomes link to
|
|
592
|
-
document anchor.
|
|
593
|
-
- `$(link:)` renders as Markdown link, target
|
|
594
|
-
rendered at bottom.
|
|
595
|
-
- `$(doc-link:)` renders as Markdown link pointing
|
|
596
|
-
to document anchor.
|
|
597
|
-
- Mixed kbids and docids in main list.
|
|
598
|
-
- Named anchors assigned correctly to all entities.
|
|
599
|
-
- `renderedSections` prevents duplicate rendering.
|
|
600
|
-
- `renderedDocuments` prevents duplicate document
|
|
601
|
-
rendering.
|
|
602
|
-
- Remaining references rendered at bottom only for
|
|
603
|
-
unrendered entities.
|
|
604
|
-
- Unicode content preserved through composition.
|
|
605
|
-
|
|
606
|
-
Tests live in the `kbdb-shared` crate:
|
|
607
|
-
`engine/crates/shared/src/content-composer/compose.rs`
|
|
608
|
-
and `engine/crates/shared/src/content-composer/render.rs`
|
|
609
|
-
(inline `#[cfg(test)]` modules).
|