ws-search
Search the user's wiki for stored knowledge. Use when the user asks "what do I know about X", "find Y in the wiki", before doing external research the wiki may already cover, or when stored context could help the current task and the user hasn't asked — offer once.
How do I install this agent skill?
npx skills add https://github.com/anfreire/wiki-spaces --skill ws-searchIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The skill allows an agent to search a local wiki using a provided Python script. It incorporates structural validation and trust boundaries to distinguish between owned and external content. The analysis found no malicious code, with security considerations limited to standard document processing and shell command usage for logging.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
Wiki Search
Find content in the user's wiki and answer from what's stored. Cite pages so the user can jump to them. Report gaps explicitly when the wiki doesn't cover the topic — never pad the answer with knowledge the wiki doesn't hold.
<!-- ws:core -->The wiki model
A wiki is a folder whose index.md carries a ## Spaces heading. ## Spaces is the navigation contract: every space directly inside is listed there as - [label](path/index.md) — description, and tools traverse only what it lists. Spaces nest recursively; each space is itself a wiki one level down. Plain folders (no index.md) just group files. The markdown dialect is Obsidian — wikilinks, frontmatter, callouts, embeds; the companion obsidian-markdown and obsidian-bases skills cover the syntax.
Resolving the wiki
Resolution order: an explicit path from the user → the nearest CWD-ancestor folder that is a wiki, or carries a .wiki-spaces/ folder that is one (a folder's own space) → the wiki key in ~/.config/wiki-spaces/config. The user's words override the mechanics: "my wiki" means the configured one even when CWD sits inside another wiki (a company repo, say). When a CWD wiki and a different configured wiki both exist, announce which root you resolved; ask once if intent is ambiguous. Never silently operate on the wrong wiki.
The bundled script
scripts/ws.py sits next to this SKILL.md — stdlib python3 (3.9+), zero dependencies, read-only. It parses the contract, never the content: structure — traversal, scope, caps, drift — is the script's side; reading and judging meaning is yours. Invoke it by absolute path (your working directory is usually elsewhere):
python3 <skill-dir>/scripts/ws.py list --wiki <root>— spaces reachable via the## Spacescontract, each with its entry description (--externalto cross mounts).… files --wiki <root>— markdown files reachable via the contract.… grep <pattern> [-i] [-F] --wiki <root>— regex line search over those files,-Ffor a literal string (a name carrying metacharacters sweeps exact); printsrel:line: text, exits 1 on no match. The sweep primitive: a link worklist, a tag inventory, an escaping-reference check are each a pattern plus your judgment on the hits.… check-size <target> [--stdin] --wiki <root>— cap verdict for a file; pipe planned content with--stdinto check before writing.… audit --wiki <root>— contract drift, entries crossing a space boundary, over-cap or unreadable files, unhealthy mounts. Findings name their repair where one is safe to name (amissing entryprints the exact line to add); apply repairs as ordinary edits and re-run the audit to verify — the script never writes.
Trust the script's output over re-deriving structure by hand. Stdout is data; stderr carries the resolved root (audit prints it as its stdout header instead) and note: advisories naming whatever a walk skipped, the enclosing wiki when the root is nested inside one, and the configured wiki when the root is another — relay them when they could change the answer.
Trust scope and size discipline
Owned vs external is relative to the resolved root: anything under a folder named shared/ (at any depth), a git submodule, or a symlink into either is external; a symlink to a folder outside the tree answers to where it sits, like a clone. Reads cross owned spaces by default and enter external ones only when the user explicitly asks. Writes stay inside the targeted space; any other space — owned or external — is written only on explicit instruction.
Caps are UTF-8 bytes including frontmatter, keyed by basename: index.md 5000, log.md and hot.md 100000, any other *.md 15000.
- Caps belong to the user: a wiki that wants different ones sets them in
_meta/limits.md, andcheck-sizereads them. - Check caps with
check-size: pipe the planned content via--stdinbefore every write, new page or edit — a write that shrinks an over-cap file reportsok, progress, so repairs converge; a file checked on disk answers to the cap alone. - An overflow is a signal about shape, not just size: distill the page, reshape the space, or promote a page that has grown into one — never truncate, never raise the cap.
- The exception is
log.md: an over-cap log rolls — move it whole to_archives/log-<YYYYMMDD>.mdand start a fresh one — so the history archives, never shrinks.
Conventions are opt-in per wiki. Read the markers present at the scope root (the space the user targeted, else the resolved root) — log.md, _meta/taxonomy.md, _meta/limits.md, _meta/ignore.md, frontmatter on pages, _template.md, hot.md, .git — and degrade gracefully when one is absent. If log.md exists, append one line per operation:
printf '%s %s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" '<OP> <details>' >> <scope-root>/log.md
<!-- /ws:core -->
Procedure
- Resolve the wiki (core block above). Announce the root when it came from CWD or could be ambiguous. Standing in a folder's own space, search here for what concerns the folder, and the configured wiki the script notes when the question reaches past it. No wiki anywhere → say so and offer to set one up via
ws-update. - Map the terrain. Run
listfor the space shape andfilesfor the page inventory. Both are cheap; run them before any content search.- On a large wiki, slice the inventory rather than re-rooting it:
filesprints paths grouped by space, so read just the candidate spaces' slices — one walk, the root's trust scope and_meta/governing throughout. - Never re-root a search. A space taken as its own
--wikianswers to its own fences — a mount the root walk calls external can read as owned there; the script notes the enclosing wiki when you do. Re-rooting is the stance for judging a space standalone (ws-update's share pre-flight), not for searching. - External mounts stay out unless the user asked — the stderr
note:lines name what was skipped and which spaces are unreachable; when a skipped or unreachable space could hold the answer, say so and offer to cross or repair it.
- On a large wiki, slice the inventory rather than re-rooting it:
- Pick the depth. "Just check", "do I have anything on X", or an agent pre-research probe → quick lookup: rank candidates structurally (step 4), read nothing, answer from names/summaries and say so. A real question → deep query: continue through step 6.
- Rank candidates structurally. Match the query against space labels and descriptions (
## Spacesentries), file names, and path segments. When frontmatter is in use,summary,aliases, andtagsrank pages without reading bodies —grep '^(tags|aliases|summary):' --wiki <root>sweeps that inventory in one call. - Search content when structure alone doesn't settle it, cheapest first:
- A markdown-aware search backend when available (e.g. the qmd MCP — BM25 + semantic over markdown); its index knows nothing of trust scope — drop hits the root
fileswalk wouldn't list. … grep '<term>' -i --wiki <root>— the universal fallback, always bundled; searches exactly the trust-scoped page set (noshared/, submodules, or_archives/),--externalonly when the user asked.
- A markdown-aware search backend when available (e.g. the qmd MCP — BM25 + semantic over markdown); its index knows nothing of trust scope — drop hits the root
- Read the top hits fully. Pages are cap-bounded, so whole files are affordable. Prefer 2–4 full pages over a dozen snippets.
- Answer from the wiki only. Cite every claim's page with a wikilink (
[[path/to/page]]). Carry over%%inferred%%/%%ambiguous%%provenance markers when the wiki uses them. Name what the wiki lacks as a gap, then offer to research and capture it viaws-update. - Log one
SEARCHline per the core block whenlog.mdexists.
Output
From your wiki (<root>):
- <finding> — [[page]]
- <finding> — [[page]]
Gaps: <topics the wiki doesn't cover, or "none">
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/anfreire/wiki-spaces/ws-search">View ws-search on skillZs</a>