Skip to main content

Mudroom

@hivemq/mudroomv2026.05.20.61· 11d agoMODELS·SKILLS
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
@hivemq/mudroomv2026.05.18.1mudroom/mudroom.ts

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's apiserver is running and a kernel is
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's `~/.config/swamp/auth.json` into the guest so
fn injectGhAuth()
Mirror the host's `gh auth token` and login into the guest's
fn injectGitIdentity()
Mirror the host's global `git config user.name`/`user.email`
fn injectClaudeAuth()
macOS-only: read the Claude Code subscription credential from
fn injectLinearMcp()
Mirror the host's Linear MCP server entry from `~/.claude.json`
fn injectAwsAuth()
Mirror the host's `~/.aws` (config, credentials, sso/cache,
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(infinite)— apple/container system status (apiserver running, kernel installed)
container(infinite)— Current state of the mudroom sandbox
commandResult(infinite)— Result metadata for the most recent exec invocation
provisioning(infinite)— Whether the guest has had its required binaries (claude/swamp/
auth(infinite)— Outcome of the most recent credential-injection call. Multiple
hostTooling(infinite)— Outcome of the most recent host-tooling install/probe (currently
mudroomConfig(infinite)— Resolved state of `<workspaceHost>/.mudroom.yaml`. Instances:
sandboxName(infinite)— Canonical sandbox name derived from a host workspace path.
sandboxIndex(infinite)— Inventory of sandboxes bound to one workspace. Written by
sandboxPrune(infinite)— Result of a `pruneSandboxes` invocation. Records which
handoffSentinel(infinite)— State of the session-handoff sentinel for this workspace.

Files

commandStdout(text/plain)— stdout captured from the most recent exec invocation
commandStderr(text/plain)— stderr captured from the most recent exec invocation
03Skills1
mudroom-setup1 file
04Previous Versions16
2026.05.18.68yankedMay 18, 2026

updated binaries

2026.05.18.67yankedMay 18, 2026

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

updated binaries

2026.05.18.66yankedMay 18, 2026

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.65yankedMay 18, 2026

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.64yankedMay 18, 2026

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.63yankedMay 18, 2026

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.62yankedMay 18, 2026

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.61yankedMay 18, 2026

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.60yankedMay 18, 2026

updated binaries

2026.05.18.59yankedMay 18, 2026

Modified 1 models. updated binaries

2026.05.11.53May 11, 2026

Modified 1 models. updated binaries

2026.05.11.52May 11, 2026

updated binaries

2026.05.11.51May 11, 2026

Modified 1 models. updated binaries

2026.05.10.50May 10, 2026

updated binaries

2026.05.10.49May 10, 2026

updated binaries

2026.05.10.1May 10, 2026
05Stats
B
83 / 100
Downloads
43
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 types1/1earned
  • Has description1/1earned
  • Platform support declared (or universal)2/2earned
  • License declared1/1earned
  • Verified public repository0/2missing
06Platforms
07Labels