Skip to content

Recipes

Practical examples for common jai setups. All examples assume you have already run jai --init.

Claude Code

Install Claude Code in its own jail

bash
curl -fsSL https://claude.ai/install.sh | jai -D -mstrict -n claude bash
  • -D suppresses granting the current directory (you're installing, not coding)
  • -mstrict uses strict mode with a separate user ID
  • -n claude creates a named jail called claude
  • The installer runs inside the jail and writes to $HOME/.jai/claude.home

Run Claude Code from that jail

If $HOME/.local/bin is already on your PATH:

bash
jai -n claude claude

Otherwise:

bash
PATH=$HOME/.local/bin:$PATH jai -n claude claude

Make jai claude use the claude jail by default

Create $HOME/.jai/claude.conf:

conf .defaults
name claude

# Mode already defaults to strict for named jails
mode strict

command PATH=$HOME/.local/bin:$PATH "$0" "$@"

Now you can simply run:

bash
jai claude

jai will find claude.conf, use the claude jail in strict mode, and prepend the install path to PATH.

Codex

Run Codex in casual mode

If Codex stores configuration in ~/.codex, expose that directory so settings persist across jail invocations:

bash
jai -d ~/.codex codex

Make jai codex do this by default

Create $HOME/.jai/codex.conf:

conf .defaults
mode casual
dir .codex

Now jai codex automatically exposes ~/.codex.

OpenCode

Run OpenCode in casual mode

OpenCode uses two directories for state:

bash
jai -d ~/.config/opencode -d ~/.local/share/opencode opencode

Make jai opencode do this by default

Create $HOME/.jai/opencode.conf:

conf .defaults
mode casual
dir .config/opencode
dir .local/share/opencode

Python virtualenv

Run Python with a jailed virtualenv

Create $HOME/.jai/python.conf:

conf default.conf
mode strict
dir venv
name python
command source $HOME/venv/bin/activate; "$0" "$@"

Now jai python enters strict mode, exposes the venv directory, activates the virtualenv, and runs whatever Python command you provide.

Multiple named jails

Named jails let you isolate tools from each other. Each gets its own home directory:

bash
jai -n claude claude      # strict jail named "claude"
jai -n codex codex        # strict jail named "codex"
jai -n scratch bash       # strict jail named "scratch"

Each jail has independent state:

  • Strict/bare home: $HOME/.jai/<name>.home
  • Casual overlay changes: $HOME/.jai/<name>.changes
  • Private tmp: /run/jai/$USER/tmp/<name>

Cleanup and reset

Tear down all jails

bash
jai -u

This unmounts all overlay directories from /run/jai, cleans up .work directories, and destroys private /tmp and /var/tmp contents. Run this when:

  • You want to start from scratch
  • You changed --mask options in a config file (masks are only applied when the overlay is first created)
  • You need to edit files in $HOME/.jai/*.changes directly
  • Overlay mounts are behaving strangely

Recover changes from casual mode

If jailed software modified config files in your home directory, you'll find those changes in:

$HOME/.jai/default.changes/

(Or $HOME/.jai/<name>.changes/ for named jails.)

To move these changes into your real home:

  1. Run jai -u to unmount the overlay
  2. Copy the changed files from the .changes directory to your home
  3. Re-run jai — optionally adding -d flags for directories the tool needs to write to directly

Stanford SCS