$npx -y skills add NatsuFox/Tapestry --skill displayExpose the organized knowledge base through a readable frontend experience. Use when a user wants to browse the knowledge base visually as a lightweight site instead of reading raw Markdown files directly. Supports building viewers for specific data paths (e.g., individual books)
| 1 | # Tapestry Display |
| 2 | |
| 3 | Publish a readable frontend for the knowledge base: **$ARGUMENTS** |
| 4 | |
| 5 | ## When to use this skill |
| 6 | |
| 7 | Use this skill when: |
| 8 | - A user wants to browse the knowledge base visually |
| 9 | - You need to generate a readable frontend for the organized content |
| 10 | - The user asks to "view", "display", "publish", or "preview" the knowledge base or a specific book |
| 11 | - A lightweight site presentation is preferred over raw Markdown files |
| 12 | - The user wants a blog-like or research portal view of the content |
| 13 | |
| 14 | ## Purpose |
| 15 | |
| 16 | This skill acts as the presentation layer for the knowledge base. |
| 17 | |
| 18 | It should: |
| 19 | |
| 20 | - scan the specified data directory hierarchy (or default to `_data/books/`) |
| 21 | - preserve the topic and chapter structure defined by `index.md` |
| 22 | - generate a readable frontend that feels closer to a blog, notebook, or research portal than to a file browser |
| 23 | - support building viewers for specific books or the entire knowledge base |
| 24 | |
| 25 | ## Workflow |
| 26 | |
| 27 | 1. Resolve the data path from the argument: |
| 28 | - If a specific path is provided (e.g., "markets-and-trading"), use `_data/books/markets-and-trading` |
| 29 | - If no argument is provided, default to `_data/books/` (entire knowledge base) |
| 30 | |
| 31 | 2. Ensure the data directory exists and contains markdown files |
| 32 | |
| 33 | 3. Publish the frontend bundle with the appropriate data path: |
| 34 | |
| 35 | ```bash |
| 36 | # For a specific book |
| 37 | python display/_scripts/publish_viewer.py --data-path _data/books/markets-and-trading --force |
| 38 | |
| 39 | # For the entire knowledge base (default) |
| 40 | python display/_scripts/publish_viewer.py --force |
| 41 | ``` |
| 42 | |
| 43 | 4. **IMPORTANT**: The viewer is created at `<data-path>/_viewer`. Serve that generated directory directly: |
| 44 | |
| 45 | ```bash |
| 46 | # Serve from the viewer directory (entire KB — default, no --data-path) |
| 47 | python -m http.server 8766 --directory _data/books/_viewer |
| 48 | |
| 49 | # Serve from the viewer directory (specific book) |
| 50 | python -m http.server 8766 --directory _data/books/markets-and-trading/_viewer |
| 51 | ``` |
| 52 | |
| 53 | > **Critical**: When the goal is to display ALL knowledge bases, always build without `--data-path` |
| 54 | > and serve `_data/books/_viewer`. Serving from a topic-specific `_viewer/` will show only |
| 55 | > that one topic. If you used `--data-path` by mistake, re-run `publish_viewer.py --force` |
| 56 | > (without `--data-path`), kill the old server, and restart from `_data/books/_viewer`. |
| 57 | |
| 58 | 5. Report back with: |
| 59 | - the data source path |
| 60 | - the viewer output directory |
| 61 | - the generated manifest path |
| 62 | - the local preview URL if served |
| 63 | |
| 64 | ## Rules |
| 65 | |
| 66 | - Treat the `index.md` hierarchy as the authoritative structural map. |
| 67 | - Do not flatten the topic/chapter tree into a single undifferentiated list. |
| 68 | - Preserve topic-level separation so semantically distant materials remain clearly separated. |
| 69 | - Make documents readable first, but keep enough structural information visible for navigation. |
| 70 | - If the knowledge base is sparse or incomplete, still generate the frontend and let empty sections remain honest rather than faking content. |
| 71 | |
| 72 | ## Common Issues |
| 73 | |
| 74 | ### Viewer Shows Only One Topic Instead of All Knowledge Bases |
| 75 | |
| 76 | **Symptom**: The viewer loads but only displays one topic (e.g., `dingyi-dex-weekly`) even though multiple KB topics exist under `_data/books/`. |
| 77 | |
| 78 | **Root cause**: `publish_viewer.py` was called with `--data-path _data/books/<topic>`, which scopes the viewer to just that topic. The generated `_viewer/` inside the topic directory is then served instead of the full KB viewer. |
| 79 | |
| 80 | **Solution**: |
| 81 | ```bash |
| 82 | # 1. Rebuild the full-KB viewer (no --data-path) |
| 83 | python display/_scripts/publish_viewer.py --force |
| 84 | |
| 85 | # 2. Kill any old server processes |
| 86 | fuser -k <port>/tcp # or: kill <PID> |
| 87 | |
| 88 | # 3. Serve from the FULL books/_viewer, not a topic-specific one |
| 89 | python -m http.server <port> --directory _data/books/_viewer |
| 90 | ``` |
| 91 | |
| 92 | **Rule**: To show ALL KB topics, always build and serve from `_data/books/_viewer`. |
| 93 | Only use `--data-path` when intentionally scoping to a single book. |
| 94 | |
| 95 | ### Data Path Not Found |
| 96 | |
| 97 | The generated viewer expects `data/knowledge-base.json` under `<data-path>/_viewer/`. If you see a JSON parsing error like "Unexpected token '<'", it usually means `_ui/` was served directly instead of the published `_viewer/` output. |
| 98 | |
| 99 | **Solution**: Re-run `publish_viewer.py` and serve `<data-path>/_viewer`. |
| 100 | |
| 101 | ## Resources |
| 102 | |
| 103 | - `display/_scripts/publish_viewer.py`: scans `_data/books/`, copies frontend assets, and generates the JSON manifest. |
| 104 | - `_ui/`: custom static frontend assets for the viewer. |