Installation
One command per shell. System-wide by default, per project when you want nothing on your PATH, or from source with cargo. What each path writes to disk, and how to undo it.
madelog is one binary with no runtime dependencies. Git is required. Git AI and Ollama are optional: Git AI adds AI sessions, Ollama adds model-written summaries. Every install path ends by running madelog onboard, which tells you what is missing.
System-wide
The default. The script downloads the release archive for your platform from GitHub Releases, checks its SHA-256 against the published SHA256SUMS, installs the binary and adds its directory to your shell's PATH if it is not there yet.
macOS and Linux:
$ curl -fsSL https://madelog.app/install.sh | shWindows, in PowerShell:
> irm https://madelog.app/install.ps1 | iexWhat the shell script does, in order:
- Refuses to run as root. Pass
--allow-rootto override. - Picks a target from
uname:aarch64-apple-darwin,x86_64-apple-darwin,x86_64-unknown-linux-gnuoraarch64-unknown-linux-gnu. Anything else stops with a message pointing atcargo install madelog. - Downloads
SHA256SUMSfrom the latest release, finds the line formadelog-<version>-<target>.zip, downloads that archive and compares its SHA-256. A mismatch prints both hashes and stops; nothing is installed. - Unpacks the archive and moves the binary to
~/.local/bin/madelogwith mode 755. On macOS it also removes thecom.apple.quarantineattribute. - If
~/.local/binis not on your PATH, appends two lines to your shell's rc file: a comment# added by the madelog installerand the export. The file depends on$SHELL:~/.zshrcfor zsh,~/.bash_profilefor bash on macOS,~/.bashrcfor bash on Linux,~/.config/fish/config.fishfor fish (withfish_add_path),~/.profileotherwise. If the file already names the directory, nothing is appended. - Runs
madelog onboardwith the terminal as its input, so the questions reach you even though the script itself was piped throughsh.
The PowerShell script mirrors it: it refuses an elevated shell (-AllowRoot overrides), downloads the x86_64-pc-windows-msvc archive, checks the sum with Get-FileHash, installs to %LOCALAPPDATA%\madelog\bin\madelog.exe, runs Unblock-File on it, and adds that directory to your user PATH through [Environment]::SetEnvironmentVariable("Path", ..., "User"). On an ARM64 machine it installs the x64 build and tells you it runs under emulation.
Open a new shell afterwards if madelog is not found. PATH changes apply to new sessions only; the installer exports the directory into its own process so that madelog onboard can run, but your current shell does not see it.
Flags and variables
Flags go after sh -s -- on macOS and Linux, and as parameters to the script block on Windows.
| Shell flag | PowerShell parameter | Effect |
|---|---|---|
--project | -Project | Per-project install, described below |
--version X.Y.Z | -Version X.Y.Z | Install that release instead of the latest |
--no-onboard | -NoOnboard | Stop after installing; do not run madelog onboard |
--allow-root | -AllowRoot (alias -AllowAdmin) | Install anyway from a root or elevated shell |
-h, --help | Print the header of the script and exit 0 |
| Variable | Effect |
|---|---|
MADELOG_INSTALL_DIR | The system-wide destination directory. Default ~/.local/bin, or %LOCALAPPDATA%\madelog\bin |
MADELOG_INSTALL_URL | A base URL or file:/// directory that holds SHA256SUMS and the archives, for testing against a local build instead of GitHub |
$ curl -fsSL https://madelog.app/install.sh | sh -s -- --version 0.1.0 --no-onboard
madelog 0.1.0 for aarch64-apple-darwin
downloaded madelog-0.1.0-aarch64-apple-darwin.zip, sha256 verified
installed ~/.local/bin/madelog
~/.local/bin is on your PATHNothing else is written. The scripts send no telemetry and create no account.
Per project
For one repository only. The binary is installed to <repo>/.madelog/bin/madelog, git is told to ignore .madelog/ through .git/info/exclude, and the post-commit hook calls the binary by its full path. Your PATH and your shell rc files are not touched. Run it inside the repository:
$ curl -fsSL https://madelog.app/install.sh | sh -s -- --project> & ([scriptblock]::Create((irm https://madelog.app/install.ps1))) -ProjectThe script finds the repository root with git rev-parse --show-toplevel and stops if you are not inside one. It ends with MADELOG_EXE=<repo>/.madelog/bin/madelog madelog onboard --project, which runs madelog init without asking the four questions. The hook line it writes:
# madelog-cli:post-commit - records this commit in .madelog/log.db
/Users/ana/projects/ledger/.madelog/bin/madelog hook post-commit || trueBecause the questions were skipped, the intent event is empty and the page's headline falls back to "How ledger came together". To fill it in, run the binary by its path with all four answers:
$ .madelog/bin/madelog init --what "A CLI that reconciles bank CSV exports against invoices" \
--for-whom "A small accounting firm" --tools "claude-code, cursor" --record-ai-sessionsThat appends a new intent event; the page reads the newest one. To use the binary by hand for anything else, call it by its path or add .madelog/bin to your PATH for that shell.
From source
With a Rust toolchain installed:
$ git clone https://github.com/vanjamodrinjak21/madelog
$ cd madelog
$ cargo install --path cli
$ madelog onboardcargo install puts the binary in ~/.cargo/bin, which the Rust installer already adds to your PATH. Until the first release is tagged, this is the only way to get a binary. The install scripts will report the release has no build for <target> until then.
Check the install
$ madelog --version
madelog 0.1.0
$ madelog onboard
+---+
| +-+-+ madelog - Proof of Process
+-+-+ | Records how your project came together.
+---+
madelog records three things: the commits you make, the AI sessions Git AI attributes to them, and the one-sentence decisions you write with `madelog note`.
All of it stays on this machine, in .madelog/log.db, until you run `madelog publish`.
No keystrokes, no screenshots, no files git ignores. `madelog export` hands you everything back as JSON.
git found /opt/homebrew/bin/git
git-ai missing Without it, AI sessions stay empty. Install it with: curl -sSL https://usegitai.com/install.sh | bash
ollama found /usr/local/bin/ollama
You are not inside a git repository, so there is nothing to record yet.
Do this next:
git init
madelog initThe banner is drawn with box characters when standard output is a terminal, TERM is not dumb, and your locale names UTF-8 (on Windows, when WT_SESSION is set, which Windows Terminal does). Otherwise it is drawn in ASCII, as above.
Verifying a download
Every release carries a SHA256SUMS file next to the archives. The install scripts check it for you. To check a download by hand, fetch the archive and the sums for a version and target, then compare:
$ v=0.1.0; t=aarch64-apple-darwin
$ curl -fsSLO https://github.com/vanjamodrinjak21/madelog/releases/download/v$v/madelog-$v-$t.zip
$ curl -fsSLO https://github.com/vanjamodrinjak21/madelog/releases/download/v$v/SHA256SUMS
$ shasum -a 256 -c --ignore-missing SHA256SUMS
madelog-0.1.0-aarch64-apple-darwin.zip: OKOn Linux use sha256sum -c --ignore-missing SHA256SUMS. In PowerShell, compute the hash and read the expected one from the file:
> (Get-FileHash .\madelog-0.1.0-x86_64-pc-windows-msvc.zip -Algorithm SHA256).Hash.ToLower()
> Select-String x86_64-pc-windows-msvc .\SHA256SUMSThe two 64-character hashes must match exactly. Targets: aarch64-apple-darwin, x86_64-apple-darwin, x86_64-unknown-linux-gnu, aarch64-unknown-linux-gnu, x86_64-pc-windows-msvc. Each archive holds the binary and the MIT licence, nothing else.
What is on disk after install
| Path | Written by | Purpose |
|---|---|---|
~/.local/bin/madelog | system-wide install | The binary. %LOCALAPPDATA%\madelog\bin\madelog.exe on Windows, ~/.cargo/bin/madelog after cargo install |
| one line in your shell rc | system-wide install, only when needed | Puts the binary's directory on PATH |
<repo>/.madelog/bin/madelog | per-project install | The binary, ignored by git |
~/.config/madelog/device.key | the first madelog init | 32-byte ed25519 secret key as 64 hex characters plus a newline, mode 0600 in a 0700 directory. Same path on every OS, including Windows (C:\Users\<you>\.config\madelog\device.key) |
<repo>/.madelog/ | madelog init | log.db, config.toml, intent.md, later site/index.html |
<repo>/.git/hooks/post-commit | madelog init | Two lines appended, or a new file with #!/bin/sh on top |
<repo>/.git/info/exclude | madelog init | One line, .madelog/ |
Uninstall
macOS and Linux:
$ rm ~/.local/bin/madelog # or ~/.cargo/bin/madelog after cargo install
$ rm -r ~/.config/madelog # the device key; read the note below firstThen remove the two lines the installer added to your rc file, if it added any:
$ grep -n "madelog" ~/.zshrc # or ~/.bashrc, ~/.bash_profile, ~/.profile, config.fishPowerShell:
> Remove-Item -Recurse "$env:LOCALAPPDATA\madelog"
> Remove-Item -Recurse "$HOME\.config\madelog"
> $p = [Environment]::GetEnvironmentVariable("Path", "User")
> [Environment]::SetEnvironmentVariable("Path", (($p -split ";") -notmatch "madelog" -join ";"), "User")Per repository, from its root:
$ rm -r .madelog # the log, the config, the rendered page, a per-project binary
$ sed -i.bak '/# madelog-cli:post-commit/,+1d' .git/hooks/post-commit
$ sed -i.bak '/^\.madelog\/$/d' .git/info/excludeThe hook file keeps whatever it held before madelog added its two lines. A hook that is left behind is harmless: the line ends in || true, so a missing binary cannot fail a commit. You will see .git/hooks/post-commit: line 5: madelog: command not found on every commit until you remove the line. With the binary present but .madelog/ gone, the hook exits 0 and prints nothing.
The device key in ~/.config/madelog/device.key signs every publish. If you delete it and later reinstall, the new key is a new device to the server, and a page published with the old key can no longer be replaced or taken down from this machine: the server answers 401 to the old device id and 403 to a new one. Keep the key, or take the page down with madelog unpublish first. Configuration has the details.