|

Container manager for software repositories that leverage AI agents

Clone
hg clone ssh://hg@leafscale.isurus.dev:2222/leafscale/repoman hg clone https://leafscale.isurus.dev/leafscale/repoman
7ededc3ad0ab bug: file BUG-050 (module-scoped struct literals skip missing-field check, caused our segfault)
Chris Tusa <chris.tusa@leafscale.com> 23 days ago

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

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"

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.

License
CDDL-1.0
Languages
Markdown 70%
Reef 29%
YAML 0%
Makefile 0%
plaintext 0%
Activity
138 commits
Updated 2 hours ago