Wrapper mode¶
Wrapper mode runs any command inside a private mount namespace where the
agent-neutral source has been compiled to the chosen harness's native
layout and injected at the paths that harness already reads. It is the low-level entry
that provider mode (agedum <name>, the normal way to launch) builds on —
provider mode is wrapper mode plus a resolved provider environment.
Reach for --wrapper directly only to front a harness with the injected context but no
provider env — e.g. native Claude with your own login — or to inspect what gets injected
with --dry-run.
agedum --wrapper claude -- claude -p "…" # render for Claude, run claude
agedum --wrapper kimi -- kimi -p "…" # render for kimi, run kimi
agedum --wrapper opencode -- opencode run "…" # render for opencode, run opencode
agedum --wrapper cline -- cline task "…" # render for Cline, run cline
Context and command are decoupled¶
The invocation has two halves split by a literal --:
- before
--—--wrapper <harness>picks the format to compile to (claude/kimi/opencode/cline/reasonix/aider/pi/codex), plus the optional--dry-run. - after
--— the command, run verbatim, including its own binary and flags. agedum does not parse or rewrite it (a harness may get extra flags appended — see its page).--wrapper=claudeis also accepted; an unknown harness or option is an error.
So the flag chooses what context the process sees, and everything after -- is yours.
How a harness resolves the source¶
Each --wrapper <harness> selects a compiler. A compiler renders the project and
global scopes into the harness's native layout and produces a plan: a set
of (compiled-file → mount-target) binds, plus any extra arguments to append to your
command. The launcher injects the binds into the namespace and runs the
command. Every harness disposes of each source in one of three ways:
| Disposition | Meaning |
|---|---|
injected (→ <dest>) |
agedum writes a compiled copy and binds it at the path the harness reads (e.g. Claude's CLAUDE.md, every harness's skills dir). |
| read in place | the harness reads the file natively at its source location, so agedum injects nothing — and cannot, since the root AGENTS.md is git-tracked. kimi, opencode, cline, reasonix, and pi all read the project AGENTS.md this way. |
| appended flag | the context is passed as an extra argument, not a bind — aider's --read for both scopes' instructions (aider reads no AGENTS.md natively). |
Two rules hold for every harness:
- Each scope lands at its own native location — the project and global sources are never concatenated into one file. The harness reads both and applies its own precedence, exactly as if you had authored them by hand. See Scopes.
- Per-harness overlays are applied — for skills, the base
SKILL.mdis merged with an optionalSKILL.<harness>.md; for the globalAGENTS.md, an optional siblingAGENTS.<harness>.mdis merged on. An overlay for a different harness is skipped.
The exact binds, targets, and any appended flags differ per harness — that is what each harness page documents:
| Harness | Wrapper resolution | Provider config |
|---|---|---|
| Claude | details | details |
| kimi | details | details |
| opencode | details | details |
| Cline | details | details |
| reasonix | details | details |
| aider | details | details |
| pi | details | details |
| codex | details | details |
Inspect without running — --dry-run¶
Put --dry-run before -- to compile the source and print the plan — the bind targets
and any appended args — without launching:
The output groups the dispositions by scope (project / global); the same view
provider mode shows, minus the resolved environment. With
--sandbox, it also lists the writable set (see below).
Filesystem sandbox — --sandbox¶
By default the launched command shares your whole filesystem read-write — the mount
namespace isolates only what the harness reads as config, not where it can write. Pass
--sandbox to switch to write-confinement: the host is mounted read-only, and the
command can write only to
- the project root — the working tree it was launched in;
- the harness's own state/config dir — so it can persist sessions, settings, and auth
(e.g.
~/.claudefor Claude Code,~/.clinefor Cline,~/.codexfor Codex); agedum knows each harness's dir and grants it write access (creating it if missing), whether or not the harness injects anything under it; - the nearest existing ancestor of every file agedum injects (so bwrap can create the mount point);
- a private
/tmp(a fresh tmpfs, discarded on exit); - any directory you add with
--rw-dir DIR(repeatable; passing it implies--sandbox). ADIRholding a shell glob (*,?,[…]) is expanded to each existing match, so--rw-dir '~/src/*'makes every immediate subdirectory of~/srcwritable.
Everything else on the host stays readable but cannot be modified, so an autonomous agent cannot alter or delete files outside its working set.
agedum --wrapper claude --sandbox -- claude -p "…" # confine writes to the project
agedum --wrapper claude --rw-dir ~/scratch -- claude -p "…" # + a writable scratch dir
--dry-run prints the resolved writable set under a sandbox · write-confinement heading,
so you can see exactly what the command will be able to write before launching. A --rw-dir
that already lives inside the project root is folded in — a parent bind covers it.
This confines the filesystem only: the network is untouched, so the harness still reaches
its model endpoint. Like all of wrapper mode it is Linux-only and relies on bwrap.
No footprint¶
Nothing is written to your real tree or $HOME: the compiled files live only inside the
launched process's mount namespace, and agedum refuses to overlay a
git-tracked path. Wrapper mode is Linux-only and needs bwrap
(bubblewrap) on PATH.
Behaviour when no source is found¶
If neither the project nor the global scope has any AGENTS.md or skills,
agedum prints a warning to stderr and still runs your command — just with nothing
injected. It never blocks the launch on an empty source.