bob¶
- ID
bob- Link
- Upstream stars
⭐ 2,146
- Last commit
2026-09-28
- Platforms
🐧 Linux · 🍎 macOS · 🪟 Windows
- Operations
installed·search·install·upgrade·upgrade_all·remove- purl types
pkg:bob/- CLI name
bob- Issues and PRs
- Source
bob is a version manager for Neovim (https://github.com/MordechaiHadad/bob), installing the editor’s own releases from https://github.com/neovim/neovim.
A package is a version token, and every verb agrees on it: install,
uninstall, update and use all take exactly one, and the listing prints
one per row. Both shapes of token are real packages: a released tag such as
v0.12.4, and the rolling nightly. That is the reading rustup settled,
where the object the verbs agree on is what counts as a package.
Parsing notes, verified against bob 4.1.7 on macOS:
No
installed_versionis captured, deliberately, followingpyenvandrustup. The token is the identity rather than a version field:nightlyis not a version at all, and one pattern has to serve both shapes, so reporting the whole token as a version would be wrong for every rolling channel. mpm treats the installed version as optional throughout.The listing is a box-drawing table, and its
Statuscolumn is the anchor that reads it. bob prints exactly two statuses,Usedfor the active version andInstalledfor the rest, so requiring one of them is what rejects the header row, whose second column readsStatus, along with the three border rows, which open on a different box character. Requiring the token to look like a version would have droppednightlyinstead.Colors are unconditional. bob writes the SGR escapes around its status and around the stable entry of the catalog whether or not it is writing to a terminal, and honors neither
NO_COLORnorTERM=dumb, all three verified. Nothing is forced to suppress them: mpm searches each line rather than anchoring it, so the patterns step over the escapes instead of fighting them.Both patterns are deliberately insensitive to whitespace and column width. The table widens from seven columns to sixteen when a nightly rollback exists, and upstream removed the padding from the catalog outright in
v4.1.4(MordechaiHadad/bob#333), so alignment is the one thing about this output that has already changed.The catalog lists released tags alone, and that costs more than a search hit.
nightlynever appears in it, so mpm, which resolves a package it was handed no manager for by searching the catalog first, refuses to install a channel bob itself installs without complaint. Naming the manager does not help: the lookup is what supplies the candidate. An installednightlystill lists, upgrades and removes normally, since those read the inventory rather than the catalog.A search here is broader than it looks, because the ids are versions. mpm’s default matching is fuzzy and counts any alphanumeric segment of the query, so
0.12.4splits into0,12and4and matches nearly every tag Neovim ever cut.--exactis what narrows it to one.No
outdated: nothing reports staleness without acting on it,updatecomputing what is behind and installing it in the same pass.No
cleanup:bob erasedeletes every installed version along with bob’s own configuration, which is a mass removal rather than reclamation. The same reading leftluarocks purgeunmapped.
Caution
bob sync is not mpm’s sync and is deliberately left unmapped. It reads a
version file from the working directory and installs whatever that names,
which is project scope rather than a metadata refresh. Nothing in bob
refreshes its catalog without also acting, so no sync is declared at all.
Note
An empty inventory is not an error: bob list writes a timestamped
There are no versions installed line to standard output and exits zero. It
carries no table row, so the pattern yields nothing and mpm reports an empty
inventory rather than a failure.
What mpm adds to bob¶
Through mpm, bob gains --exact and --extended search, to narrow to exact names or match descriptions.
Bigger still, mpm reaches across every manager at once: mpm installed and mpm outdated cover bob alongside every other manager you run in one table, mpm upgrade --all updates them together, and mpm sbom exports the whole machine as one bill of materials.
Every mpm command also gains --dry-run and --plan previews, cross-scheme version comparison and purl identifiers. See manager augmentations for how each one is built.
Your bob commands, in mpm¶
You already know bob: each operation maps one-to-one onto mpm, in an interface shared by every manager.
To… |
With |
With |
|---|---|---|
List what’s installed |
|
|
Search for a package |
|
|
Install a package |
|
|
Upgrade one package |
|
|
Upgrade everything |
|
|
Remove a package |
|
|
Prefix any command above with --dry-run to simulate the underlying manager calls without touching the system: the safe way to watch what mpm would do before trusting it.
Operations¶
Operation |
Supported |
Notes |
|---|---|---|
|
✅ |
|
|
||
|
||
|
✅ |
Exact and extended search backfilled by |
|
✅ |
|
|
✅ |
|
|
✅ |
|
|
✅ |
|
|
||
|
||
|
Configuration¶
Ignore
bobon thempmCLI by passing the--no-boboption.Ignore it for every run in your configuration:
[mpm] bob = false
Raise the timeout of all
bobcalls:[mpm.overrides.bob] timeout = 900
Run
mpm config-template bobto print all overridable settings for your configuration file:[mpm.overrides.bob] cli_names = [ "bob", ] cli_search_path = [] dry_run = false ignore_auto_updates = true plan = false post_args = [] pre_args = [] pre_cmds = [] stop_on_error = false unmaintained = false version_cli_options = [ "--version", ] version_regexes = [ "bob-nvim[ \\t]+(?P<version>\\S+)", ]
Recipes¶
A few jobs you would otherwise script around bob, one mpm command each:
Snapshot and clone a machine:
mpm --bob dump bob.toml, thenmpm restore bob.tomlon the next one.Export a compliance SBOM:
mpm --bob sbom(CycloneDX by default,--spdxfor SPDX).
Privilege escalation¶
mpm runs this manager as the current user and never prepends sudo by default. Flip the policy for its privileged operations with --sudo or the per-manager sudo override.
None of its operations is privileged.
See privilege escalation for the full policy.
Cooldown¶
State of bob’s release-age gating, from the cooldown support table:
Status: ❌ None (installs Neovim’s own GitHub releases)
A cooldown only pays off where a compromised release can be withdrawn while the clock runs, and can only be emulated where the registry dates its releases. From the retraction table:
Registry: GitHub release assets
Retraction: None: withdrawing a build is the upstream author deleting their own release or tag. Nothing sits between them and the user
Publish date: ✅ server-set
published_aton each release (REST API)
With --cooldown set, mpm skips this manager’s install and upgrade operations rather than run them unguarded (fail-closed); --cooldown best-effort opts back in.
Reference traces¶
A collection of raw native outputs captured from the manager’s own CLI and recorded in the bundled definition. If you know bob well and a transcript below looks wrong, or a newer release changed its output format, report it.
$ bob list
┌───────────┬─────────────┐
│ Version │ Status │
├───────────┼─────────────┤
│ nightly │ [33mInstalled[0m │
│ v0.12.4 │ [32mUsed[0m │
└───────────┴─────────────┘
Version check¶
The version is probed by running:
$ bob --version
bob-nvim 4.1.7
and extracted with:
r"bob-nvim[ \t]+(?P<version>\S+)"
Upstream project¶
Metrics |
|
|---|---|
Activity |
|
Popularity |
|
Metadata |
|
Changelog¶
8.0.0(2026-09-20)Add the bob Neovim version manager with
installed,search,install,removeandupgradesupport, a version token being what it calls a package,nightlyincluded.