Container manager for software repositories that leverage AI agents
repoman
Per-project Incus containers + opinionated NFS/ZFS backup. v0.1.
Build
reefc build
Produces ./build/repoman.
Test
for t in tests/test_*.reef; do
echo "== $t =="
reefc run "$t" || exit 1
done
Install
System-wide via Makefile (uses reefc build under the hood):
make
sudo make install # installs to /usr/local/bin/repoman
Quickstart
# First run creates ~/.config/repoman/repoman.toml with sane defaults.
repoman --help
repoman new isurus --repo isurus-project
repoman sync --dry-run
repoman list
Subcommands
| Subcommand | Description |
|---|---|
new <name> [--repo <dirname>] [--image <image>] |
Launch an Incus container and bind a local repo into it. (Use repoman setup --with-llm first if you want LLM stack wiring.) |
sync [name] [--no-delete] [--dry-run] |
Mirror local repos to NFS backup via rsync. |
list |
Print a table of all registered projects (read-only). |
status [name] |
Show project state from registry + live incus query. |
remove <name> --yes [--keep-incus] |
Delete the incus container and registry entry. --yes required. |
shell <name> [--cwd <path>] |
Open a bash login shell inside the project's container (replaces repoman). |
--help / -h / help |
Show usage and subcommand list. |
--version / -V |
Print version string. |
Setup wizard
First-time host bootstrap (idempotent — safe to re-run):
repoman setup # interactive
repoman setup --non-interactive # accept defaults
repoman setup --with-llm # include local LLM stack (ollama + hermes)
The wizard creates the Incus project repoman, verifies your claude-share profile
exists, and (with --with-llm) creates an llm-share profile that wires containers
to your host's ollama daemon over LAN.
Local LLM stack
repoman setup --with-llm provisions:
- An Incus profile
llm-sharethat bind-mounts/usr/local/bin/ollama(read-only)
and~/.ollama/, and setsOLLAMA_HOST=http://<host-lan-ip>:11434in the
container environment. - Registry default
[defaults].llm.enabled = true.
Containers created after --with-llm setup automatically inherit the llm-share
profile and can reach the host's ollama daemon at the configured LAN address.
Smoke test (requires Incus + NFS)
# In an existing repo dir under ~/repos:
repoman new test-foo
repoman sync test-foo --dry-run
incus delete --project repoman test-foo
Output and logging
By default repoman runs quietly — only its own ==> ... markers and any errors reach the terminal. Subprocess probes (e.g. incus project show, stat /nfs/repos, findmnt) have their stdout/stderr suppressed to /dev/null. The actual user-facing operations (launch, rsync) pass their stdio through.
To see the suppressed probe output for troubleshooting, run with --verbose (or -v). Pass --quiet (or -q) to force quiet mode if your config defaults to verbose.
Every invocation also writes a log file at <logdir>/<project>-<verb>.log, truncated each run. So if a repoman new veemarker fails, the log lives at ~/.local/state/repoman/veemarker-new.log until the next run with the same name+verb. Whole-tree sync uses all-sync.log.
Configuration
Central registry: ~/.config/repoman/repoman.toml (managed; do not edit while repoman is running).
Tool-level settings under [repoman]:
| Field | Values | Default | Effect |
|---|---|---|---|
output |
"quiet" | "verbose" |
"quiet" |
Default output mode (CLI flags override). |
Defaults under [defaults]:
| Field | Default | Effect |
|---|---|---|
repos_root |
~/repos |
Local NVMe canonical location. |
backup_root |
/nfs/repos |
NFS-mounted backup destination. |
logdir |
~/.local/state/repoman |
Per-invocation log files written here. |
incus_project |
repoman |
Incus project containers are created in. |
default_image |
images:ubuntu/26.04/cloud |
Image used when no --image flag and no override. |
profiles |
["default", "claude-share"] |
Profiles applied when creating containers. |
Per-project overrides: ~/.config/repoman/repos.d/<container-name>.toml (user-authored). Example:
[container]
image = "images:debian/12/cloud"
profiles = ["default", "claude-share", "node-dev"]
[[mount]]
source = "~/.npm"
path = "/home/ctusa/.npm"
[env]
NODE_ENV = "development"
Recommended Incus profile: claude-share
For the agent-friendly setup repoman is built around, create a shared profile that exposes the user's Claude state:
# (one-time)
incus profile create claude-share
incus profile edit claude-share # add your bind-mounts for ~/.claude, etc.
repoman uses profiles default and claude-share by default; override per-project in repos.d/<name>.toml.