@msareen/knowledge-hub-builder 0.1.5 → 0.1.7

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/AGENTS.md CHANGED
@@ -158,6 +158,10 @@ The single exception is a hub with nothing to choose between: with no bundles at
158
158
  unnamed ingest lands in `default`, created on the spot, and where `default` is the only
159
159
  bundle it lands there as it stands.
160
160
 
161
+ When a run finishes, **offer the catalog pass** for the bundle just ingested — report what
162
+ landed and how many rows are uncurated, then ask before curating anything. Neither stopping
163
+ silently at the summary nor cataloging unasked is right.
164
+
161
165
  **Catalog** (`skills/catalog/SKILL.md`) is the judgement half, one bundle at a time: read
162
166
  each `raw/` file, split it into concepts, give each OKF frontmatter, link them, register
163
167
  them in `index.md`. When the runtime supports parallel agents, fan them out over the raw
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # knowledge-hub-builder
2
2
 
3
3
  <p align="center">
4
- <img src="images/demo.gif" alt="KHB creates a hub, ingests sources, routes a question to a concept, and validates the result" width="544">
4
+ <img src="images/demo.gif" alt="khb init in the shell, then an agent session: the ingest skill asks which bundle owns the material, runs khb ingest as a tool call, offers to catalog, writes the concept docs, then answers a question from them" width="600">
5
5
  </p>
6
6
 
7
7
  **KHB (Knowledge Hub Builder)** is a local, markdown-based knowledge base maintained with
@@ -69,20 +69,25 @@ after ingestion.
69
69
  `khb ingest <bundle>` reads `sources.yaml` and writes extracted markdown under
70
70
  `bundles/<bundle>/raw/`.
71
71
 
72
- Supported without additional system tools:
72
+ Supported out of the box, with no system tools and no further installation:
73
73
 
74
74
  - text, markdown, CSV, JSON, and YAML
75
75
  - PDF and DOCX
76
76
  - ODT, XLSX, and PPTX
77
+ - OCR for images and scanned PDFs, applied automatically when a PDF has no text layer
77
78
 
78
- Optional local tools add:
79
+ OCR ships with KHB: `@hyzyla/pdfium`, `sharp`, and `tesseract.js` are ordinary dependencies,
80
+ so installing KHB pulls them down whether or not you ever ingest a scan. That costs roughly
81
+ 75 MB of WASM plus `sharp`'s native binaries — the price of an ingest that never stalls
82
+ waiting for a setup step.
79
83
 
80
- - OCR for images and scanned PDFs: `@hyzyla/pdfium`, `sharp`, and `tesseract.js`
81
- - audio and video transcription: a `whisper` or `faster-whisper` executable on `PATH`
84
+ One extractor is genuinely optional:
82
85
 
83
- If an optional extractor is missing, KHB leaves a pending row in `log.md` and prints the
84
- required setup. OCR packages must be installed where the KHB package resolves modules; the
85
- CLI prints that location.
86
+ - audio and video transcription needs a `whisper` or `faster-whisper` executable on `PATH`
87
+ (`pip install -U openai-whisper`)
88
+
89
+ Without it, KHB leaves a pending row in `log.md` and prints the required setup rather than
90
+ failing the run.
86
91
 
87
92
  Every raw markdown file carries provenance:
88
93
 
package/SPEC.md CHANGED
@@ -282,11 +282,15 @@ puts them on the CLI side of the §Division-of-labor line.
282
282
  | DOCX | `mammoth`, `pandoc` if present | bundled | high |
283
283
  | ODT, PPTX | `fflate` + XML | bundled | high |
284
284
  | XLSX | `fflate` → one markdown table per sheet | bundled | high |
285
- | scanned PDF | `pdfium` + `tesseract.js` (WASM) | opt-in, ~75 MB | low |
286
- | Images (png/jpg/webp/tif) | `tesseract.js` | opt-in, ~75 MB | low |
285
+ | scanned PDF | `pdfium` + `tesseract.js` (WASM) | bundled, ~75 MB | low |
286
+ | Images (png/jpg/webp/tif) | `tesseract.js` | bundled, ~75 MB | low |
287
287
  | Audio, video | `whisper` / `faster-whisper` | opt-in, pip | low |
288
288
 
289
- Missing optional deps degrade to a ledger row with an empty `raw` and a printed install
289
+ The OCR stack is bundled rather than opt-in: an ingest that stops to ask for an install is
290
+ worse than an install that carries WASM nobody uses. Transcription stays opt-in because it is
291
+ a Python executable, not something a JS package manager can pull down.
292
+
293
+ A missing dep degrades to a ledger row with an empty `raw` and a printed install
290
294
  hint — never to a failed run. `quality: low` output is a standing invitation for the catalog
291
295
  pass to re-read the original: a vision read of a chart or a scanned table recovers what OCR
292
296
  drops, and rewrites the raw file with `extract_tool: claude-vision`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@msareen/knowledge-hub-builder",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Knowledge Hub Builder — a bundle-of-bundles knowledge base you build with an agent",
5
5
  "keywords": ["knowledge-base", "okf", "agent", "wiki", "bundles", "claude", "codex", "rag"],
6
6
  "license": "MIT",
@@ -141,16 +141,22 @@ curation, not transcription.
141
141
  Extracted text is cached hub-wide by content hash at `inbox/extracted/<sha256>.md`, so the
142
142
  same file appearing in two bundles converts once.
143
143
 
144
- OCR and transcription need optional dependencies. When they are missing khb says so once and
145
- records the affected files as pending rather than failing the run:
144
+ **OCR needs no setup.** `@hyzyla/pdfium`, `sharp` and `tesseract.js` are dependencies of khb
145
+ itself, so a scanned PDF or a photographed page is read on the first run, in any hub, without
146
+ asking the user to install anything.
147
+
148
+ Transcription is the one route that can be absent: it wants a `whisper` or `faster-whisper`
149
+ executable on `PATH`.
146
150
 
147
151
  ```
148
- bun add @hyzyla/pdfium sharp tesseract.js # OCR — ~75 MB WASM, no system binary
149
152
  pip install -U openai-whisper # transcription (faster-whisper also works)
150
153
  ```
151
154
 
152
- Install them where `khb` resolves modules from for a global install that is the khb
153
- package directory, not your hub. khb prints the exact `cd && bun add …` to use.
155
+ When any extractor is unavailable khb says so once and records the affected files as pending
156
+ rather than failing the run a `log.md` row with an empty `raw`, waiting for the dependency.
157
+ If khb ever prints a `bun add` hint for the OCR packages, its own install tree is incomplete;
158
+ install them where `khb` resolves modules from — for a global install that is the khb package
159
+ directory, not your hub — and khb prints the exact `cd … && bun add …` to use.
154
160
 
155
161
  ## 4. Sources khb cannot reach
156
162
 
@@ -229,11 +235,30 @@ Still on you, not khb: a source **modified in place** keeps its `curated` value,
229
235
  concept derived from it does not re-enter the backlog even though its material changed.
230
236
  Watch for `raw/` files whose content shifted and re-catalog them deliberately.
231
237
 
232
- ## Hand off
238
+ ## Hand off — offer the catalog pass
233
239
 
234
240
  Ingest is done when the summary shows nothing unexpectedly pending. Report to the user what
235
- landed, what didn't and why, and how many rows are uncurated — then continue with the
236
- [catalog skill](../catalog/SKILL.md) to turn `raw/` into concept docs.
241
+ landed, what didn't and why, and how many `log.md` rows are now uncurated.
242
+
243
+ Then **offer to catalog, and wait for the answer.** Raw text is not yet knowledge — a bundle
244
+ left at the end of ingest has a backlog and nothing citable — so never stop silently on the
245
+ summary, and never start cataloging unasked either. Name the bundle and the size of the
246
+ backlog in the offer, so the answer is informed:
247
+
248
+ > Ingest landed 94 files in `real-estate/raw/`; 94 rows are uncurated. Shall I catalog them
249
+ > into concept docs now?
250
+
251
+ Take the answer at face value:
252
+
253
+ - **yes** → continue with the [catalog skill](../catalog/SKILL.md), on that bundle, reading
254
+ the backlog from `log.md`.
255
+ - **no, or not now** → stop. The ledger is the durable backlog, so nothing is lost; say that
256
+ the uncurated rows are waiting whenever they want to pick it up.
257
+ - **only part of it** — one folder, one document, the low-quality files first → catalog that
258
+ subset and leave the rest of the rows uncurated.
259
+
260
+ Offer once, for the bundle you just ingested. Do not offer to catalog a bundle this run did
261
+ not touch, and do not roll a "yes" onward into a second bundle's backlog.
237
262
 
238
263
  ## Hygiene
239
264