# Why

First, this repo is for my own reference. You are welcome to ride along.

For each new project, I copy stuff from here to the project.
I avoid global skills/AGENTS.md/etc, everything is per-project.

## AGENTS.md

Combine the `agents.md/AGENTS*.md` files as you need them. As few or as many as you want.

`cd agents.md && cat AGENTS.md AGENTS-svelte.md AGENTS-lovely-docs.md > /path/to/new/project/AGENTS.md`

Then edit the new `AGENTS.md`, and optionally feed the edits back here if they are good.

# Pi

## Packages to install:

- `pi install -l npm:@xl0/pi-lovely-dev-tools` — `/tool` and `/show-sysprompt` commands.
- `pi install -l npm:@xl0/pi-lovely-comment` — `/comment` GUI-editor draft workflow.
- `pi install -l npm:@xl0/pi-lovely-rename` — automatic and manual session naming.
- `pi install -l npm:@xl0/pi-ide-integration` — IDE selection/@mention integration.
- `pi install -l npm:@xl0/pi-lovely-web` — `web_search`/`web_fetch`/`web_image`.
- `pi install -l git:git@github.com:xl0/pi-agent-notebook-extension` — `.ipynb` read/edit tools + VSCode/Jupyter execution.

## Sandbox with bwrap (Linux only)

`scripts/run-pi-sandboxed.sh` provides a simple bubblewrap (https://github.com/containers/bubblewrap)

It mounts / read-only, keeps ~/.pi, Claude's config directory, ~/.bun, ~/.npm,
~/.cache, Cargo/rustup homes, conda/mamba dirs, VS Code user-data dirs,
~/node_modules, and XDG_RUNTIME_DIR writable by default, mounts NVIDIA device
nodes when present, and runs pi inside the sandbox. Very easy, reasonably
secure.
Escape is not impossible, but it protects against lots of oopsies.

Copy it somewhere in your $PATH: `cp scripts/run-pi-sandboxed.sh ~/.local/bin/`

```
Usage: scripts/run-pi-sandboxed.sh [--no-ssh] [--no-runtime] [--ro-runtime] [--ro-bun] [--ro-npm] [--ro-cache] [--ro-rust] [--ro-conda] [--ro-vscode] [--ro-node-modules] [--no-cuda] [--writable PATH ...] [PI_ARG ...]
       scripts/run-pi-sandboxed.sh [--no-ssh] [--no-runtime] [--ro-runtime] [--ro-bun] [--ro-npm] [--ro-cache] [--ro-rust] [--ro-conda] [--ro-vscode] [--ro-node-modules] [--no-cuda] [--writable PATH ...] [-- COMMAND [ARG ...]]

Runs `pi` in bubblewrap by default.
Use `-- COMMAND ...` to run something other than `pi`.

Bubblewrap setup:
- host / mounted read-only
- current repo mounted read-write
- repo .pi/sandbox/tmp mounted at /tmp
- repo .pi/sandbox/var-tmp mounted at /var/tmp
- network allowed by default
- ~/.pi mounted read-write by default
- CLAUDE_CONFIG_DIR mounted read-write (~/.claude by default)
- ~/.bun mounted read-write by default
- ~/.npm mounted read-write by default
- ~/.cache mounted read-write by default
- Cargo and rustup homes (~/.cargo and ~/.rustup by default) mounted read-write
- conda/mamba dirs mounted read-write by default
- VS Code user-data dirs mounted read-write by default if present
- ~/.config/matplotlib hidden behind an empty writable tmpfs
- ~/node_modules mounted read-write by default if present
- XDG runtime dir mounted read-write by default
- NVIDIA device nodes mounted by default if present, so CUDA/nvidia-smi can work

Options:
  --no-ssh           hide ~/.ssh with an empty tmpfs
  --no-runtime       hide XDG_RUNTIME_DIR (/run/user/<uid>) with an empty tmpfs
                     default: mount XDG_RUNTIME_DIR read-write if present
  --ro-runtime       keep XDG_RUNTIME_DIR read-only
  --ro-bun           keep ~/.bun read-only; default: mount ~/.bun read-write if HOME exists
  --ro-npm           keep ~/.npm read-only; default: mount ~/.npm read-write if HOME exists
  --ro-cache         keep ~/.cache read-only; default: mount ~/.cache read-write if HOME exists
  --ro-rust          keep Cargo/rustup homes read-only; default: mount CARGO_HOME
                     and RUSTUP_HOME (~/.cargo and ~/.rustup) read-write
  --ro-conda         keep conda/mamba dirs read-only; default: mount ~/.conda,
                     ~/.mamba, detected roots, and configured env/pkg dirs read-write
  --ro-vscode        keep VS Code user-data dirs read-only; default: mount existing dirs read-write
  --ro-node-modules  keep ~/node_modules read-only; default: mount read-write if present
  --no-cuda          do not mount NVIDIA device nodes into the sandbox
  --writable PATH    extra host path to mount read-write
  --help             show this help

Examples:
  scripts/run-pi-sandboxed.sh
  scripts/run-pi-sandboxed.sh --no-ssh
  scripts/run-pi-sandboxed.sh --model gpt-5
  scripts/run-pi-sandboxed.sh "prompt here"
  scripts/run-pi-sandboxed.sh --no-runtime -- pi
  scripts/run-pi-sandboxed.sh --ro-runtime
  scripts/run-pi-sandboxed.sh --ro-bun
  scripts/run-pi-sandboxed.sh --ro-npm
  scripts/run-pi-sandboxed.sh --ro-cache
  scripts/run-pi-sandboxed.sh --ro-rust
  scripts/run-pi-sandboxed.sh --ro-conda
  scripts/run-pi-sandboxed.sh --ro-vscode
  scripts/run-pi-sandboxed.sh --ro-node-modules
  scripts/run-pi-sandboxed.sh --no-cuda
  scripts/run-pi-sandboxed.sh -- bash -lc 'uname -a'
```

# Claude Code

`scripts/run-claude-sandboxed.sh` is the Claude Code equivalent of the Pi
sandbox helper. It runs `claude` by default, stores sandbox temporary files
under the repository's `.claude/sandbox/` directory, and keeps
`CLAUDE_CONFIG_DIR` writable (`~/.claude` by default). Claude is run with that
variable set explicitly so its state file, lock, and atomic-update temporary
files all live in the writable directory. The legacy `~/.claude.json` is
imported on first run, and `~/.pi` is also mounted read-write. The script
supports the same sandbox options and `-- COMMAND ...` escape hatch as
`run-pi-sandboxed.sh`. For implicit Claude invocations, it enables
`--dangerously-skip-permissions` because filesystem access is constrained by
bubblewrap.

Copy it somewhere in your `$PATH`:

```sh
cp scripts/run-claude-sandboxed.sh ~/.local/bin/
```

Run `scripts/run-claude-sandboxed.sh --help` for full usage.
