Install
May 29, 2026 ยท View on GitHub
_ __
| | / /___ __ ______ _____ ____
| | / / __ \/ / / / __ `/ __ `/ _ \
| |/ / /_/ / /_/ / /_/ / /_/ / __/
|___/\____/\__, /\__,_/\__, /\___/
/____/ /____/
Plus loin que la nuit et le jour
Relational navigation CLI for Markdown notes.
vo <note.md> recursively scans the note's parent directory, builds an in-memory index, resolves wikilinks, and prints outgoing links for the target note.
Install
Latest published release:
curl -fsSL https://raw.githubusercontent.com/0xJohnnyboy/voyage/main/scripts/install.sh | sh
Pinned version:
curl -fsSL https://raw.githubusercontent.com/0xJohnnyboy/voyage/main/scripts/install.sh | sh -s -- --version v0.1.0
Custom install dir:
curl -fsSL https://raw.githubusercontent.com/0xJohnnyboy/voyage/main/scripts/install.sh | sh -s -- --install-dir "$HOME/.local/bin"
The installer does not modify your shell profile automatically. If needed, it prints the exact
export PATH="<dir>:$PATH" line to add.
Uninstall:
rm -f /usr/local/bin/vo
# or, if installed elsewhere:
rm -f "$HOME/.local/bin/vo"
Usage
vo [options] <path-note.md>
Running vo without arguments prints a short banner + version + compact usage. Use -h for full help with all options.
Example vault and commands: example/README.md
Options:
-v,--versionprint version and exit-s,--sortdiscovery|alpha(default:discovery)-f,--formatsimple|detailed|json(default:simple)-w,--showtitle|path(default:title)-m,--modelinks|tags|categories(default:links)-p,--scopeup:N|root:<path>(default:up:0)-l,--longalias for--format detailed-d,--danglingshow unresolved links (default:true)-D,--no-danglinghide unresolved links-L,--log-levelsilent|warn|debug(default:warn)-t,--treerender outgoing relations as a tree (overrides list formatting)-n,--depthtree depth (default:1, valid only with--tree)-c,--colorauto|always|never(default:auto)--format jsonis valid only with--tree
Examples
vo notes/index.md
vo -s alpha notes/index.md
vo -l -D notes/index.md
vo --format detailed --dangling notes/index.md
vo --show path -D notes/index.md | xargs head -n 10
vo --scope up:2 notes/deep/note.md
vo --scope root:./notes notes/deep/note.md
vo --mode tags notes/index.md
vo --mode categories --tree --depth 1 notes/index.md
vo -t -n 3 notes/index.md
vo -t --long --no-dangling notes/index.md
vo -t -n 3 --format json notes/index.md
vo --color always notes/index.md
Related
voyage.nvim integrates a Telescope-like file picker with vo as a backend. For a lightweight zettelkasten-like note taking experience, try out scretch.nvim.
JSON Tree Contract (V1)
Machine-oriented JSON output is available for tree mode:
vo --format json --tree --depth <N> <path-note.md>
Success payload:
{
"schema_version": "1.1.0",
"mode": "links",
"root": {
"id": "/abs/path/to/index.md",
"label": "Home",
"path": "/abs/path/to/index.md",
"dangling": false,
"node_kind": "note",
"children": [
{
"id": "/abs/path/to/a.md",
"label": "A",
"path": "/abs/path/to/a.md",
"dangling": false,
"node_kind": "note",
"children": []
},
{
"id": "dangling:Missing Note",
"label": "Missing Note",
"path": "",
"dangling": true,
"node_kind": "note",
"children": []
}
]
}
}
Node contract:
iddeterministic string identifierlabeldisplay labelpathabsolute path for resolved notes, empty string for danglingdanglingboolean (truefor unresolved wikilinks)node_kindone ofnote|tag|categorychildrenarray of nodes
When using --mode tags or --mode categories in tree mode:
- root stays the target note
- level alternates
note -> tag/category -> note --depth 1includes one semantic hop (attribute + associated notes)
Error payload (--format json):
{
"schema_version": "1.0.0",
"error": {
"code": "json_requires_tree",
"message": "--format json is only valid with --tree"
}
}
On error, Voyage returns a non-zero exit code.
Build and Versioning
Build:
make build
Output binary: dist/vo-<goos>-<goarch> (example: dist/vo-linux-amd64)
Cross-platform builds:
make build-all
This currently generates:
dist/vo-linux-amd64dist/vo-darwin-amd64dist/vo-darwin-arm64
Version:
./vo -v
./vo --version
Build-time versioning:
{tag}whenHEADis exactly on a tag{tag}-{short-hash}otherwisedevwhen no tag exists