0.7.0
Install
Quick install (script)
curl -fsSL https://m.canouil.dev/oboro/install.sh | bash
# or pin this exact release
curl -fsSL https://m.canouil.dev/oboro/install.sh | bash -s -- --version 0.7.0The script picks the archive for your machine, verifies it against SHA256SUMS, and installs into /usr/local/bin when writable, otherwise ~/.local/bin.
It needs bash and curl; on a minimal distribution such as Alpine, install them first with apk add bash curl.
Add --features ner for the build that also finds untold names (on Linux it needs glibc 2.39+), then fetch its model:
curl -fsSL https://m.canouil.dev/oboro/install.sh | bash -s -- --version 0.7.0 --features ner
oboro models pull # about 348 MB, once, verified against pinned hashesDocker
docker volume create oboro-vault
docker run --rm \
-v oboro-vault:/vault \
-v "$PWD":/work -w /work \
--user "$(id -u):$(id -g)" \
ghcr.io/mcanouil/oboro:0.7.0 clean contract.docxThe vault volume is not optional.
Without it the mapping between placeholders and real values disappears with the container, and the document can never be restored.
The ghcr.io/mcanouil/oboro:0.7.0-ner tag carries the ner build with the recognition model already inside the image, so untold names are found with no download and no network at run time.
A prebuilt binary
Pick the archive for your machine from the table below, then:
VERSION=0.7.0
TARGET=x86_64-unknown-linux-musl # or whichever row matches
curl -fsSLO "https://github.com/mcanouil/oboro/releases/download/${VERSION}/oboro-${VERSION}-${TARGET}.tar.gz"
curl -fsSLO "https://github.com/mcanouil/oboro/releases/download/${VERSION}/SHA256SUMS"
# Check it is what was published.
sha256sum --ignore-missing --check SHA256SUMS
tar -xzf "oboro-${VERSION}-${TARGET}.tar.gz"
install -m 0755 oboro /usr/local/bin/oboroOn macOS, shasum -a 256 --ignore-missing --check SHA256SUMS does the same job.
With Rust already installed
cargo install --git https://github.com/mcanouil/oboro --tag 0.7.0From source, with the optional features
The default binaries read .txt, .md, .docx, .xlsx and text-based .pdf, and find structured values and anything on your denylist.
They do not find names nobody told them about, and they do not read images.
Names need a -ner archive from the table below (then oboro models pull), the :0.7.0-ner image, or a source build.
Images need the Tesseract system libraries, so reading them stays a source build:
cargo build --release --features ner # names and organisations, then: oboro models pull
cargo build --release --features ocr # images and scanned pages, needs TesseractIf names are not being redacted, a default build is almost certainly why.
oboro doctor reports what any build can do.
To build the optional features without setting up the system libraries on your machine, use the devcontainer, which carries the pinned toolchain, Tesseract and the OCR libraries:
docker build -f .devcontainer/Dockerfile -t oboro-dev .devcontainer
docker run --rm -it -v "$PWD":/work -w /work -u vscode oboro-dev \
cargo build --release --features "ner,ocr"In Visual Studio Code or a GitHub Codespace, reopen the folder in the container instead.
Verify what you downloaded
Beyond the checksum, every archive carries build provenance, so you can confirm it came from this repository's workflow and not from somewhere else:
gh attestation verify "oboro-0.7.0-x86_64-unknown-linux-musl.tar.gz" \
--repo mcanouil/oboroThis tool checks the model it downloads against a pinned hash before using it.
It would be inconsistent to ask you to trust its own binaries on sight.
Which archive is which
| Archive | For |
|---|---|
x86_64-unknown-linux-musl |
Linux on Intel or AMD. Statically linked, so any distribution, glibc version or Alpine. |
aarch64-unknown-linux-musl |
Linux on ARM, including most cloud instances. Statically linked. |
aarch64-apple-darwin |
macOS on Apple silicon. |
x86_64-pc-windows-msvc |
Windows on Intel or AMD. |
x86_64-unknown-linux-gnu-ner |
Linux on Intel or AMD, with name recognition. Needs glibc 2.39+ (Ubuntu 24.04+, Debian 13+). |
aarch64-unknown-linux-gnu-ner |
Linux on ARM, with name recognition. Needs glibc 2.39+. |
aarch64-apple-darwin-ner |
macOS on Apple silicon, with name recognition. |
The -ner archives find untold names once the model is fetched with oboro models pull; the others are the smaller default build.
The Windows archive is a .zip; extract it with Expand-Archive.
Documentation
Changes
Breaking changes
- feat!: Accept
--vaultand--keyafter the command that opens a vault rather than before it, sooboro --vault work.db clean notes/becomesoboro clean --vault work.db notes/.OBORO_VAULTandOBORO_KEY_FILEare unaffected, and so is every spelling that already named the command first, which is every one the documentation ever showed. Declaring the pair once at the root made them global, and global meant listed under every subcommand's help, includingoboro skill show,oboro models pullandoboro hook install, none of which ever open a vault: they were accepted there and quietly ignored, and the completion script offered them there too, so the help, the completion and the behaviour disagreed in the same place. They are now declared on the commands that use them, still global so that one declaration onmapcoversmap listandmap purgewithout being repeated on either, and the commands that never open a vault refuse them instead of taking them and doing nothing. (#102)
Features
- feat: Print a shell completion script with
oboro completions <shell>, forbash,zsh,fish,elvishandpowershell. The script goes to standard output and the destination it belongs in goes to standard error alongside it, so one command answers both halves of a question a generated script only ever answers half of:oboro completions zsh > ~/.oh-my-zsh/custom/completions/_oborowrites a file with nothing in front of it for the shell to trip over, the instructions still reach the terminal where they are useful at that moment, and2>/dev/nulldrops them for anyone scripting the command. Each shell is told its own convention rather than a generic sentence, including the leading underscore in the zsh filename and the two linescompinitneeds when the directory is not already on$fpath; oh-my-zsh is named first, because it puts$ZSH_CUSTOM/completionson$fpathand runscompinititself, so those users are finished once the file is written and the generic advice would send them to edit~/.zshrcfor no effect. The script is generated under the name the command carries rather than the name it was invoked by, so one written from a build directory or from a renamed copy still completes the installed name. (#101) - feat: Install a completion script with
oboro completions <shell> --install, which writes it where the shell reads it and edits your shell's configuration only where the file alone is not enough, inside a managed block that re-running replaces and--uninstallremoves.--dry-runreports every path either would touch. The shell is taken from$SHELLwhen it is left out, and printing to standard output is still what happens without a flag, so a redirect, or a pipe intoInvoke-Expression, works as before. PowerShell refuses to be installed and says what to run instead, since it evaluates its script from$PROFILErather than reading a file. - feat: Install zsh completions to oh-my-zsh's custom directory, or to Homebrew's
share/zsh/site-functionswhen the prefix has one and it is writable, before falling back to~/.zfuncwith anfpathline. The first two are on$fpathalready, so nothing is added to~/.zshrcfor them. Homebrew's prefix is read from$HOMEBREW_PREFIX, or found at/opt/homebrewor/usr/local, rather than by runningbrew, which acurl | bashpipe often cannot reach. - fix: Report a stale copy that cannot be removed, rather than failing on it. One of the places swept is Homebrew's prefix, which is outside the home directory and may belong to another user, and a file there is not reason enough to fail an install that has otherwise worked. Nothing is ever removed with elevated rights.
- feat: Keep an install where it is. A script already on disk is the one that is updated, wherever it is, even once the machine has gained oh-my-zsh, Homebrew or bash-completion and a first install would now choose elsewhere; copies in the other known places are swept so none is left to shadow it. Moving one is
--uninstallfollowed by a fresh install, and an unchanged script is reported asAlready currentrather than rewritten. - feat: Report in
oboro doctorwhether the completion scripts on disk still match the binary. A completion script is a copy of the command surface from the moment it was generated, so a release that adds a command leaves it offering the old set and nothing otherwise says so; each one is regenerated and compared byte for byte, which answers that exactly with no version to parse, and a stale one is followed by the command that rewrites it. Every conventional destination is looked in whatever$SHELLsays, since that variable is wrong often enough to matter and a place holding no file costs no line.docs/install.shlooks in the same places and prints the same command when it finds one, being the moment that knows a version changed. It now compares each script against the binary it has just installed rather than reporting every script it finds, so reinstalling the same version says nothing at all, and a first install stays quiet. (#101) - feat: Restrict the vault database and key on Windows with
icacls, dropping every inherited grant and giving the current account alone read and write; the key is protected before its bytes are written rather than after, and a directoryoborocreates gets an inheritable grant so the WAL and SHM sidecars pick it up without anicaclscall of their own.oboro doctorreports the ACL verdict the way it already reports the Unix file mode. - feat: Publish an
x86_64-pc-windows-msvc.zipfrom the release workflow, the default build only since ONNX Runtime and Tesseract stay source builds on Windows. Checksummed inSHA256SUMSand attested for build provenance alongside the other archives. (#106)