ws-update
Create or update content in the user's wiki — and set the wiki up when none exists yet. Use when the user says "update wiki", "sync project", "save this", "capture this", "store this research", "set up my wiki", "create a wiki", "set up a wiki for this project", or wants to distill knowledge from a project, conversation, or research session, or to adopt an existing folder of notes as a wiki. When a session produced durable knowledge worth keeping, offer once at a natural wrap-up — never per-turn.
How do I install this agent skill?
npx skills add https://github.com/anfreire/wiki-spaces --skill ws-updateIs this agent skill safe to install?
- Gen Agent Trust Hubpass
The ws-update skill manages a Markdown-based wiki for knowledge extraction and project syncing. It uses a bundled Python script to enforce structure, size limits, and trust boundaries. The skill performs standard file system and Git operations and includes robust path normalization to prevent directory traversal. External repository interactions are user-guided and follow a clear ownership model.
- Socketpass
No alerts
- Snykpass
Risk: LOW · No issues
What does this agent skill do?
Wiki Update
Extract durable knowledge from the current source — a project, the conversation, a research session — and place it in the user's wiki. Merge before creating, respect the wiki's conventions, and keep every file inside its size cap.
<!-- 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 -->
Initialization
When nothing resolves — no explicit path, no CWD-ancestor wiki, no valid config — set one up inline: follow references/init.md, then resume the request. A broken configured path (missing on disk, no index.md, not absolute) is a hard stop, not a setup trigger — surface it and let the user decide. A folder's own space — asked for ("set up a wiki for this project"), or offered once when a sync targets a folder that has none — follows references/own-space.md, whether or not a wiki already resolves.
Procedure
-
Resolve the wiki (core block) and announce the root when it came from CWD or could be ambiguous.
-
Detect conventions at the scope root (core block). Presence markers (
log.md, taxonomy,hot.md) never inherit from a parent;_meta/limits.md,_meta/ignore.md, and_template.mdfollow their nearest-ancestor rule. Skip every step whose marker is absent. -
Detect the mode from the user's intent — CWD only disambiguates which project, never the mode:
Mode Trigger Input Direct add "add this to the wiki", "save this recipe" — a concrete artifact in hand the handed content Project sync "sync this project", explicit project naming project files, git log Conversation capture "save this", "capture this" — the session itself, no single artifact the current conversation Research capture "store this research" findings from the session -
Extract knowledge. Direct add: take the content as handed — your job is placement and dedup, not re-synthesis. Project sync: decisions and rationale, patterns, tool/API wiring, trade-offs, results — from the files and recent git history. Conversation: durable conclusions and decisions, written as facts ("X works by…"), never chat summary. Research: what took effort and would be expensive to re-derive.
-
Filter and deduplicate. Knowledge-capture wikis get the noise filter: answerable from the code or a quick search? skip; needed in 3 months? keep. Content-store wikis (recipes, journals, runbooks) skip the filter — every entry is intentional. Enumerate existing pages via
filesand rank by filename/path/frontmatter overlap: when a near-match exists, merge into it instead of creating a sibling. -
Place.
listprints each space with its entry description — the placement hints; check top-level plain folders too. Match semantically: knowledge about a source belongs with that source's space when one exists — its own.wiki-spaces/, or its space in the wiki; knowledge reusable beyond it belongs with its topic. Standing in a folder's own space, that topic's home is the configured wiki the script notes — a second root: name the page and its place there, and on a yes take that root through steps 2 and 5 before writing. Several equally plausible candidates, or none → ask. Flat wiki → write at the root. Names follow the wiki's own pattern — match what existing pages do; where no pattern exists, default to lowercase, hyphenated, ≤50 chars. -
Check the cap on every write. Pipe planned content before writing:
python3 <skill-dir>/scripts/ws.py check-size <target> --stdin --wiki <root> <<'EOF' <planned content> EOFAn edit pipes its planned content the same way (a shrink of an over-cap page reports
ok); the audit backstops what slips through. Onover— never truncate, never ignore, never raise the cap. Re-read the page and its space's index, diagnose why it overflowed, then act:- Bloat — padding, near-duplicates, prose pasted in raw, entries you wouldn't re-create today → distill: merge, tighten, drop. The cap exists to force this judgment.
- Growth — genuinely distinct topics sharing one file → reshape the space to what it would look like had it been designed for today's content: self-standing sibling pages under a hub, a promotion, or a regrouped layout (Space operations links both procedures).
Both can apply — distill first, then reshape what remains. Update every index you touch. Filenames like
topic-2.mdortopic-more.mdmean a file was split without rethinking the space — never ship them. An over-capindex.mdis navigation debt: push detail into child pages, one line per entry.
-
Write. New pages: nearest ancestor
_template.mdif present, else the wiki's page shape (frontmatter only where the wiki already uses it). Mark non-source claims%%inferred%%, conflicting sources%%ambiguous%%. Add up to 2 wikilinks on first natural mentions. Updates: merge, preserve manual content, bumpupdated:if frontmatter is in use, never overwrite unrelated sections. On a project sync, record the repo path (~-contracted) on the project's hub page —repo:/sources:frontmatter where in use, else one plain line — so a later session maps the checkout to its page. More than ~10 pages changing → show the plan and ask first. -
Keep the contract. Created a new space, removed one, or moved pages? Update
## Spacesper Space operations below.## Itemssections are optional human curation — maintain one where the index already has it. Then check the shape you're leaving: entry descriptions still true, no name that only makes sense historically — small fixes now; bigger reshapes become the close-out'sws-tendsuggestion. -
Close out. Run
<!-- ws:safe-repairs -->audit. Apply the safe structural repairs yourself, re-auditing between rounds until gone:- Add the exact entry line a
missing entryfinding prints, then trail it with a— description— the placement hint every later operation reads. - Insert the
## Spacesheading a registered bare child lacks — only where the finding's hint asks for the insert; a near-miss hint asks for a rename, which stays reported as author intent. - Remove an entry the audit says crosses another space's boundary — that space owns the deeper listing; register it there instead when it is missing.
An undeclared bare index is a promotion decision — surface it, act only on the user's call. Other findings are reported, not auto-repaired; outside this sync's write scope, suggest a
ws-tendpass — suggestion only, never run it yourself. Log anUPDATEline per the core block and confirm in one block:Updated wiki (<root>)with created paths, updated paths, mode, and audit outcome. - Add the exact entry line a
Space operations
Create a space (a folder needing first-class navigation):
mkdir -p <root>/<path> && printf '# <Title>\n\n## Spaces\n' > <root>/<path>/index.md
Register it in the nearest ancestor space's ## Spaces — - [<name>/](<name>/index.md) — description, href percent-encoded where the name demands it; the description is the placement hint later operations read. The audit's missing entry finding prints the exact line if in doubt.
Remove a page: sweep for what points at it first — grep -F '<stem>' --wiki <root> (every link form carries the stem; judge each hit, code examples aside) — rewrite or drop the real links, prefer a move to _archives/ over deletion, then audit.
Remove a space: confirm with the user (prefer _archives/ over deletion), delete the folder, remove its entry from the parent's ## Spaces, then audit to verify nothing dangles.
Mount someone else's space: references/mount.md. Share a space of yours: references/share.md.
Promote a page into a space — routine once a page's shape asks for it; inventory its links, snapshot, move, rewrite, verify: references/promote.md. Rename, move, merge, or demote a space on the same skeleton: references/restructure.md.
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-update">View ws-update on skillZs</a>