@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.
- package/.agents/skills/catalog/SKILL.md +7 -0
- package/.agents/skills/export/SKILL.md +7 -0
- package/.agents/skills/ingest/SKILL.md +7 -0
- package/.agents/skills/lint/SKILL.md +7 -0
- package/.agents/skills/new-bundle/SKILL.md +7 -0
- package/.agents/skills/query/SKILL.md +7 -0
- package/.agents/skills/visualize/SKILL.md +7 -0
- package/.bundle_template/index.md +9 -0
- package/.bundle_template/log.md +10 -0
- package/.bundle_template/raw/.gitkeep +15 -0
- package/.bundle_template/refs.md +6 -0
- package/.bundle_template/sources.yaml +13 -0
- package/.claude/skills/catalog/SKILL.md +7 -0
- package/.claude/skills/export/SKILL.md +7 -0
- package/.claude/skills/ingest/SKILL.md +7 -0
- package/.claude/skills/lint/SKILL.md +7 -0
- package/.claude/skills/new-bundle/SKILL.md +7 -0
- package/.claude/skills/query/SKILL.md +7 -0
- package/.claude/skills/visualize/SKILL.md +7 -0
- package/AGENTS.md +167 -0
- package/CLAUDE.md +13 -0
- package/README.md +289 -0
- package/SPEC.md +354 -0
- package/document/faq.md +156 -0
- package/package.json +52 -0
- package/scripts/cli.ts +66 -0
- package/scripts/export.ts +42 -0
- package/scripts/ingest/acquire.ts +189 -0
- package/scripts/ingest/exts.ts +29 -0
- package/scripts/ingest/files.ts +29 -0
- package/scripts/ingest/folder.ts +44 -0
- package/scripts/ingest/index.ts +125 -0
- package/scripts/ingest/protect.ts +42 -0
- package/scripts/ingest/web.ts +54 -0
- package/scripts/init.ts +93 -0
- package/scripts/lib/args.ts +8 -0
- package/scripts/lib/extract.ts +384 -0
- package/scripts/lib/graph-page.ts +477 -0
- package/scripts/lib/graph.ts +117 -0
- package/scripts/lib/ledger.ts +136 -0
- package/scripts/lib/log.ts +53 -0
- package/scripts/lib/paths.ts +55 -0
- package/scripts/lib/scaffold.ts +56 -0
- package/scripts/lib/util.ts +154 -0
- package/scripts/lint.ts +165 -0
- package/scripts/new-bundle.ts +17 -0
- package/scripts/visualize.ts +104 -0
- package/skills/catalog/SKILL.md +164 -0
- package/skills/export/SKILL.md +31 -0
- package/skills/ingest/SKILL.md +229 -0
- package/skills/lint/SKILL.md +69 -0
- package/skills/new-bundle/SKILL.md +25 -0
- package/skills/query/SKILL.md +114 -0
- package/skills/visualize/SKILL.md +33 -0
- package/templates/hub/gitattributes +12 -0
- package/templates/hub/gitignore +12 -0
- 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.
|