Get started

Install it, point it at your accounts, and see what has drifted.

Install

On macOS and Linux:

Terminal
curl -fsSL https://m.canouil.dev/minato/install.sh | bash

On Windows:

PowerShell
powershell -ExecutionPolicy ByPass -c "irm https://m.canouil.dev/minato/install.ps1 | iex"

Either script detects your platform, verifies the download against the release SHA256SUMS, and puts the binary somewhere you can run it: /usr/local/bin when writable and otherwise ~/.local/bin, or %LOCALAPPDATA%\Programs\minato on Windows, which it adds to your user PATH when it is not already there. Set MINATO_VERSION to pin a release, MINATO_INSTALL_DIR to choose where it lands, or MINATO_SKIP_CHECKSUM=1 to bypass verification. The shell script needs bash and curl. The PowerShell one runs on Windows PowerShell 5.1 as well as PowerShell 7, and takes MINATO_NO_MODIFY_PATH=1 to leave PATH alone.

Terminal
cargo install --git https://github.com/mcanouil/minato --tag <version>

Every release carries an archive for macOS on Apple silicon and Intel, Linux on x86-64 and ARM64, and Windows on x86-64 and ARM64, each holding the binary alone.

Terminal
curl -fsSLO https://github.com/mcanouil/minato/releases/download/<version>/minato-<version>-<target>.tar.gz
curl -fsSLO https://github.com/mcanouil/minato/releases/download/<version>/SHA256SUMS
sha256sum --ignore-missing --check SHA256SUMS
tar -xzf minato-<version>-<target>.tar.gz
sudo install minato /usr/local/bin/minato

On macOS, shasum -a 256 --ignore-missing --check SHA256SUMS does the same job. On Windows, unzip the archive and put minato.exe somewhere on PATH.

Terminal
git clone https://github.com/mcanouil/minato && cd minato
cargo install --path .

No host toolchain is needed beyond Docker. The provided .devcontainer/ carries Rust, git, gh, jq, and kata.

Terminal
devcontainer up --workspace-folder .
devcontainer exec --workspace-folder . cargo install --path .

See CONTRIBUTING.md for the full setup, including token handling.

Minato shells out to git, so it needs a git binary on PATH. Doing so is deliberate: your SSH agent, credential helpers, and git configuration all apply unchanged.

Enable completion

Terminal
minato completions --install

That writes the script where the shell reads it, taking the shell from $SHELL unless you name one, and edits your shell’s configuration only where the file alone is not enough. --dry-run reports every path it touches first, and --uninstall removes what it wrote.

Open a new shell, then minato <Tab> lists the commands and minato clone --<Tab> lists that command’s flags.

Without --install, minato completions <shell> prints the script to standard output and where it belongs to standard error, so a redirect captures the script alone and the instructions still reach your terminal. Shells sets out every destination, the configuration each shell needs, and how to do it by hand.

PowerShell is the one that is never written to a file: it evaluates the script from $PROFILE instead.

PowerShell
minato completions powershell | Out-String | Invoke-Expression

The script comes from the same definitions the binary is built from, so it can never offer a command that does not exist. It does have to be regenerated after an upgrade that adds one, which minato doctor reports and --install carries out.

In bash, zsh, and fish, flags with a fixed set of values complete those too, so minato status --state <Tab> offers all eight states. The powershell and elvish scripts complete commands and flag names only.

Authenticate

No token is ever stored by Minato. It reads one from MINATO_GITHUB_TOKEN, then GITHUB_TOKEN, then the gh CLI, so it stays wherever you already keep it.

Terminal
gh auth login

Check what it found, without ever printing the token itself:

Terminal
minato auth status
Output
Authenticated to GitHub using the gh CLI.

Configure

Configuration is TOML at ~/.config/minato/minato.toml, or wherever MINATO_CONFIG points. Running minato doctor before it exists prints a sample to start from.

~/.config/minato/minato.toml
[providers.github]
users = ["your-username"]
orgs = []

[local]
roots = ["~/Projects"]
layout = "{repo}"
protocol = "ssh"

[cache]
ttl = "15m"

roots are searched for existing clones. A clone is matched to a repository by its remote URL rather than by where it sits, so one root covers any arrangement of folders beneath it.

Check everything is usable

doctor reports on every check rather than stopping at the first problem.

Terminal
minato doctor
Output
    CHECK          DETAIL
ok  git            2.55.0
ok  token          found in the gh CLI
ok  configuration  /Users/you/.config/minato/minato.toml
ok  roots          /Users/you/Projects
ok  cache          /Users/you/.cache/minato
ok  completions    current: /Users/you/.zfunc/_minato

A completion script is a copy of the command surface taken when it was generated, so an upgrade that adds a command leaves it offering the old one. doctor compares each script it finds against what the binary generates now, and prints the command to rewrite any that has fallen behind.

Output
!!  completions    1 of 2 found out of date

completions:
1 of 2 found out of date
Regenerate:
  minato completions fish --install

The places searched are the ones set out in Shells, with $ZSH_CUSTOM honoured when oh-my-zsh has been moved. A shell you have not set up is never mentioned, and PowerShell is not searched at all, since its script is evaluated from $PROFILE rather than saved to a file.

See what has drifted

Terminal
minato status --state drifted

Forks and clones of repositories you do not own are left out by default, so this is the repositories you maintain. Add --include-forks or --include-external to bring them back.

Provider responses are cached for the cache.ttl window, fifteen minutes by default, so a second run is effectively instant, and cached output always says how old it is. Set cache.ttl to any friendly duration such as "1h", or add --refresh to ask again straight away.

Close the gap

Every command that changes anything takes --dry-run first.

Terminal
minato fetch                      # always safe: never touches a working tree
minato update --dry-run           # see what would be fast-forwarded
minato update                     # do it

update fast-forwards only what is strictly behind and has no modified tracked files. Everything else is reported with the reason.

Terminal
minato sync-fork --dry-run        # see which forks would sync with upstream
minato sync-fork                  # fast-forward each behind fork on GitHub

sync-fork uses GitHub’s merge-upstream, so it fast-forwards a fork only when it is strictly behind its upstream. A fork holding its own commits is reported and left alone rather than merged.

Record the tree, and put it back

A scan says what is on this machine now. A manifest says what the tree should hold, so a rebuilt or second machine can be brought back to the same layout.

Terminal
cd ~/Projects
minato manifest write             # record every clone, into ~/Projects/.minato.toml

The file sits in the tree it describes, and every path in it is relative to that directory. Sync the directory however you already sync anything, and the layout travels with it: nothing has to agree about absolute paths, and no configuration is read to restore it.

Terminal
minato manifest diff              # what the record and the tree disagree about
minato manifest apply --dry-run   # what restoring would clone
minato manifest apply             # clone what is recorded and missing here

A clone sitting somewhere other than its recorded place is reported and left alone, since someone put it there. Add --relocate to move those into the recorded place instead.

Recording is additive: a repository you do not have here is kept in the file, because the machine that does have it shares the same record. Drop one deliberately.

Terminal
minato manifest forget minato     # stop recording it; the clone is untouched

Once a tree holds a manifest, minato clone and minato move keep it up to date, and any command run from inside the tree works on it even on a machine with no configuration yet.

Browse it instead

Terminal
minato tui

Every action the interface offers calls the same function the matching command calls, so nothing can be done there that cannot be scripted.

See every command

Back to top