zetl — help
Bi-directional wikilink graph CLI with optional defeasible reasoning, vault history, and a multi-user collaborative web UI. To override this page, drop a help.html in .zetl/themes/<theme>/.
Install
Requires a Rust toolchain (rustup). Clone the repo, then install the variant you want:
git clone https://codeberg.org/anuna/zetl
cd zetl
# wikilink features only
make install
# with defeasible reasoning
cargo install --path . --features reason
# with vault history (jj-backed temporal snapshots)
cargo install --path . --features history
# everything (reasoning + history + semantic search + MCP)
cargo install --path . --features "reason,history,semantic,mcp"
Collaboration mode (--collab) is always available. SPL-based access control needs --features reason.
Quick start
# point zetl at any vault of markdown files
zetl -d ./my-vault index # build/refresh the link index
# explore the graph
zetl -d ./my-vault links "Some Page"
zetl -d ./my-vault backlinks "Some Page" --depth 2
zetl -d ./my-vault path "Page A" "Page B"
# search and validate
zetl -d ./my-vault search "query"
zetl -d ./my-vault check
# this web UI
zetl -d ./my-vault serve # http://localhost:3000
# static export
zetl -d ./my-vault build # writes ./dist
Tip: when run from inside the vault directory, you can omit -d.
Common commands
zetl index— build/refresh the link indexzetl links <page>/zetl backlinks <page>— graph querieszetl path A B— shortest link path between two pageszetl similar <name>— fuzzy page-name matchzetl search "query"— full-text search (--regexfor patterns)zetl check— dead links, orphans, syntax/SPL diagnosticszetl blocks <page>— content-addressable block hasheszetl view <page>— Xanadu two-pane page viewerzetl serve/zetl build— web UI / static sitezetl --help— full CLI reference
History & time travel
Built with --features history:
zetl history log # graph evolution timeline
zetl history page "Some Page" # page evolution
zetl --at "3 days ago" links "Page" # query any read-only command at a point in time
zetl watch # auto-snapshot on file changes
Reasoning
Built with --features reason. Embed Spindle Lisp in ```spl code blocks or standalone .spl files, then:
zetl reason status # vault-wide conclusions
zetl reason explain "release-candidate" --format natural
zetl reason why-not "docs-updated"
zetl reason conflicts --suggest
Collaboration
# first-time setup (saves a 12-word recovery phrase)
zetl serve --collab --init-owner --owner-name Alice
# subsequent runs
zetl serve --collab
# invite a collaborator (link copies to clipboard)
zetl invite --as Alice --role editor
Roles: reader, editor, admin. Authentication uses WebAuthn passkeys with BIP39 mnemonic recovery. Real-time co-editing syncs over WebSocket via a Peritext CRDT.
Customising
- Themes: override Minijinja templates in
.zetl/themes/<name>/(base.html,index.html,page.html,folder.html,help.html, …). Missing templates fall back to the bundled defaults. Activate with--theme <name>. - Static assets: drop CSS/JS/images in
.zetl/themes/<name>/static/— served at/_static/. - Hooks: executable scripts in
.zetl/hooks/atpre-build,post-build,post-index,post-check,pre-serve,on-save,on-agent,on-access-request. Receive vault context as JSON on stdin.
More
Source, issues, and full docs: codeberg.org/anuna/zetl.