| name | wiki-dashboard |
| description | Generate a self-contained HTML dashboard for a Karpathy-style wiki — pages by type, tag cloud, backlink graph, recent activity, and size/age histograms. Single HTML file with no external CDN calls, safe to open offline or share. Use this skill whenever the user says 'wiki dashboard', 'visualize my wiki', 'show me the wiki in HTML', 'generate a dashboard', 'wiki overview as HTML', 'render the wiki', 'what does my wiki look like', 'wiki graph', 'wiki visual overview', or wants a visual birds-eye view of their knowledge base beyond what wiki-resume offers as plain text. |
| allowed-tools | Read, Write, Bash, Glob |
Wiki Dashboard
Render a single self-contained HTML file that gives the user a birds-eye view of their wiki — more visual than wiki-resume, less text-heavy than reading individual pages.
Read ${CLAUDE_PLUGIN_ROOT}/references/karpathy-pattern.md once at the start.
When to run
- User asks for a dashboard, HTML overview, or visualization of the wiki
- After a major ingest session to see the shape of new additions
- Before sharing the wiki with someone else — the dashboard is shareable as a single file
Never run when
- The wiki is empty — there is nothing to visualize
- The wiki is not set up — offer
wiki-setup
Parameters
| Parameter | Required | Description |
|---|
--wiki-root | No | Override the auto-detected wiki root |
--output | No | Output path (default: <wiki-root>/wiki-dashboard.html) |
--open | No | yes / no (default no) — whether to print the file:// URL prominently at the end |
--graph | No | no (default) / pass1 / yes — render the structural graph view alongside the standard dashboard. pass1 runs only the deterministic [[wikilink]] pass. yes additionally drives Pass-2 LLM evaluation (see Workflow §3) |
--graph-only | No | yes / no (default no) — emit only the graph HTML, skip the standard dashboard |
--graph-output | No | Output path for the graph HTML (default: <wiki-root>/wiki-graph.html) |
--model | No | Model id used for Pass-2 cache key (default: sonnet) |
--graph-pass2-budget | No | Max number of Pass-2 LLM evaluations per run (default: 50) |
Workflow
1. Locate the wiki
Walk upward to find .cogni-wiki/config.json. If none, stop.
2. Run the renderer script
Invoke ${CLAUDE_PLUGIN_ROOT}/skills/wiki-dashboard/scripts/render_dashboard.py --wiki-root <path> --output <output>. The script reads every page in the per-type page dirs, parses frontmatter, counts inbound [[wikilinks]], and writes a single HTML file containing:
- Header with wiki name, slug, description, created date
- Stats strip (page count, raw sources, last lint, 30-day activity)
- Pages by type (donut proxy via stacked bars — no JS charting library)
- Tag cloud (top 30 tags, font-sized by frequency)
- Recent activity (last 20 log entries)
- Most-linked pages (top 10 by inbound-link count)
- Orphan pages list
- Full page index grouped by type, with inline-link counts
The output HTML is self-contained: one file, no external CSS/JS/fonts, no CDN calls. Safe to open offline and safe to share — nothing leaves the user's machine to render it. If the script exits non-zero, report the error to the user with the raw stderr output — do not write a partial or broken HTML file.
3. Graph build (when --graph ∈ {pass1, yes})
The graph view is generated by ${CLAUDE_PLUGIN_ROOT}/skills/wiki-dashboard/scripts/build_graph.py. It is independent of render_dashboard.py — they share _wikilib helpers but produce two separate HTML files. Read ${CLAUDE_PLUGIN_ROOT}/skills/wiki-dashboard/references/graph-renderer.md once at the start of this step.
3a. Pass 1 (always runs, free, deterministic).
Invoke build_graph.py --mode build --wiki-root <path> --output <graph-output>. It walks every page, extracts [[wikilink]] targets (resolving against _wikilib.build_slug_index), drops self-loops and dangling targets, runs Label Propagation for community ids, reads any cached Pass-2 judgements, and writes the self-contained graph HTML. Stop here if --graph pass1.
3b. Pass 2 (only when --graph yes).
Invoke build_graph.py --mode enumerate-candidates --wiki-root <path> --model <model> --limit <budget>. The script returns up to --graph-pass2-budget page pairs that:
- share at least one tag, OR
- share a
type: AND have ≥ 0.20 Jaccard body-token overlap, OR
- have ≥ 0.35 Jaccard body-token overlap regardless of tags/type;
- AND are not already covered by a Pass-1 edge;
- AND are not foundation×foundation pairs;
- AND don't have a fresh cache hit (
page_a_hash + page_b_hash + model_id all match).
For each candidate (in the order returned — deterministic by pair_id, so partial runs resume), the orchestrator reads page_a_preview and page_b_preview from the manifest and asks the configured model:
Read these two wiki page previews. Do they have an unstated semantic relationship that isn't already captured by an explicit [[wikilink]]? Reply with strict JSON: {"related": true|false, "confidence": 0.0-1.0, "relationship": "<short phrase>"}.
The orchestrator then calls build_graph.py --mode record-judgement --pair-id <id> --slug-a <a> --slug-b <b> --judgement related|unrelated --confidence <f> --relationship "<phrase>" --model <model>. Each call atomically writes one cache file under .cogni-wiki/graph-cache/<pair_id>.json. If the run is interrupted mid-loop, every recorded pair persists; resuming re-enumerates and only the unevaluated pairs come back.
3c. Re-render with the populated cache.
Re-invoke build_graph.py --mode build so the new INFERRED edges land in the HTML.
3d. Log line.
Append one line to wiki/log.md: ## [YYYY-MM-DD] graph | nodes=<N>, extracted=<E1>, inferred=<E2>, communities=<C>. The graph prefix joins the existing operation enum.
4. Report to the user
Print:
- Path to the generated HTML file
- A one-line summary of what it contains ("Rendered dashboard for {N} pages — open with
open {path}")
- If
--open yes, wrap the path in file:// so the terminal treats it as a URL
5. Do not write anywhere else
The standard dashboard never touches the wiki content. The graph build appends one ## [YYYY-MM-DD] graph | … line to log.md (Step 3d) when --graph runs and writes per-pair cache files under .cogni-wiki/graph-cache/. Neither path mutates page bodies or config.json.
Output
- A single HTML file at
<output> (default <wiki-root>/wiki-dashboard.html)
- When
--graph ∈ {pass1, yes}: a second HTML file at <graph-output> (default <wiki-root>/wiki-graph.html) plus per-pair cache files under <wiki-root>/.cogni-wiki/graph-cache/
- When
--graph yes: one ## [YYYY-MM-DD] graph | … line appended to wiki/log.md
Constraints
- Read-only by default. The standard dashboard never writes to the wiki. The graph build appends a
graph log line and writes per-pair cache files; neither mutates page bodies or config.json.
- Self-contained single file. No external CSS, CDN, Google Fonts, or JS libraries. Inline everything into one HTML file. The graph view ships its own minimal vanilla-canvas force-directed renderer (~300 LOC inline JS) to avoid bundling vis-network's ~600 KB; see
references/graph-renderer.md.
- No network calls. The script must not reach out to any URL at render time.
- Stdlib only. Python 3 stdlib for rendering — no Jinja, pandas, or plotly. The graph build uses only stdlib for Label Propagation community detection (no networkx).
- Print-friendly. The standard dashboard renders well when saved as PDF. The graph view is interactive-only — opt out via
--graph no for print scenarios.
- Accessible color. No content conveyed by color alone.
- Idempotent. Running twice produces identical bytes (modulo the "generated at" timestamp). Label Propagation is seeded by sorted-slug initialisation with lower-id-wins tie-break to keep community ids stable.
References
${CLAUDE_PLUGIN_ROOT}/references/karpathy-pattern.md — the pattern
./scripts/render_dashboard.py — the standard HTML renderer
./scripts/build_graph.py — the two-pass graph builder (#221)
./references/graph-renderer.md — graph-renderer contract, cache schema, future swap-in points