Two things: 1. The host scripts are first-class verbs now — 'box setup-host', 'box teardown-host [--purge-incus]', 'box migrate-host --box <n>'. Nobody should have to run ~/.local/share/box/host/<script>.sh; that read like an external script and exposed an install path. Each verb execs the installed script with its flags passed through (same pattern as 'box doctor'). README, doctor hints, and the uninstall section point at the verbs now. 2. The repo-runbook convention is '.box/', not '.claudebox/'. Renamed across docs and the templates' agent briefing; the briefing tells the agent to read either, and box-recipe.md notes the rename, so repos still shipping '.claudebox/' keep working through the transition. (Consuming repos rename their own folder — tracked separately.) Also widened the help command column for the longer verb names, and fixed one sed-casualty where a broad '.claudebox'→'.box' pass had turned the README's legacy user.claudebox tag into user.box.
61 lines
2.5 KiB
YAML
61 lines
2.5 KiB
YAML
#cloud-config
|
|
users:
|
|
- name: claude
|
|
shell: /bin/bash
|
|
sudo: "ALL=(ALL) NOPASSWD:ALL"
|
|
lock_passwd: true
|
|
write_files:
|
|
- path: /home/claude/.claude/CLAUDE.md
|
|
owner: "claude:claude"
|
|
permissions: '0644'
|
|
defer: true
|
|
content: |
|
|
# You are running inside a box (template: claude)
|
|
|
|
A box is a trust-less, network-isolated, ephemeral VM created by the
|
|
`box` CLI. Keep this context in mind:
|
|
|
|
- **Creds-free by default.** The box starts with no Claude and no git
|
|
credentials. If you need to authenticate Claude, the operator runs `/login`
|
|
interactively. For git, the operator adds their own credentials (a PAT or
|
|
`gh auth login`). Never assume credentials are present; never ask for or
|
|
store secrets on disk beyond what the operator sets up.
|
|
- **Isolated.** The box reaches the public internet but nothing on the host or
|
|
local network. There is no inbound path.
|
|
- **Disposable.** Nothing here is backed up. State is discarded when the box is
|
|
removed; the operator persists work via git push and via `box snapshot`.
|
|
- **Bootstrap runbook.** If the repository you are working in contains a
|
|
`.box/` folder (older repos may use `.claudebox/`), read it as your setup runbook — how to install
|
|
dependencies, start services, template environment files, seed data, and
|
|
smoke-test — and follow it. It is documentation for you, not a script the
|
|
host runs.
|
|
package_update: true
|
|
packages:
|
|
- git
|
|
- gh
|
|
- curl
|
|
- ca-certificates
|
|
- gnupg
|
|
- ripgrep
|
|
- jq
|
|
- tmux
|
|
- age
|
|
- unzip
|
|
- build-essential
|
|
- zsh
|
|
runcmd:
|
|
- curl -fsSL https://get.docker.com | sh
|
|
- usermod -aG docker claude
|
|
- curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
|
|
- apt-get install -y nodejs
|
|
- sudo -u claude bash -lc 'curl -fsSL https://claude.ai/install.sh | bash'
|
|
# 'box exec <box> -- claude …' runs through a NON-interactive shell, which
|
|
# reads no .bashrc/.zshrc — a PATH export there is invisible to it. The
|
|
# symlink makes claude reachable from every shell, interactive or not.
|
|
- ln -sf /home/claude/.local/bin/claude /usr/local/bin/claude
|
|
- echo 'export PATH="$HOME/.local/bin:$PATH"' >> /home/claude/.bashrc
|
|
- chsh -s /usr/bin/zsh claude
|
|
- sudo -u claude bash -lc 'RUNZSH=no CHSH=no sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"'
|
|
- echo 'export PATH="$HOME/.local/bin:$PATH"' >> /home/claude/.zshrc
|
|
- echo 'set -g mouse on' > /home/claude/.tmux.conf
|
|
- chown claude:claude /home/claude/.tmux.conf
|