Installation
markdown source of this page
The page as a markdown file: index.md
+++
title = "Installation"
subtitle = "starting a wiki in a project"
status = "approved"
intent = """
Installation exists so that any project, on any stack, can start a wiki with one pinned release of the
tool and a handful of files. Updating should be a one-line change a reviewer can see.
"""
[[infobox]]
group = "Identity"
rows = [
{ label = "Package", value = "wiki-builder", cite = "package" },
{ label = "Command", value = "wiki", cite = "package" },
]
[[infobox]]
group = "Requirements"
rows = [
{ label = "Python", value = "3.11 or newer", cite = "package" },
{ label = "Dependency", value = "mistune, pinned exactly", cite = "package" },
{ label = "Runner", value = "uv or pip", cite = "uv" },
]
[[infobox]]
group = "Defaults"
rows = [
{ label = "Wiki folder", value = "docs/wiki", cite = "where" },
]
+++
wiki-builder is one Python package, and its only command is `wiki`.[^package] What each command does is
described on [Commands](commands.md), and checking a wiki on every push on
[Continuous integration](continuous-integration.md). An agent can take a project through every step
below from the [Installation prompt](installation-prompt.md).
## Requirements
It needs Python 3.11 or newer, and one dependency pinned exactly, the markdown parser `mistune`.[^package]
The wrapper script below also needs `uv`, whose `uvx` runs a release straight from its git address; a
project without `uv` installs a release with `pip` and runs `wiki` directly.[^uv]
## Wrapper
A project commits one script that runs a pinned release, and passes `--root` so the tool finds the project
wherever the script is called from.[^root]
```sh
#!/bin/sh
# scripts/dev-wiki.sh
set -eu
WIKI_VERSION=TAG
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
exec uvx --from "git+https://github.com/timothymarois/wiki-builder@$WIKI_VERSION" \
wiki "$@" --root "$ROOT"
```
The tool accepts `--root` after the command, which is what lets the script add it to whatever it is
handed.[^root] `TAG` names a published wiki-builder release.{missing}
## First wiki
The tool reads a wiki from `docs/wiki` unless told otherwise.[^where] That folder needs a `wiki.toml`
with a site name and at least one section, or the tool stops and says so.[^config]
```toml
[site]
name = "Notes"
[[section]]
title = "Start"
pages = ["index", "goals"]
```
Every wiki needs a `goals.md` page to collect the intents onto, and every page needs a title and an
intent.[^pages] Every page a section lists must exist, so the example above also needs an
`index.md`.[^nav] A page about the wiki itself says `goals = false`.[^exempt]
```markdown
+++
title = "Goals"
status = "approved"
goals = false
intent = """
This page collects what each part of the project is for.
"""
+++
What each part is for.
```
`wiki sync` writes the skill for the project's agents and records the release, then `wiki build` records
each page's date.[^sync] The tool writes no ignore file, so a project adds `docs/wiki/site/` to its own
`.gitignore` to keep the rendered site out of version control, as wiki-builder does.[^ignore]
```sh
./scripts/dev-wiki.sh sync
./scripts/dev-wiki.sh build
./scripts/dev-wiki.sh check
```
## Updates
An update is a new tag in the script, then `wiki sync` to rewrite the skill and record the release.[^sync]
`wiki check` fails until that release is recorded, and names every page a new rule breaks.[^version]
[^package]: `pyproject.toml` — `[project.scripts]` names the `wiki` command, `requires-python` asks for
3.11 or newer, and `dependencies` pins `mistune==3.3.4`.
[^uv]: uv docs — [Tools](https://docs.astral.sh/uv/guides/tools/): `uvx` is an alias for `uv tool run`,
and `--from` installs a tool from another source, such as a git repository; `action.yml` — installs
wiki-builder with `pip`, without `uv`.
[^root]: `src/builder/cli.py` — `main()` accepts `--root` and `--wiki` before the command or after it.
[^where]: `src/builder/build.py` — `wiki_of()` defaults the wiki to `docs/wiki`.
[^config]: `src/builder/config.py` — `read_config()` refuses a `wiki.toml` with no `site.name` or no
`[[section]]`.
[^pages]: `src/builder/build.py` — `write_site()` refuses a wiki with no `goals.md`, and `read_pages()`
refuses a page with no title or intent.
[^nav]: `src/builder/build.py` — `render_nav()` refuses a section listing a page that does not exist.
[^exempt]: `src/builder/build.py` — `goals = false` is skipped by `goals_page()` and `uncited_problems()`.
[^sync]: `src/builder/cli.py` — `sync()` writes the skill and calls `record_version()` in
`src/builder/config.py`; `src/builder/build.py` — `write_site()` records dates in `UPDATED.toml`.
[^ignore]: `.gitignore` — `docs/wiki/site/`; `src/builder/cli.py` — `run()` builds into `site` inside the
wiki folder, and nothing in `src/builder` writes a `.gitignore`.
[^version]: `src/builder/build.py` — `version_problems()`, called from `check()`, which gathers every
problem at once.
Last updated 14 September 2026