107 lines
4.7 KiB
Markdown
107 lines
4.7 KiB
Markdown
---
|
|
name: wiki
|
|
description: >
|
|
Search the user's own notes — personal git note repos plus the live workspace — by
|
|
keyword, topic or meaning. Use to answer questions about what the user has written
|
|
down, recorded or decided, and to find which file covers a topic.
|
|
Triggers on: "/wiki", "find in my notes", "what did I write about", "do I have notes on".
|
|
Read-only: it never writes, edits or captures notes, and it does not answer from
|
|
general knowledge — only from what is indexed on disk.
|
|
---
|
|
|
|
# /wiki
|
|
|
|
Hybrid search over the user's notes. `chunks` is the single retrieval unit: FTS5 supplies a
|
|
BM25 rank, `sqlite-vec` a vector rank, and RRF merges the two.
|
|
|
|
Reply to the user in their own language.
|
|
|
|
## Pick a layer
|
|
|
|
Three layers, cheapest first. Start with the one that matches the question.
|
|
|
|
| Question shape | Command |
|
|
|---|---|
|
|
| exact string, filename, hostname, IP, identifier, code | `grep <pattern>` |
|
|
| "what do I even have about X", orientation, browsing | `toc [--source X] [--tag Y]` |
|
|
| a topic or a paraphrase, wording unknown | `search "<query>"` |
|
|
|
|
```sh
|
|
uv run skills/wiki/scripts/wiki_search.py grep "rotate_snapshots"
|
|
uv run skills/wiki/scripts/wiki_search.py toc --source travel
|
|
uv run skills/wiki/scripts/wiki_search.py search "jak snížit elektroodpad" --limit 5
|
|
```
|
|
|
|
For the full flag reference of any subcommand:
|
|
|
|
```sh
|
|
uv run skills/wiki/scripts/wiki_search.py --help
|
|
uv run skills/wiki/scripts/wiki_search.py <subcommand> --help
|
|
```
|
|
|
|
## Behavioral contract
|
|
|
|
**The index is a retrieval hint, never the answer.** `search` returns an excerpt to tell you
|
|
*which file* is relevant. Before answering, read that file fresh from disk — the index can be
|
|
up to a minute behind, and the excerpt is truncated. Never quote figures, commands or
|
|
decisions straight from a `search` excerpt.
|
|
|
|
**Only markdown is indexed; `grep` sees everything.** Source code, configs and data files never
|
|
reach `search` or `toc`. For anything code-shaped — an identifier, a flag, a function name —
|
|
`grep` is the right layer, not a fallback. Exact match is what matters there anyway.
|
|
|
|
**`grep` is a regex.** Escape regex metacharacters when the user means them literally
|
|
(`.`, `(`, `[`, `*`, `+`, `?`, `|`). It searches the files on disk, so it is always current.
|
|
|
|
**`search` results always look plausible.** The vector half has no distance floor: it returns
|
|
its nearest chunks whatever you ask, so an empty result set means an empty index, not "nothing
|
|
matches". Judge each hit against the question and say so when nothing genuinely fits — do not
|
|
present a weak nearest neighbour as an answer.
|
|
|
|
**Read the notes the output prints.** Each hit shows `source:path`, the breadcrumb, and which
|
|
half found it (`bm25 #2, vec #1`). A hit both halves rank highly is worth more than one only
|
|
the vectors found.
|
|
|
|
## Notes the output may print
|
|
|
|
- `embeddings unavailable … FTS-only results` — the semantic half is down, so only keyword
|
|
matching ran. Paraphrase queries will do badly; say so rather than concluding the notes are
|
|
silent on the topic. Try `grep` with the user's own wording.
|
|
- `N chunks still awaiting vectors` — a sync is mid-flight or was degraded. Recent notes may
|
|
be missing from the semantic half.
|
|
- `reindex needed: …` on stderr with exit 1 — the index was built under a different embedding
|
|
contract. Nothing is wrong with the notes; the index has to be rebuilt (see below). Do not
|
|
retry the query.
|
|
|
|
## Sources
|
|
|
|
Defined in `wiki/config.yaml`. Each has a stable **source id** used in output and in
|
|
`--source`. Git sources are read-only clones under `wiki/remote/<id>/`; the `workspace` source
|
|
indexes the live workspace. The user's repos are the canonical data — nothing here ever writes
|
|
to them.
|
|
|
|
`toc --tag` filters on frontmatter tags, which only exist where the user wrote them.
|
|
|
|
## Indexing
|
|
|
|
`wiki_sync.py` runs every minute from the crontab and does all the work offline. Never index
|
|
inside a turn: a full rebuild takes minutes and the `exec` tool times out at 60 s.
|
|
|
|
```sh
|
|
uv run skills/wiki/scripts/wiki_sync.py # what cron runs; a quiet tick is free
|
|
uv run skills/wiki/scripts/wiki_sync.py --full # wipe and rebuild
|
|
```
|
|
|
|
`--full` is needed only after the embedding model, its dimensions, the query prefix or the
|
|
chunker change — that is what a `reindex needed` message means. It re-embeds everything, so
|
|
run it in the background and tell the user it is running, never inside a turn where they wait.
|
|
|
|
`log/wiki_sync.log` holds one line per event: what was indexed, `WARN` for a source that was
|
|
skipped, and a `coverage` line naming top-level directories that hold markdown no source
|
|
covers. Read it when `search` cannot find something the user is sure they wrote.
|
|
|
|
## Environment
|
|
|
|
- `WIKI_DB` — override the index path (tests).
|
|
- `WIKI_CONFIG` — override the config path (tests).
|