|

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
1bacbaae1c2f v0.3 scope reduction: drop --hermes flag and Project.hermes field
Chris Tusa <chris.tusa@leafscale.com> 19 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
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-share that bind-mounts /usr/local/bin/ollama (read-only)
    and ~/.ollama/, and sets OLLAMA_HOST=http://<host-lan-ip>:11434 in 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"

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