Skip to main content

Mudroom

@hivemq/mudroomv2026.05.20.61· 3mo agoMODELS
01README

Run Claude Code (and other workloads) inside a macOS apple/container sandbox. Creates one container per workspace — defaulting to the Microsoft typescript-node devcontainer image (Debian 12 bookworm-based, ships node, npm, git, gh, and gnupg) and overridable per sandbox. Bind-mounts the host workspace directory into the guest, and injects the host Claude Code credential so the guest session shares the host subscription without exposing secrets in argv. The trust boundary is the container itself: the host filesystem outside the bind-mounted workspace is not exposed, but inside the guest Claude has Bash(*) and full network egress. Mudroom is container-isolation, not Claude-permission-isolation — anything Claude does inside the box can curl, install packages, and write to the mounted workspace. Includes the mudroom host-side CLI wrapper and the mudroom-setup skill that installs a shell function pointing at the bundled binary.

02Models1
mudroom/mudroom.tsv2026.05.18.1

Global Arguments

ArgumentTypeDescription
containerName?stringName used for the apple/container instance (also used as its ID).
workspaceHoststringHost filesystem path to bind-mount into the sandbox at /workspace.
imagestringOCI image used for the sandbox guest. Defaults to the signed
swampSourceHost?stringHost path to bind-mount read-only at /home/node/.swamp/source inside
sessionsHost?stringHost path to bind-mount read-write at /home/node/.claude/projects
fn ensureContainerCli()
Idempotently install the pinned apple/container CLI on the macOS
fn prepareHost(installKernel?: boolean)
Ensure apple/container
ArgumentTypeDescription
installKernel?booleanPass --enable-kernel-install (default: true). Set false if the
fn up()
Create the sandbox if it does not exist, then start it. Idempotent.
fn exec(command: array, workdir?: string, timeoutSeconds?: number)
Run a command inside the sandbox and capture stdout/stderr
ArgumentTypeDescription
commandarrayCommand and arguments (argv-style)
workdir?stringWorking directory inside the sandbox (defaults to /workspace)
timeoutSeconds?numberKill the command after this many seconds (client-side abort)
fn down()
Stop the sandbox. State is preserved for the next `up`.
fn destroy()
Stop and permanently delete the sandbox. Use this for full teardown.
fn provisionGuest()
First-run installer: probe the guest for required binaries
fn injectSwampAuth()
Mirror the host
fn injectGhAuth()
Mirror the host
fn injectGitIdentity()
Mirror the host
fn injectClaudeAuth()
macOS-only: read the Claude Code subscription credential from
fn injectLinearMcp()
Mirror the host
fn injectAwsAuth()
Mirror the host
fn loadConfig(workspacePath?: string)
Load and validate `${workspacePath}/.mudroom.yaml`. Returns a
ArgumentTypeDescription
workspacePath?stringHost directory containing `.mudroom.yaml`. Defaults to
fn writeStarterConfig(workspacePath?: string, force?: boolean)
Probe the host for available credentials (gh, git identity,
ArgumentTypeDescription
workspacePath?stringHost directory to write `.mudroom.yaml` into. Defaults to
force?booleanOverwrite an existing `.mudroom.yaml` (defaults to false).
fn applyConfiguredMirroring(workspacePath?: string)
Load `${workspacePath}/.mudroom.yaml` and run each enabled
ArgumentTypeDescription
workspacePath?stringHost directory containing `.mudroom.yaml`. Defaults to
fn nameForCwd(cwd: string)
Compute the canonical sandbox name for a host workspace path.
ArgumentTypeDescription
cwdstringHost workspace directory. Symlinks are resolved before hashing.
fn listSandboxes(cwd: string)
Inventory mudroom sandboxes bound to one workspace. Reads `cwd`
ArgumentTypeDescription
cwdstringHost workspace directory to scope the listing to.
fn pruneSandboxes(cwd: string, dryRun?: boolean)
Stop and delete duplicate mudroom sandboxes for one workspace.
ArgumentTypeDescription
cwdstringHost workspace directory to scope the prune to.
dryRun?booleanReport what would be deleted without making any changes
fn recordAutoUpdate(status: enum, fromVersion?: string, toVersion?: string, durationMs: number, error?: string)
Relay the wrapper-side auto-update outcome (status + from/to
ArgumentTypeDescription
statusenum
fromVersion?string
toVersion?string
durationMsnumber
error?string
fn stageTranscript(workspaceHostPath: string, sessionId: string, origin: enum)
Write the session-handoff sentinel at
ArgumentTypeDescription
workspaceHostPathstringAbsolute host path of the workspace directory. On the guest
sessionIdstringClaude Code session ID ($CLAUDE_SESSION_ID from the Stop hook).
originenumWhich side is staging the transcript.
fn resolveStaged(workspaceHostPath: string)
Read-only probe: return the staged sentinel record (with computed
ArgumentTypeDescription
workspaceHostPathstringAbsolute host path of the workspace directory.
fn claimStage(workspaceHostPath: string, sessionsHostOnHost?: string)
Atomically claim the handoff sentinel via `Deno.rename` so
ArgumentTypeDescription
workspaceHostPathstringAbsolute host path of the workspace directory.
sessionsHostOnHost?stringHost path where guest session .jsonl files live (typically
fn writeHandoffHook(workspacePath: string, mudroomHome: string)
Install the Claude Code Stop hook that calls `stageTranscript`
ArgumentTypeDescription
workspacePathstringHost directory that contains (or will contain)
mudroomHomestringResolved `$MUDROOM_HOME` path (e.g. `/Users/blake/.mudroom`).
fn detectLiveHostSession(workspaceHostPath: string, windowSecs?: number)
Scan `~/.claude/projects/<claudeSlug(workspaceHostPath)>/` for
ArgumentTypeDescription
workspaceHostPathstringAbsolute host path of the workspace directory.
windowSecs?numberHow many seconds back to look for activity (default 60).

Resources

system— apple/container system status (apiserver running, kernel installed)
container— Current state of the mudroom sandbox
commandResult— Result metadata for the most recent exec invocation
provisioning— Whether the guest has had its required binaries (claude/swamp/
auth— Outcome of the most recent credential-injection call. Multiple
hostTooling— Outcome of the most recent host-tooling install/probe (currently
mudroomConfig— Resolved state of `<workspaceHost>/.mudroom.yaml`. Instances:
sandboxName— Canonical sandbox name derived from a host workspace path.
sandboxIndex— Inventory of sandboxes bound to one workspace. Written by
sandboxPrune— Result of a `pruneSandboxes` invocation. Records which
handoffSentinel— State of the session-handoff sentinel for this workspace.

Files

commandStdout— stdout captured from the most recent exec invocation
03Previous Versions16
2026.05.18.68yanked

updated binaries

2026.05.18.67yanked

Fix mudroom init: skip writeStarterConfig when .mudroom.yaml already exists so hook reinstall works without -f

updated binaries

2026.05.18.66yanked

Fix session handoff: add missing --origin arg and context-aware SWAMP_REPO_DIR in Stop hook; add host→guest .jsonl bridge in claimStage

updated binaries

2026.05.18.65yanked

Hotfix for 2026.05.18.64: the revert missed three multi-line container-exec arrays in auth.ts (credsScript, settingsScript, teamsScript), so the .64 build still pinned --user node on those three injection paths. Result: Claude credentials, default settings, and Linear-MCP teams patch were silently written to /home/node/.claude/ in containers whose bind mounts targeted /root, never reaching Claude on launch — surfaced as the first-run theme/welcome screen. Lint test strengthened to whole-file scan so future array splits cannot hide the same regression. Yanking .64.

updated binaries

2026.05.18.64yanked

Revert: container exec no longer runs as --user node. The .61/.62/.63 series tried to switch the guest user to node so HOME matched the bind-mount target /home/node/.claude/projects; the cascading work (auth.ts inject paths, /home/node/.claude ownership) made it strictly worse than the simpler alternative. Now the bind-mount targets are /root/.claude/projects and /root/.swamp/source, every guest exec runs as the container default (root), and auth.ts is untouched. Session handoff (mudroom resume-host, mudroom doctor, exit-time hint) is preserved. Sandboxes from .60-.63 should still mudroom destroy && mudroom once after upgrading so the fresh container picks up the new mount target.

updated binaries

2026.05.18.63yanked

Fix for 2026.05.18.62: provisionGuest now chowns /home/node/.claude and /home/node/.config{,/swamp,/gh}/aws back to node:node before any auth injection. apple/container creates the intermediate parents of bind-mounted paths (e.g. /home/node/.claude/projects) as root, which silently broke 'cat > /home/node/.claude/.credentials.json' from a --user node exec — surfaced as 'mudroom: injectClaudeAuth failed'. Non-recursive on .claude so the host-shared /home/node/.claude/projects mount keeps its real ownership. Existing sandboxes can heal in place with: container exec --user 0 chown node:node /home/node/.claude /home/node/.config /home/node/.aws — or just mudroom destroy && mudroom.

updated binaries

2026.05.18.62yanked

Fix follow-up to 2026.05.18.61: credential injection methods (injectSwampAuth, injectGhAuth, injectGitIdentity, injectClaudeAuth, injectLinearMcp, injectAwsAuth) now also exec as --user node so their writes land in /home/node/.claude, /home/node/.config, etc. — where claude (which now runs as node) actually reads from. Without this, mudroom 2026.05.18.61 silently dropped Claude creds, gh auth, git identity, swamp auth, Linear MCP, and AWS creds inside the guest. Existing sandboxes still need a one-time mudroom destroy && mudroom after upgrading.

updated binaries

2026.05.18.61yanked

Fix Aapple/container exec now runs as the node user so Claude session jsonls land in the per-sandbox bind mount instead of /root/.claude/projects. Adds mudroom resume-host (bridges guest sessions for native claude --resume on the host) and mudroom doctor (diagnoses stop-hook, sessionsHost config, sessions dir, and runtime user). Existing sandboxes must be recreated once: mudroom destroy && mudroom.

Modified 1 models. updated binaries

2026.05.18.60yanked

updated binaries

2026.05.18.59yanked

Modified 1 models. updated binaries

2026.05.11.53

Modified 1 models. updated binaries

2026.05.11.52

updated binaries

2026.05.11.51

Modified 1 models. updated binaries

2026.05.10.50

updated binaries

2026.05.10.49

updated binaries

2026.05.10.1
04Stats
B
83 / 100
Downloads
46
Archive size
176.9 KB
  • Has README or module doc2/2earned
  • README has a code example1/1earned
  • README is substantive1/1earned
  • Most symbols documented1/1earned
  • No slow types (deprecated)1/1earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository0/2missing
05Platforms
06Labels