Most setups need no configuration: musubi hub, create, join, and clone write what
musubi needs. This page lists what you can set, and where musubi keeps its files.
Settings
musubi’s settings are jj’s, under musubi; it has no config file of its own. See and change
them with jj config:
jj config list musubi
jj config set --user musubi.daemon.log 'info,musubi_sync=debug'
musubi loads jj’s config files as jj does (system, user, repo, and workspace), so the
commits it makes when it merges concurrent work carry your identity, and are signed if you
sign commits.
This machine’s
musubi reads these as jj would outside any repository, so a repository’s config doesn’t
change them. Set them with --user.
| Key | Effect |
|---|---|
musubi.hub | The hub commands use without --hub, in place of the default this machine saved (the first hub it used, or on the hub’s own machine, that hub’s directory). Give it as --hub takes it: the name you ssh to the hub’s machine by, or on that machine, the hub’s directory, which may start with ~/. On the hub’s machine, its own name or localhost means the hub musubi hub serves there without --dir, reached without ssh. |
musubi.daemon.log | What the daemon logs, unless --log or RUST_LOG says. See Logging. |
musubi.daemon.socket | The path of the daemon’s control socket, in place of the usual one. See Files and directories. |
musubi.daemon.connections | as-needed, the default, for the daemon to keep one connection to each hub, which every repository there shares, and to open another for each transfer of 16 MiB or more while it lasts. one to keep to one connection to each hub, large transfers included, as where each new ssh is costly: through a tunnel that asks you to log in, say. |
musubi.templates.list | The template, in jj’s template language, musubi list prints each hub, hive and copy with, unless -T gives one. musubi list --help lists its keywords. |
The daemon reads musubi.daemon.* when it starts, so run musubi daemon restart after
changing them.
Each repository’s
musubi reads these as jj would in the repository, so any of jj’s config files can set them.
| Key | Effect |
|---|---|
musubi.forget-after | How long this copy may go unused before the hive forgets it: never, or a duration of at least a second, such as 30m, 6h, 1h 30m, or 2 days: numbers with units from s, min or m, h or hours, d or days, w or weeks, and so on (M is months, not minutes). musubi create, join, and clone set it unless jj’s config sets it already: 6h when a coding agent (Claude Code or Codex) runs them, never otherwise. Not shared across a hive. See Take a repository or machine out. |
musubi.shared-config | A list of further repo config keys for the hive to share, such as ["aliases.l"]. See Share settings. |
musubi.share-credentials | true to share the user and password an https remote URL may carry. Off by default; set it per machine. |
operation.hostname | This machine’s name in a hive, unless --machine gives another. |
git.executable-path | The git musubi runs, as jj does. |
snapshot.auto-update-stale | jj’s own: true makes every jj command update a working copy that another machine made stale. |
A hive always shares these repo config keys, whatever musubi.shared-config says:
revset-aliases."immutable_heads()", revset-aliases."trunk()", git.private-commits, and
musubi.shared-config itself.
Environment variables
| Variable | Effect |
|---|---|
RUST_LOG | What a command logs, unless --log says. See Logging. |
NO_COLOR | No colour, unless --color or your config’s ui.color asks for it, as for jj. See Colours. |
MUSUBI_SSH | The ssh program to run, in place of ssh. |
MUSUBI_SOCKET | The daemon’s control socket, in place of the usual one. Same as --socket. |
MUSUBI_STATE_DIR | One directory for musubi’s state and the daemon’s socket, in place of the usual ones. With JJ_CONFIG for its settings, this runs a second, separate musubi. |
COMPLETE | Set by your shell to have musubi complete what you type. See Complete commands in your shell. |
On macOS and Linux, musubi daemon install (and musubi hub install) passes your PATH,
and any MUSUBI_*, JJ_CONFIG, XDG_CONFIG_HOME, and XDG_STATE_HOME variables set when
you run it, to the service that starts the daemon (or the hub): run it again after changing
them. On Windows, the daemon started at login gets the login’s environment.
Logging
The hub and the daemon log what they do, at info, and only warnings from the jj library
they use (jj_lib). Other commands log only warnings, since they report what they did
themselves.
musubi hublogs to its terminal. Run at login bymusubi hub install, it logs on macOS tohub.login musubi’s state directory, starting the log afresh when it starts if it has passed 10 MiB, and on Linux to the journal:journalctl --user -u musubi-hub.musubi daemon, run in the foreground, logs to its terminal.- A daemon started in the background, by a command or at login, logs to
daemon.login musubi’s state directory, starting the log afresh when it starts if it has passed 10 MiB. Under systemd, it logs to the journal instead:journalctl --user -u musubi.
Logs are in colour only on a terminal, and then as for the rest of what musubi prints (see Colours). A log file never is, nor is anything else the hub or the daemon writes to one.
To choose what a command logs, pass --log with a filter in RUST_LOG’s syntax,
or set RUST_LOG; --log wins:
musubi --log debug hub
musubi --log musubi_sync=debug sync # each request a sync makes, without a daemon
When a daemon serves the repository, musubi sync asks it to sync, so the requests are the
daemon’s to log. To watch them, run the daemon in the foreground: musubi daemon stop, then
musubi --log musubi_sync=debug daemon.
A daemon started for you isn’t given --log: set musubi.daemon.log and run musubi daemon restart. One started by another command itself, rather than through launchd or systemd,
inherits that command’s RUST_LOG, which then takes the setting’s place.
Colours
musubi prints as jj does, through jj’s own formatting, reading jj’s config for it as jj
does outside any repository: the system’s and yours, not a repository’s.
--color (always, never, debug, or auto) or else jj’s ui.color says when to colour
what it prints: by default, auto, only on a terminal, and never if NO_COLOR is set and your
config doesn’t set ui.color. jj’s colors table says how, by label; --color=debug shows
each label. Besides jj’s own labels, such as commit_id, working_copies, warning, and
hint, musubi gives these:
| Label | Text | Default |
|---|---|---|
heading | a heading, such as musubi list’s This repository: | bold |
hive | a hive’s name | bold |
machine | a machine’s name | green |
problem | what’s wrong, such as a sync that fails | red |
jj config set --user 'colors.machine' yellow
Files and directories
These are every file musubi writes. Its settings are in jj’s config files, as Settings says. To remove them all from a machine, see Take a repository or machine out.
On every machine
| Path | Holds |
|---|---|
The state directory: $XDG_STATE_HOME/musubi, so ~/.local/state/musubi on Linux and macOS unless you set XDG_STATE_HOME; %APPDATA%\musubi on Windows; or $MUSUBI_STATE_DIR | state.toml, which lists the copies the daemon syncs, each with its machine key and where it is, and this machine’s default hub; daemon.log; hub_key and hub_key.pub, the machine’s ssh key for reaching hubs; ssh-agent, a link to the latest ssh agent, for the daemon; login-service, while musubi daemon install has the daemon start at login; on the hub’s machine, hub.path, the directory a hub started without --dir serves, hub.log, the log of a hub launchd runs, and hub-login-service, while musubi hub install has the hub run at login; the running daemon’s process id; locks. |
.jj/repo/musubi/ in each repository | The repository’s hive (hive.toml, which records its hive, its jj config id, and whether it joined, left, or its hive was removed), this machine’s identity in it (machine), its last sync (status.json), when the daemon last cleaned up after jj in it (gc, and gc.lock while it does), and musubi’s own record of the hive’s operations. musubi leave records in hive.toml that the copy left, removes status.json, and keeps the rest. Removing it from a repository that syncs, or copying it into another repository, confuses musubi: use musubi leave and musubi clone. |
| Each repository’s jj repo config and git config | The settings a hive shares: the git remotes, and the repo config keys that Share settings lists. Also musubi.forget-after, which musubi join, create and clone set. jj keeps the repo config outside the repository; jj config path --repo prints where. |
What musubi daemon install adds | On macOS, ~/Library/LaunchAgents/io.github.bos.musubi.plist; on Linux, ~/.config/systemd/user/musubi.service (in $XDG_CONFIG_HOME if set); on Windows, the value musubi under HKCU\Software\Microsoft\Windows\CurrentVersion\Run. musubi daemon uninstall removes it. |
What musubi hub install adds | On macOS, ~/Library/LaunchAgents/io.github.bos.musubi.hub.plist; on Linux, ~/.config/systemd/user/musubi-hub.service (in $XDG_CONFIG_HOME if set). musubi hub uninstall removes it. |
The daemon’s control socket is $XDG_RUNTIME_DIR/musubi/daemon.sock on Linux (without
XDG_RUNTIME_DIR, musubi-<uid>/daemon.sock in $TMPDIR or /tmp),
$TMPDIR/musubi/daemon.sock on macOS, and the named pipe \\.\pipe\musubi-<user> on
Windows. With MUSUBI_STATE_DIR set, it is daemon.sock in that directory instead (on
Windows, a pipe named after it). Its directory must belong to you and be writable by no one
else, or musubi won’t use it. --socket, MUSUBI_SOCKET, or musubi.daemon.socket choose
another.
On the hub’s machine
The hub’s directory, ~/musubi-hub by default, holds:
| Path | Holds |
|---|---|
hub.toml | The hub’s settings: the name --advertise gave it. |
<hive id>/ | One directory per hive: its name, in hive.toml, and its operations and objects. |
removed/ | Hives that musubi hub remove removed, each emptied a day later and kept, empty, as the record that it was removed. Also, for a day or so, stores the hub found corrupt and made again. |
run/hub.sock | The socket the hub listens on, which only you can reach. |
hub.lock | A lock that keeps a second hub from serving the directory. |
Outside it, each machine that reaches the hub over ssh adds a line to
~/.ssh/authorized_keys, ending in musubi@<host>, that lets its hub_key run only
musubi hub connect. See The ssh key musubi
adds.
Nothing in the hub’s directory needs backing up: every machine keeps what it synced, so losing the directory loses no work. See Replace or move a hub.