@msareen/knowledge-hub-builder 0.1.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 (57) hide show
  1. package/.agents/skills/catalog/SKILL.md +7 -0
  2. package/.agents/skills/export/SKILL.md +7 -0
  3. package/.agents/skills/ingest/SKILL.md +7 -0
  4. package/.agents/skills/lint/SKILL.md +7 -0
  5. package/.agents/skills/new-bundle/SKILL.md +7 -0
  6. package/.agents/skills/query/SKILL.md +7 -0
  7. package/.agents/skills/visualize/SKILL.md +7 -0
  8. package/.bundle_template/index.md +9 -0
  9. package/.bundle_template/log.md +10 -0
  10. package/.bundle_template/raw/.gitkeep +15 -0
  11. package/.bundle_template/refs.md +6 -0
  12. package/.bundle_template/sources.yaml +13 -0
  13. package/.claude/skills/catalog/SKILL.md +7 -0
  14. package/.claude/skills/export/SKILL.md +7 -0
  15. package/.claude/skills/ingest/SKILL.md +7 -0
  16. package/.claude/skills/lint/SKILL.md +7 -0
  17. package/.claude/skills/new-bundle/SKILL.md +7 -0
  18. package/.claude/skills/query/SKILL.md +7 -0
  19. package/.claude/skills/visualize/SKILL.md +7 -0
  20. package/AGENTS.md +167 -0
  21. package/CLAUDE.md +13 -0
  22. package/README.md +289 -0
  23. package/SPEC.md +354 -0
  24. package/document/faq.md +156 -0
  25. package/package.json +52 -0
  26. package/scripts/cli.ts +66 -0
  27. package/scripts/export.ts +42 -0
  28. package/scripts/ingest/acquire.ts +189 -0
  29. package/scripts/ingest/exts.ts +29 -0
  30. package/scripts/ingest/files.ts +29 -0
  31. package/scripts/ingest/folder.ts +44 -0
  32. package/scripts/ingest/index.ts +125 -0
  33. package/scripts/ingest/protect.ts +42 -0
  34. package/scripts/ingest/web.ts +54 -0
  35. package/scripts/init.ts +93 -0
  36. package/scripts/lib/args.ts +8 -0
  37. package/scripts/lib/extract.ts +384 -0
  38. package/scripts/lib/graph-page.ts +477 -0
  39. package/scripts/lib/graph.ts +117 -0
  40. package/scripts/lib/ledger.ts +136 -0
  41. package/scripts/lib/log.ts +53 -0
  42. package/scripts/lib/paths.ts +55 -0
  43. package/scripts/lib/scaffold.ts +56 -0
  44. package/scripts/lib/util.ts +154 -0
  45. package/scripts/lint.ts +165 -0
  46. package/scripts/new-bundle.ts +17 -0
  47. package/scripts/visualize.ts +104 -0
  48. package/skills/catalog/SKILL.md +164 -0
  49. package/skills/export/SKILL.md +31 -0
  50. package/skills/ingest/SKILL.md +229 -0
  51. package/skills/lint/SKILL.md +69 -0
  52. package/skills/new-bundle/SKILL.md +25 -0
  53. package/skills/query/SKILL.md +114 -0
  54. package/skills/visualize/SKILL.md +33 -0
  55. package/templates/hub/gitattributes +12 -0
  56. package/templates/hub/gitignore +12 -0
  57. package/templates/hub/outer.index.md +13 -0
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: query
3
+ description: Answer a question from the KHB knowledge base — route to one bundle, search and read its concept docs, and offer to write back any durable new concept the answer produced. Use when the user asks what/why/how about any topic stored in bundles, or asks to look something up in the wiki/knowledge base.
4
+ ---
5
+
6
+ # Query KHB
7
+
8
+ Route from `outer.index.md` to exactly one bundle, enter through that bundle's `index.md`,
9
+ answer from concept docs only — then, if answering produced something durable, offer to
10
+ keep it. This file is the whole protocol.
11
+
12
+ ## 1. Route to exactly one bundle
13
+
14
+ `outer.index.md` is one line per bundle, so a hub whose scope lines are thin — or new, or
15
+ just growing — will not route a first-time question on description alone. Escalate in this
16
+ order and stop at the first step that yields a single bundle:
17
+
18
+ 1. **Read `outer.index.md`.** One bundle obviously owns the question → go. If the hub has
19
+ exactly one bundle, this step is trivially done.
20
+ 2. **Grep the indexes.** Search the question's key terms across `bundles/*/index.md` and any
21
+ nested `*/index.md`. This is still routing: you are reading routing tables to find the
22
+ door, not answering from what you hit.
23
+ 3. **Grep concept front matter.** Still inconclusive → search `title`, `description` and
24
+ `tags` across concept docs. Then, if still nothing, full text across concept bodies.
25
+ Never grep `raw/` — it is uncurated, and a hit there is not an answer.
26
+ 4. **Ask the user.** Two or more bundles still plausible → use the runtime's user-input
27
+ facility, or ask directly in chat, with one option per candidate bundle and its scope
28
+ line. A wrong silent guess costs a whole wasted traversal and an answer from the wrong
29
+ domain; the question costs one turn.
30
+
31
+ Text search is a legitimate way to *find the door*. It is not a way to answer: whatever a
32
+ grep hits, go back to the winning bundle's `index.md` and enter through it, so the index
33
+ gets a chance to route you to the better doc next to the one you matched.
34
+
35
+ A question that genuinely needs two bundles is **not** ambiguity — that is the collation
36
+ protocol below. Ambiguity is when one bundle owns the answer and you cannot tell which.
37
+
38
+ Reaching step 3 or 4 means routing failed at step 1. That is an `outer.index.md` defect, not
39
+ a user error: sharpen the bundle's scope line so the same question routes at step 1 next
40
+ time, and log it in the meta bundle backlog if the hub has one.
41
+
42
+ ## 2. Read
43
+
44
+ 1. `<bundle>/index.md` → follow progressive disclosure (subdirectory indexes) to the concept
45
+ doc(s); use frontmatter `type`/`tags` to filter, and follow in-bundle markdown links for
46
+ related concepts.
47
+ 2. **Check relevance before you use it.** A doc that matched on a keyword is not necessarily
48
+ about the question. Read enough to confirm it answers what was asked, and discard it
49
+ otherwise — a confidently wrong citation is worse than "the hub doesn't cover this".
50
+ 3. Answer from concept docs only, never from `raw/`. Cite file paths.
51
+
52
+ If nothing in the bundle covers the question, say so plainly. Offer to ingest a source that
53
+ would, rather than answering from general knowledge as if it came from the hub. If you do
54
+ answer from outside the hub, mark clearly which parts those are.
55
+
56
+ ## 3. Cross-bundle query (collation protocol)
57
+
58
+ When the question spans bundles A and B:
59
+
60
+ 1. Resolve the A-side in bundle A fully.
61
+ 2. Consult `A/refs.md`. If B is listed, follow it; if not, and B is clearly needed, add the
62
+ ref (bundle, reason) as part of your work.
63
+ 3. Enter B **via `B/index.md`** — never jump to a B note directly from A's text.
64
+ 4. Resolve the B-side in bundle B fully.
65
+ 5. Collate in your answer, not in the files.
66
+
67
+ Parallel variant: orchestrator dispatches agent 1 → A, agent 2 → B (steps 1 and 4
68
+ concurrently), then performs step 5 itself.
69
+
70
+ ## 4. Learn — offer to keep what the answer produced
71
+
72
+ A query is not always read-only. Sometimes answering means joining two concepts that were
73
+ never joined before, and that join is worth more than the one answer it just produced: the
74
+ next person to ask gets it for free, and the bundle gets denser rather than just bigger.
75
+
76
+ **Propose, then write on confirmation.** Never write silently — a bundle that fills up with
77
+ restated one-off answers is worse than one that stays thin.
78
+
79
+ Offer a new concept when **all** of these hold:
80
+
81
+ - the answer required synthesis across two or more concepts, or resolved something the
82
+ existing docs left implicit;
83
+ - the same question is plausibly asked again — it is knowledge, not this conversation;
84
+ - no existing concept already covers it (check before offering — folding into an existing
85
+ doc is usually the better move, and is worth offering instead);
86
+ - it lives entirely inside one bundle. A synthesis that spans bundles belongs to whichever
87
+ bundle owns the question, phrased in that bundle's terms with a `refs.md` entry to the
88
+ other. Never write merged cross-bundle content into either.
89
+
90
+ Ask concisely: what you would write, where, and what it would link to. On yes:
91
+
92
+ 1. Write the concept doc with full OKF frontmatter (`type`, `title`, `description`, `tags`,
93
+ `timestamp`), in whichever subdirectory fits — the same rules as
94
+ [catalog](../catalog/SKILL.md).
95
+ 2. **Link it to the concepts it was derived from, and link those back to it.** A synthesis
96
+ nobody can reach from its sources is a dead end; the back-links are what make the bundle
97
+ denser rather than just longer.
98
+ 3. Register it in the bundle's `index.md`. Unindexed means invisible to the next query.
99
+ 4. Note it in `log.md` — source `query: <the question>`, `curated` the new path — so the
100
+ provenance of a doc with no ingested source is still recorded.
101
+ 5. `khb lint`.
102
+
103
+ Corrections work the same way: if answering reveals that a concept doc is **wrong** or
104
+ stale, say so and offer to fix it in place. That is a repair, not a new concept, and it
105
+ still needs confirmation.
106
+
107
+ ## Query hygiene
108
+
109
+ - Prefer index navigation over grep for *reading*; grep freely for *routing*.
110
+ - Never answer from `raw/`. If the only material is raw, say so — the remedy is to catalog
111
+ the bundle, not to cite evidence as knowledge.
112
+ - Ask rather than guess a bundle.
113
+ - Grep reached a concept the index didn't → fix the index. That is a routing defect the
114
+ query just exposed, and it costs one line to repair.
@@ -0,0 +1,33 @@
1
+ ---
2
+ name: visualize
3
+ description: Serve the live KHB bundle graph. Use when the user wants to see the bundle map or after bundles/refs change.
4
+ ---
5
+
6
+ # Visualize KHB
7
+
8
+ 1. Run `khb visualize` (aliases: `vis`, `viz`) from anywhere inside the hub — it walks up
9
+ to `khb.json` to find the root, serves the graph from a local server, prints the URL and
10
+ opens it in the default browser (`--no-open` to skip that). It binds a random free port
11
+ unless `--port N` pins one (falling back to a random port if that one's taken).
12
+ 2. Two zoom levels: top level shows bundles as nodes (sized by concept count) with directed
13
+ `refs.md` edges — that view is the cross-bundle map. Click a bundle to drill into its
14
+ concepts; the `← all bundles` button or Escape comes back out. Clicking empty space does
15
+ nothing — it will not throw you out of the bundle.
16
+ 3. Inside a bundle the concepts are grouped into labelled regions, one per top-level
17
+ subdirectory (`tables/`, `notes/`, …), rather than floating freely — so the shape you
18
+ see is how the bundle is actually organised. Deeper subdirectories fold into their
19
+ top-level folder.
20
+ 4. The canvas pans and zooms: wheel to zoom at the cursor, drag the background to pan,
21
+ `fit` in the top bar or the `F` key to reframe everything. The opening view is already
22
+ settled and framed, zoomed in far enough to read.
23
+ 5. Node labels are the concept `title`, clipped, and any label that would collide with
24
+ another is left out — so text stays sparse and readable. Zoom in to reveal more of
25
+ them. The `type` is the node's colour; it is named in words in the hover strip at the
26
+ bottom and in the panel, so there is no legend to consult.
27
+ 6. Click a concept to open a side panel with its untruncated title, full path, type, and
28
+ body, fetched on demand from the server. The theme toggle (dark/light) in the top bar
29
+ is remembered between runs.
30
+ 7. A refresh button rescans the hub live and refetches the graph — useful mid-catalog, when
31
+ the graph is still changing.
32
+ 8. The server exits on its own once you close the browser tab (no need to hunt down a
33
+ background process); Ctrl+C also works.
@@ -0,0 +1,12 @@
1
+ # Knowledge is markdown written by agents and humans on different platforms — normalize
2
+ # to LF so diffs stay readable and a bundle synced across machines doesn't churn.
3
+ * text=auto eol=lf
4
+
5
+ # Anything acquired into raw/ is provenance, not source. Don't rewrite it.
6
+ bundles/*/raw/** -text
7
+ *.png binary
8
+ *.jpg binary
9
+ *.pdf binary
10
+ *.docx binary
11
+ *.xlsx binary
12
+ *.pptx binary
@@ -0,0 +1,12 @@
1
+ # Acquired source material — re-fetchable from sources.yaml; log.md keeps the record.
2
+ bundles/*/raw/
3
+
4
+ # Agent-specific machine-local permissions; shared skills remain tracked.
5
+ .claude/settings.local.json
6
+
7
+ # Extraction cache (inbox/extracted/<sha256>.md) — re-derivable from the sources.
8
+ inbox/
9
+
10
+ # Generated
11
+ visualizer/graph.html
12
+ export/
@@ -0,0 +1,13 @@
1
+ # outer.index — bundle router
2
+
3
+ Routing only. One line of scope + when to route there. No knowledge content here.
4
+
5
+ <!-- lint: every bundles/<name>/ must appear below; every entry must exist on disk -->
6
+
7
+ | Bundle | Scope | Route here when |
8
+ |---|---|---|
9
+
10
+ ## Groups
11
+
12
+ Group related bundles under a heading as they accumulate — by org, by client, by
13
+ whatever line matters. A heading routes to bundles, never to notes.