-
-
Notifications
You must be signed in to change notification settings - Fork 0
Getting Started
You need Rust 1.89 or newer. Nothing else — no Node, no database, no container runtime.
git clone https://github.com/metadatastician/berrywiki.git
cd berrywiki
cargo build --releaseThe binary lands at target/release/berrywiki.
A GitHub wiki is an ordinary git repository. Clone yours:
git clone https://github.com/OWNER/REPO.wiki.git my-wiki
berrywiki serve my-wikiOpen http://127.0.0.1:23779. You get three panes: the page tree, the page itself, and an outline with backlinks.
That port is the default and is deliberate: 23779 sits in an IANA-unassigned
block, well away from the 8080/3000-class ports that collide with everything
else you have running. BerryWiki listens on TCP only, loopback by default.
--addr host:port moves it.
To try it without touching a real wiki, the repository ships a fixture notebook:
cargo run -p berrywiki-cli -- serve fixtures/test-wikiberrywiki check my-wiki # tree + diagnostics; exit 1 on any error
berrywiki sidebar my-wiki --write # regenerate _Sidebar.md
berrywiki serve --github OWNER/REPO # mirror a GitHub wiki (read-only)
berrywiki backup my-wiki ./backups # recoverable copy: bundle + drafts + journal
berrywiki restore ./backups my-wiki # rebuild a wiki from that copy
berrywiki import notes.ctd my-wiki # CherryTree notebook; reports, writes nothingcheck is the one to run in anger. It reports broken links, missing parents,
cycles and duplicate ids, and exits non-zero if any of them are errors — so it
works as a pre-commit hook or a CI step on your wiki repo.
For a private wiki, supply a token through the environment, never as an argument:
BERRYWIKI_GITHUB_TOKEN=ghp_… berrywiki serve --github OWNER/REPOPassing it as a flag would leave it in your shell history and in the process list, so BerryWiki does not accept one.
berrywiki backup my-wiki ./backups-2026-09-09
berrywiki restore ./backups-2026-09-09 my-new-wikiA backup is a directory holding three things: a git bundle of all committed history, your drafts, and the operation journal. Two refusals are deliberate and worth knowing before you script this:
-
backuprefuses a dirty working tree. A bundle carries committed history only, so backing up over uncommitted edits would silently omit them. Commit first, or accept that the backup is of the last commit. -
restorerefuses a folder that already has contents. It rebuilds into a new folder, sets the remote from the recorded origin, and puts the drafts back under the new folder's own app state — remember drafts are keyed by the wiki's path, so this step is what stops a restore losing them.
The search index is not archived. It is derived data and is rebuilt on demand.
berrywiki import notes.ctd my-wiki # report only
berrywiki import notes.ctd my-wiki --json # the same report, machine-readable
berrywiki import notes.ctd my-wiki --apply # actually write itWithout --apply nothing is written at all — the command tells you what the
notebook would become and stops. With --apply it still refuses rather than
overwrite: two siblings sharing a title, a page that already exists and did not
come from this same node, or a target folder that is not a git working tree
each stop the run before the first write, not partway through. An applied
import is one commit.
Re-running an import that already succeeded writes nothing, because every imported page records the node it came from.
Only the plain .ctd format is read. .ctb, .ctz and .ctx are refused by
name rather than half-parsed — see Decisions for why that line is
drawn where it is.
A local folder that is a git working tree is served with commit-on-save: every save is one commit, the regenerated sidebar included. That is the default, so you do not need to commit by hand on top of it — and should not, or you will be committing over commits BerryWiki has already made.
Pushing stays separate and explicit. The /changes page offers fetch,
fast-forward and push — never a merge, never a force. A history that has
diverged is reported rather than reconciled behind your back.
berrywiki serve my-wiki --author "Ada Lovelace <ada@example.org>"
berrywiki serve my-wiki --no-commit--author sets the commit identity; without it BerryWiki uses the git config
of the clone. --no-commit serves the folder without touching git at all, if
you would rather commit by hand — and a folder that is not a git working tree
falls back to that automatically, with a warning.
What is still missing is the resolving of a conflict once one exists: it is
detected and shown, on one /conflicts page for the whole wiki, but you finish
the job in git. See Roadmap.