This is the multi-page printable view of this section. Click here to print.
Reference
1 - CLI Commands
CLI Commands
aibox uses a small verb/resource grammar. aibox.toml is desired state, aibox apply reconciles generated files and images, and aibox up enters the workspace.
Global Options
| Option | Environment Variable | Default | Description |
|---|---|---|---|
--config <PATH> | – | ./aibox.toml | Path to configuration file |
--log-level <LEVEL> | AIBOX_LOG_LEVEL | info | Log verbosity |
-y, --yes | – | – | Skip confirmation prompts |
Core Workflow
aibox init my-app --harness claude --addon python
aibox apply
aibox up
aibox down
aibox doctor
Command Grammar
aibox init [NAME] [OPTIONS]
aibox apply [RESOURCE] [NAME] [OPTIONS]
aibox up [OPTIONS]
aibox down
aibox get <RESOURCE> [OPTIONS]
aibox describe <RESOURCE> [NAME] [OPTIONS]
aibox set <TARGET> [VALUE] [EXTRA...] [OPTIONS]
aibox edit <RESOURCE>
aibox reset <RESOURCE> [OPTIONS]
aibox delete <RESOURCE> [NAME] [OPTIONS]
aibox create <RESOURCE> [NAME] [OPTIONS]
aibox self <ACTION> [OPTIONS]
init
Create aibox.toml, generated devcontainer files, .aibox-home/, context scaffolding, and provider pointer files.
aibox init
aibox init my-app --harness claude
aibox init runner --profile headless-runner
aibox init my-app --addon python --addon infrastructure
aibox init my-app --harness claude --harness codex
aibox init my-app --context-mode harness-only --harness claude
aibox init my-app --theme catppuccin-mocha
| Option | Default | Description |
|---|---|---|
[NAME] | Current directory | Project/container name |
--base <BASE> | debian | Base image |
--profile <PROFILE> | human-dev | Usage profile: human-dev or warning-mode headless-runner |
--context-mode <MODE> | processkit | Context layer: processkit or harness-only |
--harness <NAME> | claude | AI harness, repeatable |
--addon <NAME> | – | Addon name, repeatable |
--theme <THEME> | gruvbox | Runtime UI theme family |
--processkit-version <TAG> | latest prompt/default | Pin processkit |
--include-prerelease | off | Include processkit prereleases when init selects a version; explicit prerelease pins always work |
The hidden legacy --context <PKG> option is still accepted as a processkit
package selector for compatibility. New configs use [context].mode and,
when processkit is enabled, [context].packages.
--context-mode harness-only creates a container-and-harness project with no
processkit install, no processkit MCP gateway, no processkit hooks/preauth, no
processkit command adapters, and no processkit Migration entities.
apply
Reconcile generated project state with aibox.toml.
aibox apply
aibox apply --no-cache
aibox apply --rebuild
aibox apply --config-only
aibox apply --standardize-config
aibox apply migration MIG-20260430_1200
aibox apply audio
aibox apply env research
| Option | Description |
|---|---|
--no-cache | Force a full image rebuild without using cached layers |
--rebuild | Visible alias for --no-cache |
--config-only | Regenerate files without building the image |
--standardize-config | Rewrite aibox.toml through the current canonical grouped template after compatibility migrations. Recognized schema fields are preserved; unknown keys block the rewrite. |
--fix-compliance-contract | Rewrite the processkit compliance block in AGENTS.md |
--no-container | Skip runtime probing and image build for CI/nested containers |
Runtime
aibox up
aibox up --layout focus
aibox up --apply
aibox down
aibox get runtime
aibox get runtime --resources
aibox get runtime --resources -o json
aibox describe runtime
aibox delete runtime
up starts or creates the workspace container and attaches through tmux. down stops the compose project. delete runtime removes the container while preserving project files and .aibox-home/.
get runtime reports the configured container name and detected state
(running, stopped, or missing). With --resources, it reports a
best-effort resource pressure snapshot from the current Linux runtime by
reading cgroupfs and procfs directly rather than shelling out to ps or
free.
aibox get runtime --resources includes:
| Field | Source | Meaning |
|---|---|---|
memory_current_bytes | /sys/fs/cgroup/memory.current | Current cgroup memory usage in bytes |
memory_max | /sys/fs/cgroup/memory.max | Cgroup memory limit, or unlimited when the kernel reports max |
oom_kill_count | /sys/fs/cgroup/memory.events | Cumulative oom_kill counter for the cgroup |
total_process_count | numeric entries under /proc | Total visible process count |
processkit_mcp_python_process_count | /proc/*/cmdline | Python processes whose command line looks like a processkit MCP server |
The default table output is compact and human-readable. -o json and
-o yaml emit the same field names for automation; unavailable cgroup values
are null, while process counts fall back to 0 if /proc cannot be read.
Inspecting Resources
get is compact and scriptable. describe is detailed and human-readable. All list/detail commands support -o, --format table|json|yaml; --output is accepted as a visible alias.
aibox get addon
aibox describe addon python
aibox describe addon-catalog -o json
aibox describe image-provenance-policy -o json
aibox get runtime --resources -o json
aibox describe provider-backends -o json
aibox describe workspace-manifest -o json
aibox get skill
aibox get skill --all --category engineering
aibox describe skill model-recommender-route
aibox get process
aibox describe process release-semver
aibox get migration
aibox get env
aibox describe env
aibox get kit
Preview projections
These describe resources are stable enough for local automation. The
workspace manifest has been promoted to aibox.workspace-manifest.v0 because
processkit now recognizes Artifact{kind=workspace-manifest}; the other
environment-contract projections remain aibox.*.v0-preview until processkit
publishes more detailed canonical Artifact schemas.
| Command | Schema | Contents |
|---|---|---|
describe addon-catalog | aibox.addon-catalog.v0 | Built-in addon metadata, profile intent, automation usage class, exported surfaces, dependencies, and tool versions |
describe workspace-manifest | aibox.workspace-manifest.v0 | Sorted projection of aibox.toml: project, context mode/packages, processkit source when enabled, AI harnesses, addons, and MCP server keys |
describe provider-backends | aibox.provider-backends.v0-preview | Supported AI harness backends, selected status, addon availability, MCP config targets, and permission targets |
describe image-provenance-policy | aibox.image-provenance-policy.v0-preview | GHCR image tag or tag template, generated file paths, runtime version/profile markers, selected addons, and release phase commands |
The preview projections do not create processkit entities and should not be treated as canonical processkit Artifacts yet.
Mutating Resources
set changes config. Use --apply when you want to reconcile immediately.
aibox set theme.mode dark --apply
aibox set theme.name tokyo-night --apply --restart-session
aibox set addon python enabled
aibox set addon python disabled --apply
aibox set skill model-recommender-route enabled
aibox set skill pandas-polars disabled --apply
aibox set migration MIG-20260430_1200 in-progress
Delete explicit resources:
aibox delete addon python
aibox delete addon python --apply
aibox delete skill pandas-polars
aibox delete env research --yes
aibox delete migration MIG-20260430_1200 --reason "Not applicable"
Reset And Backup
Project reset is intentionally scoped; there is no bare destructive reset.
aibox create backup
aibox create backup --dry-run
aibox create backup --output-dir /tmp/my-backup
aibox reset project
aibox reset project --dry-run
aibox reset project --no-backup --yes
aibox reset context --from-processkit v0.25.0 --dry-run
reset project is the practical aibox soft reset. It stops the runtime,
backs up aibox-managed project files, preserves auth/cache state from
.aibox-home/, removes the managed scaffold, and writes a reset recovery
migration briefing when user content is found in the backup. It also removes
aibox.toml, so it is not a one-command reinit. Recreate or restore
aibox.toml, run aibox init or aibox apply, then review
context/migrations/pending/ for the recovery advice.
reset context is plan-only in this release. It reports the processkit-owned
context paths that a hard reset would replace from a selected processkit
baseline and the project-owned context paths that must be preserved or reviewed.
Use normal migrations unless the owner explicitly approves a hard context reset.
Diagnostics
aibox doctor
aibox doctor --integrity
aibox doctor --integrity -o json
aibox doctor audio
aibox doctor security
doctor audio checks host PulseAudio readiness. doctor security runs available dependency/image scanners.
LaTeX container scripts
Named LaTeX documents are configured under [[latex.documents]]. aibox apply
deploys the following managed scripts to .aibox-home/.local/bin; they are on
PATH inside the development container and are not host CLI commands.
aibox-latex-build # build all configured documents
aibox-latex-build overview # build one configured document
aibox-latex-watch overview # continuous foreground build inside the container
Host-side aibox up starts the read-only Compose preview sidecar when preview is
enabled. It serves every configured PDF and shows a selection page at its root
when more than one exists. See LaTeX Build and Preview
for container workflow, remote forwarding, and security details.
Self Management
aibox self update --check
aibox self update --dry-run
aibox self update
aibox self completion bash
aibox self uninstall
aibox self uninstall --purge
Removed Old Grammar
The hard-break CLI redesign removed the old top-level command taxonomy.
| Removed | Use |
|---|---|
aibox sync | aibox apply |
aibox start | aibox up |
aibox stop | aibox down |
aibox status | aibox get runtime |
aibox remove / aibox rm | aibox delete runtime |
aibox theme ... | aibox set theme.mode ... or aibox set theme.name ... |
aibox addon ... | aibox get/describe/set/delete addon ... |
aibox kit ... | aibox get/describe/set/delete skill/process ... |
aibox migrate ... | aibox get/set/apply/delete migration ... |
aibox update | aibox self update |
aibox completions | aibox self completion |
aibox uninstall | aibox self uninstall |
aibox audio check/setup | aibox doctor audio / aibox apply audio |
2 - Configuration
Configuration
aibox.toml is the single source of truth for an aibox project. All generated files derive from it.
Full Specification
[aibox]
project_name = "my-app" # Human-readable project name
profile = "human-dev" # Usage profile: human-dev or headless-runner
[container]
name = "my-app" # Container name
hostname = "my-app" # Container hostname
user = "aibox" # Container user (default: aibox)
[container.image]
release_version = "latest" # aibox image/CLI version, or "latest"
base = "debian" # Base image flavor
[container.paths]
devcontainer_json = ".devcontainer/devcontainer.json"
docker_compose = ".devcontainer/docker-compose.yml"
docker_compose_override = ".devcontainer/docker-compose.override.yml"
dockerfile = ".devcontainer/Dockerfile"
dockerfile_local = ".devcontainer/Dockerfile.local"
local_env = ".aibox-local.env"
[container.lifecycle]
post_create_command = "npm install" # Command to run after container creation
keepalive = false # Periodic DNS keepalive for idle network timeouts
[container.resource_thresholds]
memory_mib_warn = 4096 # Optional warning limit for cgroup memory usage in MiB
process_count_warn = 400 # Optional warning limit for total live processes; 0 disables
processkit_mcp_python_warn = 50 # Optional warning limit for live Python MCP server processes; 0 disables
oom_kill_warn = 0 # Optional warning threshold for cgroup OOM kill count
[container.environment]
NODE_ENV = "development" # Project-wide env vars (non-secret; use .aibox-local.toml for secrets)
[[container.extra_volumes]]
source = "~/.aws" # Host path (~ expanded)
target = "/home/aibox/.aws" # Container path
read_only = true
[context]
mode = "processkit" # processkit | harness-only
packages = ["product"] # processkit package selection
[processkit]
source = "https://github.com/projectious-work/processkit.git"
version = "latest" # newest stable release, "unset", or a real tag (including an explicit prerelease)
src_path = "src"
# branch = "main" # Optional; tarball-first, branch as fallback
# release_asset_url_template = "..." # Optional, for non-GitHub hosts
[processkit.context]
schema_version = "1.0.0" # Context schema version (semver)
[addons.python.tools] # Addon: Python runtime
python = { version = "3.14" }
uv = { version = "0.12.0" }
[addons.rust.tools] # Addon: Rust toolchain
rustc = { version = "1.97.1" }
clippy = {}
rustfmt = {}
[addons.git-ui.tools] # Optional: GitHub CLI and lazygit
gh = {}
lazygit = {}
[integrations.github]
credential_helper = "auto" # auto | gh | none
[ai]
model_providers = ["anthropic"] # Optional provider env hints (API key + base URL)
harnesses = [ # Harness order is list order
{ harness = "codex", enable = true, install = true },
# { harness = "claude", enable = true, install = true },
]
[ai.agents]
canonical = "AGENTS.md"
provider_mode = "pointer" # pointer | full
[ai.mcp]
# Team-shared MCP servers merged into all generated MCP client configs
# (see also [[mcp.servers]] in .aibox-local.toml for personal servers)
[[ai.mcp.servers]]
name = "my-team-tool" # Unique server name
command = "npx" # Executable to run
args = ["-y", "@acme/team-server"] # Arguments
# [ai.mcp.servers.env] # Optional environment variables
# API_KEY = "..."
[customization]
theme = "gruvbox" # Theme family; concrete legacy names still parse
mode = "auto" # Theme mode: auto, light, dark
prompt = "default" # Starship preset (8 options)
layout = "dev" # tmux layout (4 options)
[customization.tmux.status]
mode = "extended" # extended | plain | disabled (legacy: powerline -> extended)
[customization.tmux.status.layout]
# Row lists are ordered. Removing a name disables that status element.
# Allowed line1-left entries:
# - session: current tmux session name and prefix/copy-mode state
# - windows: tmux window list
#
# Allowed line1-right / line2-left / line2-right entries:
# - aibox_log: aibox log health counts
# - aibox_oom: cgroup OOM kill counters
# - aibox_proc: live process count versus configured process warning limit
# - aibox_ai: detected AI-agent/runtime process count
# - aibox_mcp: processkit/MCP daemon and server process status (processkit mode)
# - aibox_mig: pending processkit migration count (processkit mode)
# - weather: weather segment from tmux-powerkit
# - uptime: container uptime
# - datetime: local date/time
# - git: current repository branch/status
# - github: GitHub/repository integration status
# - kubernetes: Kubernetes context/status
# - terraform: Terraform/OpenTofu workspace/status
# - cloud: local cloud CLI/context status
# - cloudstatus: networked public provider status checks; opt-in, not enabled by default
# - hostname: container hostname
# - externalip: detected external IP
# - ssh: SSH agent/key status
# - netspeed: network throughput
# - ping: network latency
# - cpu: CPU usage
# - loadavg: system load average
# - memory: memory usage
# - swap: swap usage
# - disk: disk usage
# - gpu: GPU status when available
# - modelstatus_<provider>: per-provider AI status segment; explicit layout entries render even when model-provider auto-add is off
line1-left = ["session", "windows"]
line1-right = ["aibox_log", "aibox_oom", "aibox_proc", "aibox_ai", "aibox_mcp", "aibox_mig", "weather", "uptime", "datetime"]
line2-left = ["git", "github", "kubernetes", "terraform", "cloud"]
line2-right = ["hostname", "externalip", "ssh", "netspeed", "ping", "cpu", "loadavg", "memory", "swap", "disk", "gpu"]
[customization.tmux.status.labels]
# Visible headers/icons for status segments. Layout controls which segments appear;
# this section controls how those segments are labeled once rendered.
# Values may be plain ASCII labels or symbols. ASCII is safest across terminals;
# Nerd Font / Powerline symbols are compact but require the user's terminal font.
# Practical symbol candidates from Nerd Fonts. Keep icons distinct across
# configured PowerKit segments so adjacent status cells remain scannable.
aibox-log = ""
aibox-oom = ""
aibox-proc = ""
aibox-ai = ""
aibox-mcp = ""
aibox-mig = ""
kubernetes = ""
cloud = ""
cloud-aws = ""
cloud-gcp = ""
cloud-azure = ""
cloud-multi = ""
uptime = ""
netspeed = ""
netspeed-download = ""
netspeed-upload = ""
[customization.tmux.status.separators]
# PowerKit separator style. Options: normal | rounded | slant | slantup | trapezoid | flame | pixel | honeycomb | none
style = "rounded"
# Edge separators may use a different style at status boundaries.
edge-style = "rounded"
# Spacing between elements. Options: false | true | both | windows | plugins
elements-spacing = "both"
[customization.tmux.status.refresh]
# Refresh/caching controls for extended tmux status.
# interval-seconds: tmux redraw cadence. Higher values reduce shell process churn.
# aibox-metrics-cache-ttl-seconds: LOG/OOM/PROC/AI/MCP/MIG cache TTL.
# netspeed-cache-ttl-seconds: network throughput cache TTL.
# kubernetes-cache-ttl-seconds: local kubeconfig context cache TTL.
# cloud-cache-ttl-seconds: local cloud CLI/context cache TTL.
# github-cache-ttl-seconds: local repo + GitHub issue/PR/discussion count cache TTL.
interval-seconds = 15
aibox-metrics-cache-ttl-seconds = 30
netspeed-cache-ttl-seconds = 10
kubernetes-cache-ttl-seconds = 120
cloud-cache-ttl-seconds = 120
github-cache-ttl-seconds = 120
[customization.tmux.status.forge]
# Exact GitHub SSH hostnames and aliases recognized by the Forge segment.
github-hosts = ["github.com", "github-work"]
[customization.tmux.status.model-providers]
# Optional networked model-provider health segments for the extended tmux status line.
# Each configured provider becomes one PowerKit segment when enabled, for example OAI ✓ or ANT .
# enabled: false avoids auto-adding all configured providers; explicit layout entries still render.
# cache-ttl-seconds: minimum time between provider status requests per provider.
# timeout-seconds: per-request HTTP timeout so status rendering cannot hang tmux.
# show-ok: true shows healthy providers with ✓; false hides healthy providers and only shows degraded/unknown/outage.
enabled = false
cache-ttl-seconds = 300
timeout-seconds = 3
show-ok = true
# Provider entries:
# - provider: stable key from the model roster (openai, anthropic, google, mistral, deepseek, cohere, xai, alibaba, aws, meta, microsoft, minimax, moonshot, nvidia, xiaomi, zai)
# - label: short category header shown in the status segment; use text or a symbol that your font supports
# - checks: any of overall, models, harness; worst status wins (outage > degraded > unknown > ok)
# - status-url: JSON status endpoint; Statuspage summary APIs are supported, Google uses incidents.json
# - overall-components/model-components/harness-components: optional component-name filters for providers with componentized status APIs
# Symbols: ✓ ok, degraded, outage, ? unknown.
[[customization.tmux.status.model-providers.providers]]
provider = "openai"
label = "OAI"
checks = ["overall", "models", "harness"]
status-url = "https://status.openai.com/api/v2/summary.json"
model-components = ["Responses", "Chat Completions", "Embeddings", "Realtime", "Images"]
harness-components = ["CLI", "Codex API", "Codex Web"]
[[customization.tmux.status.model-providers.providers]]
provider = "anthropic"
label = "ANT"
checks = ["overall", "models", "harness"]
status-url = "https://status.claude.com/api/v2/summary.json"
model-components = ["Claude API"]
harness-components = ["Claude Code"]
[[customization.tmux.status.model-providers.providers]]
provider = "google"
label = "GOOG"
checks = ["overall", "models"]
status-url = "https://status.cloud.google.com/incidents.json"
[audio]
enabled = false # Enable audio bridging
backend = "pulseaudio" # Audio bridge backend
install = true # Install container audio tools
pulse_server = "tcp:host.docker.internal:4714"
Section Reference
[aibox]
Top-level project metadata.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
project_name | String | No | container.name | Human-readable project name |
profile | String | No | "human-dev" | Usage profile: human-dev or experimental headless-runner |
profile is currently a compatibility signal for addon selection and doctor
warnings. It does not change the generated image tag yet; headless-runner
is reserved for automation-safe configurations that avoid subscription CLI
tools and interactive desktop helpers.
For automation, aibox describe workspace-manifest -o json emits a sorted,
read-only aibox.workspace-manifest.v0 projection of this file. The projection
uses processkit’s canonical Artifact{kind=workspace-manifest} kind, while the
machine-readable JSON shape remains aibox-owned until processkit publishes a
more detailed Artifact schema.
aibox describe provider-backends -o json similarly emits
aibox.provider-backends.v0-preview, an aibox-local index of supported harness
backends, addon availability, and MCP registration/permission targets.
aibox doctor uses the same preview model to warn about selected backends that
cannot participate in MCP automation, have no permission projection, or conflict
with the headless-runner profile.
aibox describe image-provenance-policy -o json emits
aibox.image-provenance-policy.v0-preview, which summarizes the configured
GHCR image tag or tag template, generated Dockerfile/Compose files, runtime
version/profile markers, selected addons, and the host-side release phase
command template.
[container]
Container configuration. Controls the generated docker-compose.yml and Dockerfile.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | String | Yes | – | Container name (used by compose and runtime inspect) |
hostname | String | No | "aibox" | Container hostname |
user | String | No | "aibox" | Container user |
post_create_command | String | No | – | Command to run after container creation |
keepalive | Boolean | No | false | Periodic DNS keepalive for development environments with idle network timeouts. |
environment | Map (String → String) | No | {} | Environment variables injected into the container. Suitable for non-secret project-wide values; use .aibox-local.toml for secrets. |
extra_volumes | Array of ExtraVolume | No | [] | Additional bind mounts. Each entry has source, target, and optional read_only. |
resource_thresholds | Table | No | see below | Warning thresholds used by aibox doctor for cgroup/procfs pressure signals. |
Generated Compose files include a top-level project name, an explicit service
image, and container_name = [container].name. Container runtime and Compose
views should therefore show each aibox project under its configured
project/container identity instead of a generic devcontainer group.
[container.resource_thresholds]
These thresholds are warnings only. They do not stop aibox up or fail the
container build; they make aibox doctor surface resource pressure before the
operating system starts killing processes.
| Field | Type | Default | Description |
|---|---|---|---|
memory_mib_warn | Integer | unset | Warn when cgroup memory.current exceeds this many MiB. |
process_count_warn | Integer | 400 | Warn when /proc contains more processes than this. Set to 0 to disable. |
processkit_mcp_python_warn | Integer | 50 | Warn when many Python processkit MCP server processes are live. Only rendered and used in processkit mode. Set to 0 to disable. |
oom_kill_warn | Integer | 0 | Warn when cgroup memory.events reports more OOM kills than this. |
[[container.extra_volumes]]
Each entry in the extra_volumes array is an ExtraVolume with these fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
source | String | Yes | – | Host path (supports ~ expansion) |
target | String | Yes | – | Container path where the volume is mounted |
read_only | Boolean | No | false | Mount the volume read-only |
Example — mount a personal host configuration directory:
[[container.extra_volumes]]
source = "~/.aws"
target = "/home/aibox/.aws"
read_only = true
GitHub CLI configuration created inside the container does not need an extra
volume: /home/aibox/.config/gh is already persisted through the managed
.aibox-home/.config mount. See GitHub authentication
for the least-privilege PAT and persistent-login options.
Use Dockerfile.local for installing additional packages, and docker-compose.override.yml for ports and additional services. Both files are scaffolded by aibox init and are never overwritten by aibox apply.
Environment variables and bind mounts can also be configured directly in [container.environment] / [[container.extra_volumes]] in aibox.toml, or — for secrets and per-developer settings that should not be committed — in .aibox-local.toml.
.aibox-local.toml
.aibox-local.toml is a personal, gitignored overlay for per-developer settings that should never be committed — API keys, provider endpoint/base URL overrides, personal bind mounts, and similar secrets. It lives next to aibox.toml in the project root and is automatically added to .gitignore by aibox init and aibox apply.
Three sections are supported:
[container.environment]— merged on top ofaibox.toml’s[container.environment]. Local values win on conflicts.[[container.extra_volumes]]— appended after any volumes declared inaibox.toml.[[mcp.servers]]— personal MCP servers appended to the team MCP servers fromaibox.toml [ai.mcp]. All sources are merged into each generated MCP client config file.
All other configuration (container name, addons, processkit version, etc.) must remain in aibox.toml.
See the dedicated Local Config reference for a full example and merge-behavior details.
[context]
Selects the project context layer.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
mode | String | No | processkit | processkit installs the processkit-backed project context layer. harness-only skips processkit content and uses only generated container/harness configuration. |
packages | Array of strings | No | ["product"] in processkit mode, [] in harness-only mode | processkit package selection. Required to be non-empty in processkit mode. Ignored in harness-only mode. |
schema_version | String (semver) | No | "1.0.0" | Accepted for compatibility. Canonical processkit-mode rendering stores the schema version under [processkit.context]. |
aibox init --context-mode harness-only writes:
[context]
mode = "harness-only"
In harness-only mode, generated aibox.toml, AGENTS.md, provider pointer
files, MCP config, status comments, and migration surfaces do not mention
processkit. aibox apply still regenerates .devcontainer/, .aibox-home/,
selected harness config, addon files, and team/personal MCP servers; it does
not install context/skills/, context/templates/processkit/, processkit
hooks, processkit preauth, processkit command adapters, or processkit Migration
entities.
Use [skills].include and [skills].exclude for explicit skill-level
overrides when mode = "processkit".
[latex]
Defines named LaTeX documents and their shared build/preview behavior. Add the
latex addon separately to install TeX Live in the container.
[latex]
engine = "lualatex"
cache_dir = ".latex-cache"
options = []
[[latex.documents]]
name = "overview"
source = "docs/overview.tex"
output_dir = ".latex-cache/overview"
[latex.preview]
enabled = true
engine = "embedpdf"
bind = "127.0.0.1"
port = 8765
document = "overview"
allow_public = false
| Key | Type | Required | Default | Description |
|---|---|---|---|---|
engine | String | No | lualatex | lualatex, pdflatex, xelatex, or tectonic. Tectonic supports build but not watch. |
cache_dir | Relative path | No | .latex-cache | Root for project-local TEXMFVAR and TEXMFCONFIG. Parent traversal is rejected. |
options | Array | No | [] | Additional single-line engine arguments. |
documents[].name | String | Yes | – | Unique command-safe document name. |
documents[].source | Relative path | Yes | – | Main TeX source. |
documents[].output_dir | Relative path | No | .latex-cache/output | PDF, log, and auxiliary output directory. |
preview.enabled | Boolean | No | false | Generates one shared read-only Compose preview sidecar; host-side aibox up starts it and it serves every configured document. |
preview.engine | String | No | embedpdf | Viewer implementation; currently only embedpdf is supported. |
preview.bind | IP address | No | 127.0.0.1 | Compose host-publish address. Loopback is accessible only from that host; use 0.0.0.0 only for other machines. |
preview.port | Integer | No | 8765 | Host-published port for the document index and all viewers. It maps to sidecar port 8765. |
preview.document | String | No | first configured document | Default for legacy /document.pdf and /events routes. All configured documents are served. |
preview.allow_public | Boolean | No | false | Required for a non-loopback host bind. The preview has no authentication. |
Run aibox apply after changing this section. Besides refreshing the canonical
config comments, apply adds conditional LaTeX companion guidance to AGENTS.md
and installs the managed aibox-latex-build and aibox-latex-watch scripts
into the development container’s runtime home. Compilation and watch mode run
only in that main container. See LaTeX Build and Preview
for the workflow and remote access. aibox generates the read-only serving
sidecar and its port mapping; do not add a duplicate mapping to
docker-compose.override.yml.
[addons]
Addons install language runtimes and tool bundles into the container. AI
harnesses are selected under [ai]; aibox may still use internal addon recipes
to install their CLIs.
[addons.python.tools]
python = { version = "3.14" }
uv = { version = "0.12.0" }
For interactive Git tooling:
[addons.git-ui.tools]
gh = {}
lazygit = {}
Omit git-ui if the project does not need GitHub CLI or lazygit in the
container. The aibox repo may select it for maintenance workflows, but it is
not required for every generated project.
Run aibox get addon to see all available addons, or aibox describe addon <name> for tool details and supported versions. See the Addons page for full documentation.
[skills]
Controls which skills from processkit are installed into context/skills/.
Fresh aibox.toml scaffolds list the standard processkit operating skills in
include. If include is empty, aibox falls back to installing every skill in
the pinned processkit version minus anything listed in exclude.
aibox apply reconciles newly introduced standard skills into existing
processkit projects while respecting explicit exclude entries. Tooling-linked
skills remain opt-in: an interactive apply asks before persisting a
recommendation. For example, selecting the latex addon offers to add
latex-authoring; a non-interactive apply prints the recommendation without
changing skill selection.
[skills]
include = ["pk-doctor", "status-briefing"] # install only these plus core skills
exclude = ["research-with-confidence"] # omit from the default all-skills set
include and exclude are mutually exclusive: use one or the other, not both.
Both accept skill names (the filename without .md). enabled and disabled
are accepted as aliases for older configs. An empty [skills] table (or
omitting the section entirely) installs all skills.
See the Skills page for the full processkit boundary.
This section is omitted and ignored in context.mode = "harness-only".
[ai]
AI harness and model-provider configuration. Harness entries are ordered; the
order of the harnesses list is the tmux/layout order. A harness participates
in generated agent/MCP config only when enable = true; CLI installation is
controlled independently by install = true.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
harnesses[].harness | String | Yes for each entry | none | Harness id. Supported values: claude, codex, gemini, aider, continue, cursor, copilot, opencode, hermes, tau. Tau reads project instructions from AGENTS.md and Agent Skills from .agents/skills/; Tau does not currently expose a built-in MCP client. |
harnesses[].enable | Boolean | No | false | Include this harness in generated runtime, agent, and MCP config. Alias: enabled. |
harnesses[].install | Boolean | No | false | Install the matching in-container CLI recipe when available. Cursor has no container CLI, so keep this false for cursor. |
harnesses[].version | String | No | addon’s default | Optional CLI version pin. |
model_providers | Array of strings | No | [] | Optional provider env hints: anthropic, openai, google, mistral. Each maps to both an API key env var and an optional base URL env var. |
Harness controls live in the ordered harnesses list. Optional entries are
usually shown as one-line inline tables so they can be enabled by uncommenting
one line:
harnesses = [
{ harness = "codex", enable = true, install = true },
# { harness = "claude", enable = true, install = true },
# { harness = "cursor", enable = true, install = false },
]
Provider env mapping:
| Provider | API key env | Base URL env |
|---|---|---|
anthropic | ANTHROPIC_API_KEY | ANTHROPIC_BASE_URL |
openai | OPENAI_API_KEY | OPENAI_BASE_URL |
google | GEMINI_API_KEY | GEMINI_BASE_URL |
mistral | MISTRAL_API_KEY | MISTRAL_BASE_URL |
model_providers is a catalog hint only; it does not inject environment variables into Compose by itself. Set provider credentials explicitly in [container.environment], preferably in .aibox-local.toml:
[container.environment]
OPENAI_API_KEY = "..."
OPENAI_BASE_URL = "https://api.openai.com/v1" # Optional override
GEMINI_API_KEY = "..."
GEMINI_BASE_URL = "https://generativelanguage.googleapis.com" # Optional override
Some provider CLIs/SDKs also support aliases (for example OPENAI_API_BASE).
Legacy compact harness lists, harness_order, providers = [...],
[ai.harness.<name>], and [addons.ai-*.tools] inputs are still accepted for
compatibility. Use aibox apply --standardize-config to rewrite a schema-clean
config into the current canonical shape.
[processkit]
The load-bearing content section. Configures the content source
the project consumes — skills, primitives, processes, package YAMLs, and the
canonical AGENTS.md template. The default upstream is the canonical
projectious-work/processkit
repo, but any processkit-compatible source works (forks, self-hosted, private
mirrors).
This section is only active when [context].mode = "processkit". In
harness-only mode it is omitted from generated configs and ignored by
aibox apply.
If version is the sentinel unset, both aibox init and aibox apply skip
the processkit fetch entirely. Pin a real tag (e.g. v0.27.4) to land the
content. The downloaded tarball is git-tracked under
context/templates/processkit/<version>/ so derived projects always have the
original to diff against.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
source | String | No | https://github.com/projectious-work/processkit.git | Git URL of the content source. |
version | String | No | unset | Semver tag to consume. The sentinel unset skips fetching until a real tag is set. |
src_path | String | No | src | Subdirectory inside the source repo containing the shippable payload. Auto-detected for flat release-asset tarballs. |
branch | String | No | (none) | Optional branch override for testing pre-release work. Discouraged but supported. |
release_asset_url_template | String | No | (GitHub-style default) | URL template for the release-asset tarball. Placeholders: {source} (.git stripped), {version}, {org}, {name}. Set this for non-GitHub hosts. |
[processkit.context]
Processkit-mode context-system metadata.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
schema_version | String (semver) | No | "1.0.0" | Context schema version. Canonical rendering keeps this under [processkit.context] for processkit-backed projects. |
Fetch strategy
The fetcher tries strategies in priority order:
- Branch override (if
branchis set) —git clone --branch <name>. - Release-asset tarball — downloads a purpose-built
.tar.gzfrom the URL built fromrelease_asset_url_template(or the GitHub-style default{source}/releases/download/{version}/{name}-{version}.tar.gz). When a sibling<asset>.sha256file is present, the tarball bytes are verified against it before extraction. The verified SHA256 is recorded inaibox.lockasrelease_asset_sha256for bit-exact reproducibility. - Host auto-tarball — falls back to GitHub / GitLab’s auto-generated
archive/refs/tags/<version>.tar.gzwhen no release asset is available. - Git clone of the tag — last resort for hosts that serve neither tarball form (typical for self-hosted git over SSH).
The release-asset path lets producers (processkit and any compatible content source) ship a smaller, explicit shippable artifact. Consumers get bit-exact reproducibility for free.
A SHA256 mismatch is a hard error (does NOT fall through), since it indicates either tampering or a producer bug; both are situations the user should be told about.
Example: consume a Gitea-hosted fork
[processkit]
source = "https://gitea.acme.com/platform/processkit-acme.git"
version = "v1.2.0"
release_asset_url_template = "https://gitea.acme.com/{org}/{name}/releases/download/{version}/{name}-{version}.tar.gz"
[ai.mcp]
MCP server definitions and permission configuration. aibox apply merges
servers from these sources and regenerates all MCP client config files:
- Built-in processkit servers — only in
context.mode = "processkit", either the processkit gateway or separate per-skill servers, depending on[ai.mcp.gateway] aibox.toml [[ai.mcp.servers]]— team-shared servers committed to version control.aibox-local.toml [[mcp.servers]]— personal servers, gitignored
Generated files (.mcp.json, .cursor/mcp.json, .gemini/settings.json, .codex/config.toml, .codex/hooks.json, .continue/mcpServers/) are gitignored. They are always reproducible from the config sources above and must not be committed — doing so would embed personal server definitions or credentials from .aibox-local.toml.
In harness-only mode, processkit servers and the processkit gateway are not registered. Team and personal MCP servers are still generated for enabled harnesses.
processkit Gateway: [ai.mcp.gateway]
When the selected processkit release provides processkit-gateway, its stdio
proxy can start the matching localhost daemon on demand. It can replace the
one-process-per-skill MCP topology with a single processkit MCP entry.
[ai.mcp.gateway]
mode = "auto" # auto | daemon | stdio | separate
lazy_catalog = true
host = "127.0.0.1"
port = 8765
path = "/mcp"
| Mode | Behavior |
|---|---|
auto | Register a self-starting processkit gateway daemon when the installed processkit version ships it; otherwise fall back to separate per-skill servers |
daemon | Use one localhost processkit gateway daemon plus one stdio proxy per harness |
stdio | Register processkit-gateway directly as a stdio MCP server |
separate | Always register one MCP server per processkit skill |
lazy_catalog = true is the default. It enables processkit’s lazy catalog
where the selected gateway topology supports it. Set it to false only when
troubleshooting gateway import behavior. Legacy values daemon-proxy and
granular are still accepted as aliases for daemon and separate.
The daemon-backed mode is localhost-only. Run aibox apply after changing
this section so generated harness configs stay in sync.
Server Definitions: [[ai.mcp.servers]]
Each [[ai.mcp.servers]] entry has these fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name | String | Yes | – | Unique server name (used as the key in generated configs) |
command | String | Yes | – | Executable to run (e.g. npx, /usr/local/bin/my-server) |
args | Array of strings | No | [] | Arguments passed to command |
env | Map (String → String) | No | {} | Environment variables set when the server process starts |
Example:
[[ai.mcp.servers]]
name = "internal-docs"
command = "/usr/local/bin/internal-docs-mcp"
args = ["--stdio"]
[ai.mcp.servers.env]
LOG_LEVEL = "info"
Credential-bearing personal servers belong in the gitignored
.aibox-local.toml [[mcp.servers]] section. Do not commit GitHub tokens in
aibox.toml; see GitHub authentication.
Permission Configuration: [ai.mcp.permissions]
Controls which MCP servers harnesses are permitted to use, eliminating repetitive permission prompts. aibox apply expands glob patterns into concrete server names and regenerates harness-specific permission files for supported harnesses.
Global defaults:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
default_mode | String | No | "ask" | Default permission when no explicit pattern matches. Use "allow" only when every configured MCP server is trusted. |
allow_patterns | Array of strings | No | [] | Glob patterns to auto-allow. Supports server patterns such as "processkit-*" and Claude-style aliases such as "mcp__processkit-*" or "mcp__processkit-skill-gate__*". |
deny_patterns | Array of strings | No | [] | Glob patterns to auto-deny (takes precedence over allow). Use for restricting specific tool families. |
Per-harness overrides (optional):
[ai.mcp.permissions.harness.claude-code]
default_mode = "allow" # Override global default if needed
allow_patterns = [] # Add harness-specific patterns
[ai.mcp.permissions.harness.opencode]
default_mode = "allow"
deny_patterns = [] # Restrict specific tools per harness
aibox maps this provider-neutral permission intent to each harness’s native
configuration format. Sandbox, approval, and network policy are configured
separately in [ai.execution].
Example:
[ai.mcp.permissions]
default_mode = "ask"
allow_patterns = ["mcp__processkit-*"]
deny_patterns = ["mcp__processkit-dangerous-admin"] # Deny a specific pattern if needed
[ai.mcp.permissions.harness.claude-code]
# Use default settings; Claude Code will auto-allow all processkit tools
[ai.mcp.permissions.harness.continue]
# Continue defaults to "ask" for safety; override to "allow" to auto-approve
default_mode = "allow"
Servers that require personal credentials or are not relevant to all team members belong in [[mcp.servers]] in .aibox-local.toml, not committed [[ai.mcp.servers]]. See Local Config.
[ai.execution]
Controls the default execution policy intent for AI harnesses. aibox uses stable cross-harness vocabulary here and maps it to each harness where supported.
[ai.execution]
filesystem = "workspace-write" # read-only | workspace-write | container-full
approval = "on-request" # ask | on-request | never
network = "ask" # deny | ask | allow
[ai.execution.codex]
filesystem = "container-full"
approval = "on-request"
network = "ask"
The legacy [ai.harness.<name>.execution] table is still accepted for existing
configs, but new scaffolds use [ai.execution.<name>].
filesystem = "container-full" means the devcontainer is the filesystem
security boundary. For Codex this maps to sandbox_mode = "danger-full-access",
which keeps .git writable inside a trusted aibox devcontainer. It is distinct
from Codex’s --dangerously-bypass-approvals-and-sandbox: approvals remain
controlled by the approval axis.
Unsupported axes for a harness are best-effort projections; they are retained in
aibox.toml as project intent even when the current harness has no exact native
setting.
[ai.agents]
Controls how aibox init scaffolds the canonical agent entry document
(AGENTS.md) and the provider-specific entry files (CLAUDE.md, future
CODEX.md, …). The principle is provider neutrality: every agent
harness reads the same AGENTS.md so a project doesn’t have to keep
N copies of the same instructions in sync. Provider files exist only
to satisfy specific harnesses’ auto-load conventions (Claude Code
auto-loads CLAUDE.md at startup, etc.).
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
canonical | String | No | "AGENTS.md" | Filename of the canonical agent entry document. Almost no one should override this — the default matches the agents.md ecosystem convention. |
provider_mode | String | No | "pointer" | How provider files are scaffolded. pointer (recommended): provider files are thin pointers that say “see AGENTS.md”. full: provider files contain the rich provider-flavoured content — use only when a project genuinely needs different instructions per harness. |
aibox init always creates AGENTS.md (write-if-missing — never
overwrites). When the Claude harness is enabled, it also creates
CLAUDE.md, either as a thin pointer (default) or with the full rich
content (provider_mode = "full"). Other harnesses (Aider, Gemini,
Codex, Copilot, Continue) use config files rather than markdown
entries and are not affected by this section.
Existing files are never overwritten. If you already have a hand-written
AGENTS.md or CLAUDE.md, aibox init leaves it alone.
[customization]
Visual and layout configuration. See Themes and Layouts for details.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
theme | String | No | "gruvbox-dark" | Color theme. Supports the tmux-powerkit popular theme roster and variants, plus projectious; see Themes. |
mode | String | No | "auto" | Global theme mode overlay: auto, light, dark. auto follows the host OS appearance when detectable during aibox apply, aibox up, or aibox set theme.*; otherwise it preserves the selected concrete theme. |
prompt | String | No | "default" | Starship preset: default, plain, arrow, minimal, nerd-font, pastel, powerline-pastel, bracketed. Legacy pastel-powerline is accepted as an alias. |
layout | String | No | "dev" | tmux layout: dev, focus, cowork, ai |
tmux.status.mode | String | No | "extended" | tmux status presentation: extended uses the themed multi-line PowerKit status, plain keeps minimal tmux text, disabled turns the status line off. Legacy powerline is accepted as an alias for extended. |
tmux.status.separators.style | String | No | "rounded" | PowerKit separator style: normal, rounded, slant, slantup, trapezoid, flame, pixel, honeycomb, none. |
tmux.status.separators.edge-style | String | No | "rounded" | PowerKit edge separator style for status boundaries. Uses the same values as style. |
tmux.status.separators.elements-spacing | String | No | "both" | PowerKit spacing mode: false, true, both, windows, plugins. |
tmux.status.forge.github-hosts | Array of strings | No | ["github.com"] | Exact GitHub SSH hostnames and aliases recognized by the Forge status segment. Add aliases declared in SSH config, such as github-work. |
[audio]
Audio bridging configuration.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
enabled | Boolean | No | false | Enable PulseAudio environment setup |
backend | String | No | "pulseaudio" | Audio bridge backend. Only pulseaudio is currently supported. |
install | Boolean | No | true | Select the internal audio-voice recipe when audio is enabled |
pulse_server | String | No | "tcp:host.docker.internal:4714" | PulseAudio server address |
Legacy [container.audio] input is still accepted for compatibility. Fresh
scaffolding writes top-level [audio].
[integrations.github]
GitHub integration behavior for generated runtime Git configuration.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
credential_helper | String | No | "auto" | auto writes a managed Git include when the git-ui addon installs gh; gh always writes it; none skips and removes the managed include. For github.com HTTPS remotes, the include resets earlier credential helpers before delegating to gh auth git-credential, and never stores token values. |
This setting selects the generated Git credential helper; it does not select or store a GitHub token. Configure scoped tokens or a persistent GitHub CLI login through the local GitHub authentication guidance.
Apply Behavior
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
preserve_disabled_harness_state | Boolean | No | false | Records the owner’s decision to retain .aibox-home state for disabled AI harnesses. Without a decision, aibox apply retains the state and prints the preserve-or-purge path without creating a Migration. |
purge_disabled_harness_state | Boolean | No | false | Explicitly removes retained state for disabled AI harnesses on the next aibox apply. |
Environment Variable Overrides
Some settings can be overridden via environment variables:
| Variable | Overrides | Description |
|---|---|---|
AIBOX_HOST_ROOT | .aibox-home/ path | Host directory for persistent config (default: .aibox-home/) |
AIBOX_WORKSPACE_DIR | Workspace mount source | Host directory mounted as /workspace |
AIBOX_LOG_LEVEL | --log-level | Log verbosity (trace, debug, info, warn, error) |
Example:
AIBOX_WORKSPACE_DIR=/home/user/projects/my-app aibox up
3 - Local Config (.aibox-local.toml)
Local Config (.aibox-local.toml)
.aibox-local.toml is a personal, gitignored overlay that sits next to aibox.toml in the project root. It exists for secrets and per-developer settings that must never be committed to version control — API tokens, personal credential paths, and similar values that differ between contributors.
Why it exists
aibox.toml is committed and shared across the team. That’s the right place
for project-wide settings: container name, context mode, processkit version
when processkit is enabled, addons, shared environment variables, and so on.
But tokens and personal bind mounts don’t belong there. .aibox-local.toml
gives every developer a private escape valve without requiring .gitignore
discipline on every secret.
Location and gitignore
.aibox-local.toml lives in the project root, next to aibox.toml:
my-project/
├── aibox.toml ← committed, shared
├── .aibox-local.toml ← gitignored, personal
├── .devcontainer/
└── context/
aibox init and aibox apply automatically add .aibox-local.toml to .gitignore. You do not need to do this manually.
Supported sections
Three sections are supported. Everything else must remain in aibox.toml.
[container.environment]
Inject environment variables into the container. These are merged on top of any [container.environment] values in aibox.toml. If the same key appears in both files, the local value wins.
[container.environment]
GH_TOKEN = "github_pat_xxxxxxxxxxxx"
ANTHROPIC_API_KEY = "sk-ant-api03-..."
OPENAI_API_KEY = "sk-proj-..."
AWS_PROFILE = "my-dev-profile"
aibox apply writes these values to the gitignored .aibox-local.env, which
Docker Compose loads into the container. The values therefore survive
container replacement and image rebuilds. They are still normal container
environment variables: processes running as the container user, including an
AI agent, can read them.
[[container.extra_volumes]]
Personal bind mounts appended after any volumes declared in aibox.toml. Each entry requires source (host path) and target (container path). read_only defaults to false.
[[container.extra_volumes]]
source = "~/.aws"
target = "/home/aibox/.aws"
read_only = true
[[container.extra_volumes]]
source = "~/.ssh/id_ed25519"
target = "/home/aibox/.ssh/id_ed25519"
read_only = true
[mcp]
Personal MCP servers appended to the generated MCP client configs on aibox apply. Use this section for servers you want only on your machine — internal tools, local scripts, or servers that require credentials you don’t want to share.
Each server entry is an [[mcp.servers]] table with the same fields as committed [[ai.mcp.servers]] in aibox.toml:
[[mcp.servers]]
name = "my-internal-tool"
command = "npx"
args = ["-y", "@acme/internal-mcp-server"]
[[mcp.servers]]
name = "local-notes"
command = "/home/user/bin/notes-mcp"
args = ["--db", "~/notes.db"]
[[mcp.servers]]
name = "stripe"
command = "npx"
args = ["-y", "@stripe/mcp"]
[mcp.servers.env]
STRIPE_SECRET_KEY = "sk_test_..."
aibox apply merges personal servers with team servers (from
aibox.toml [ai.mcp]) and, in processkit mode, built-in processkit servers,
then regenerates all MCP client config files. The generated files are
gitignored — they are never committed to version control, so personal keys
and server definitions stay private.
Merge behavior
| Section | Merge rule |
|---|---|
[container.environment] | Merged with aibox.toml; local values win on key conflicts |
[[container.extra_volumes]] | Appended after aibox.toml volumes; no deduplication |
[[mcp.servers]] | Appended after aibox.toml MCP servers; all sources merged into each generated config file |
GitHub authentication
Choose the authentication model according to how much GitHub access the container and its AI agents should receive. A narrowly scoped personal access token (PAT) is the recommended default. An interactive GitHub CLI login is more convenient, but may grant the container substantially broader access.
Recommended: least-privilege PATs
Put the token used for normal GitHub CLI commands in GH_TOKEN. GitHub CLI
reads it automatically:
[container.environment]
GH_TOKEN = "github_pat_default_project_token"
Grant this token only the repositories and permissions the project normally needs. When one workflow needs access to another repository or organization, add a second, purpose-specific variable instead of broadening the default token. For example, a derived project can receive permission to report issues to an upstream project without receiving wider upstream access:
[container.environment]
GH_TOKEN = "github_pat_default_project_token"
PROJECTXXX_ISSUES_TOKEN = "github_pat_upstream_issues_token"
Select the second credential only for the command that needs it:
GH_TOKEN="$PROJECTXXX_ISSUES_TOKEN" \
gh issue create --repo projectious-work/aibox
The temporary assignment overrides GH_TOKEN for that invocation only. The
default token remains active for subsequent commands. Give the additional PAT
only the target repository’s Issues: read and write permission plus the
metadata access GitHub requires.
This arrangement makes the authorization boundary visible in both the local configuration and the command. It also lets a human decide exactly which rights are available to an AI agent in the container.
For a fine-grained PAT that targets an organization repository, select that organization as the token’s resource owner and include the target repository. Organization policy may require an administrator to approve the token. The fact that the user can create an issue in a public repository through the GitHub website does not automatically authorize a repository-scoped PAT to do the same through the API.
Alternative: persistent GitHub CLI login
For a trusted personal workspace where broad account access is acceptable, log in from inside the running container:
gh auth login --hostname github.com --web --git-protocol https --insecure-storage
--insecure-storage tells GitHub CLI to store its OAuth token in its config
file instead of a system keyring. In an aibox container that file is under
/home/aibox/.config/gh/, backed by the project’s gitignored
.aibox-home/.config/gh/ directory. It survives container restarts,
replacements, and image rebuilds. The token is a GitHub bearer credential; it
is not tied to a particular container ID or image.
GH_TOKEN and GITHUB_TOKEN take precedence over credentials saved by
gh auth login. To use the stored login, remove both variables from
.aibox-local.toml and from any other container environment configuration,
then run aibox apply to regenerate .aibox-local.env and recreate or restart
the container as needed.
Check the effective authentication inside the container with:
env | grep -E '^(GH_TOKEN|GITHUB_TOKEN)='
gh auth status
gh api user --jq .login
The first command should produce no output.
The stored OAuth token is plaintext in .aibox-home/.config/gh/hosts.yml.
Gitignore prevents accidental normal commits, but it does not encrypt the
credential or protect it from the host user, container processes, AI agents,
backups, malware, or an explicit git add --force. Treat .aibox-home/ as
secret-bearing local state. Prefer scoped PATs when the container should not
inherit the human user’s broader GitHub authority.
Full example
A typical .aibox-local.toml for a developer working with Claude, GitHub, and AWS, plus a personal MCP server:
[container.environment]
ANTHROPIC_API_KEY = "sk-ant-api03-..."
GH_TOKEN = "github_pat_xxxxxxxxxxxx"
AWS_PROFILE = "my-dev-profile"
AWS_REGION = "eu-west-1"
[[container.extra_volumes]]
source = "~/.aws"
target = "/home/aibox/.aws"
read_only = true
[[container.extra_volumes]]
source = "~/.ssh/id_ed25519"
target = "/home/aibox/.ssh/id_ed25519"
read_only = true
[[mcp.servers]]
name = "my-internal-tool"
command = "npx"
args = ["-y", "@acme/internal-mcp-server"]
What is NOT supported
Everything outside of [container.environment], [[container.extra_volumes]], and [[mcp.servers]] is ignored. The following must remain in aibox.toml:
- Container name, hostname, user, lifecycle, image, and generated paths
[context]— context mode and processkit package selection[addons]— addon configuration[processkit]— content source and version pin when processkit mode is enabled[skills]— enabled/disabled lists when processkit mode is enabled[ai]— harnesses, agents, and team MCP servers[customization]— theme, mode, prompt, layout[audio]— audio bridging
After editing .aibox-local.toml, run aibox apply (or aibox apply --no-build for a config-only refresh) to regenerate .devcontainer/ files with the updated environment and volumes, and MCP client config files with the updated server list.
4 - Cheatsheet
Keyboard Shortcuts
Quick reference for all tools in the aibox environment. Press the tab for the tool you need.
!!! tip “In-app help”
- tmux: The status bar always shows available keys for the current mode
- Yazi: Press ~ or F1 to see all keybindings
- Vim: Type :help for built-in help
- lazygit: Press ? to see context-sensitive keybindings when the optional git-ui addon is enabled
=== “tmux”
## tmux (Terminal Multiplexer)
Leader key: ++ctrl+b++ — press and release, then press the action key.
### Pane Navigation
| Key | Action |
|-----|--------|
| `Ctrl+g` `h` / `Left` | Focus pane left |
| `Ctrl+g` `j` / `Down` | Focus pane down |
| `Ctrl+g` `k` / `Up` | Focus pane up |
| `Ctrl+g` `l` / `Right` | Focus pane right |
### Pane Management
| Key | Action |
|-----|--------|
| `Ctrl+g` `n` | New pane (best direction) |
| `Ctrl+g` `d` | Split down |
| `Ctrl+g` `r` | Split right |
| `Ctrl+g` `x` | Close current pane |
| `Ctrl+g` `f` | Toggle fullscreen |
| `Ctrl+g` `e` | Toggle embed / floating |
| `Ctrl+g` `z` | Toggle pane frames |
| `Ctrl+g` `=` | Increase pane size |
| `Ctrl+g` `-` | Decrease pane size |
### Window Management
| Key | Action |
|-----|--------|
| `Ctrl+g` `t` | New window |
| `Ctrl+g` `w` | Close window |
| `Ctrl+g` `[` | Previous window |
| `Ctrl+g` `]` | Next window |
| `Ctrl+g` `1`..`5` | Jump to window by number |
| `Ctrl+g` `i` | Move window left |
| `Ctrl+g` `o` | Move window right |
### Scroll & Search
| Key | Action |
|-----|--------|
| `Ctrl+g` `u` | Enter scroll mode |
| `Ctrl+g` `/` | Search scrollback |
**In scroll mode:**
| Key | Action |
|-----|--------|
| `j` / `k` | Scroll down / up |
| `d` / `u` | Half-page down / up |
| `f` / `b` | Full page down / up |
| `g` / `G` | Top / bottom |
| `/` | Search |
| `q` or `Esc` | Exit scroll mode |
**In search mode:**
| Key | Action |
|-----|--------|
| `n` / `N` | Next / previous match |
| `c` | Toggle case sensitivity |
| `w` | Toggle wrap |
| `o` | Toggle whole word |
### Session
| Key | Action |
|-----|--------|
| `Ctrl+g` `s` | Session chooser |
| `Ctrl+g` `m` | Session manager |
### Quit
| Key | Action |
|-----|--------|
| `Ctrl+g` `q` | Quit tmux |
| `Ctrl+q` | Quit tmux (global) |
!!! info "Default layout windows"
The generated `dev` layout opens with pre-configured tmux windows:
**work** (Yazi, 1st harness, shell), optional **lazygit**,
**ai** for further harnesses, and **shell**. Window numbers shift when
optional windows are omitted.
=== “Yazi”
## Yazi (File Manager)
Yazi uses Vim-style navigation. The aibox config adds a few custom bindings on top of the defaults.
### Navigation
| Key | Action |
|-----|--------|
| `h` / `Left` | Go to parent directory |
| `j` / `Down` | Move cursor down |
| `k` / `Up` | Move cursor up |
| `l` / `Right` / `Enter` | Open file or enter directory |
| `g` `g` | Go to first item |
| `G` | Go to last item |
| `~` | Go to home directory |
### Opening Files (aibox custom)
| Key | Action |
|-----|--------|
| `Enter` | Open file in-place (suspends Yazi, `:q` returns) |
| `e` | Open in adjacent Vim pane (stays in Yazi) |
| `O` | Interactive opener selection |
### File Operations
| Key | Action |
|-----|--------|
| `a` | Create new file or directory (append `/` for directory) |
| `r` | Rename file |
| `d` | Trash selected files |
| `D` | Permanently delete selected files |
| `y` | Yank (copy) selected files |
| `x` | Yank (cut) selected files |
| `p` | Paste yanked files |
| `Space` | Toggle selection on current file |
| `v` | Visual mode (select range) |
| `V` | Invert selection |
### Search & Filter
| Key | Action |
|-----|--------|
| `/` | Search files in current directory |
| `f` | Filter files (fuzzy match) |
| `.` | Toggle hidden files |
### Preview & Tabs
| Key | Action |
|-----|--------|
| `Tab` | Switch preview pane |
| `t` | Create new tab |
| `1`..`9` | Switch to tab by number |
| `[` / `]` | Previous / next tab |
### Misc
| Key | Action |
|-----|--------|
| `z` | Jump to directory (zoxide) |
| `:` | Open command shell |
| `~` / `F1` | View all keybindings |
| `q` | Quit Yazi |
=== “Vim”
## Vim (Editor)
Leader key: `Space`
### Leader Commands
| Key | Action |
|-----|--------|
| `Space` `w` | Save file |
| `Space` `q` | Quit |
| `Space` `x` | Save and quit |
| `Space` `n` | Next buffer |
| `Space` `p` | Previous buffer |
| `Space` `l` | List buffers |
| `Space` `e` | Open netrw file explorer |
### Split Navigation
| Key | Action |
|-----|--------|
| `Ctrl+h` | Move to left split |
| `Ctrl+j` | Move to split below |
| `Ctrl+k` | Move to split above |
| `Ctrl+l` | Move to right split |
### Essential Motions
| Key | Action |
|-----|--------|
| `h` `j` `k` `l` | Left, down, up, right |
| `w` / `b` | Next / previous word |
| `0` / `$` | Start / end of line |
| `gg` / `G` | Top / bottom of file |
| `Ctrl+d` / `Ctrl+u` | Half-page down / up |
| `%` | Jump to matching bracket |
| `f{char}` | Jump to next {char} on line |
### Editing
| Key | Action |
|-----|--------|
| `i` / `a` | Insert before / after cursor |
| `I` / `A` | Insert at start / end of line |
| `o` / `O` | New line below / above |
| `dd` | Delete line |
| `yy` | Yank (copy) line |
| `p` | Paste after cursor |
| `u` / `Ctrl+r` | Undo / redo |
| `.` | Repeat last change |
| `ciw` | Change inner word |
| `>>` / `<<` | Indent / dedent line |
### Search
| Key | Action |
|-----|--------|
| `/pattern` | Search forward |
| `?pattern` | Search backward |
| `n` / `N` | Next / previous match |
| `Esc` `Esc` | Clear search highlight |
| `*` | Search word under cursor |
### Commands
| Key | Action |
|-----|--------|
| `:w` | Save |
| `:q` / `:q!` | Quit / force quit |
| `:wq` or `:x` | Save and quit |
| `:e <file>` | Open file |
| `:%s/old/new/g` | Find and replace in file |
!!! note "Dev-box Vim settings"
- Relative line numbers are enabled for fast `{N}j`/`{N}k` jumps
- Tabs expand to 4 spaces (2 for YAML, JSON, HTML, CSS, JS, TS)
- Trailing whitespace is stripped on save
- Persistent undo is enabled across sessions
=== “lazygit”
## lazygit (Git TUI)
lazygit is panel-based. Press `?` at any time to see context-sensitive keybindings.
### Panel Navigation
| Key | Action |
|-----|--------|
| `1` | Status panel |
| `2` | Files panel |
| `3` | Branches panel |
| `4` | Commits panel |
| `5` | Stash panel |
| `h` / `l` | Switch panels left / right |
| `j` / `k` | Move up / down within panel |
| `[` / `]` | Previous / next tab within panel |
### Files Panel
| Key | Action |
|-----|--------|
| `Space` | Stage / unstage file |
| `a` | Stage / unstage all files |
| `c` | Commit staged changes |
| `A` | Amend last commit |
| `d` | Discard changes to file |
| `e` | Edit file in editor |
| `o` | Open file in default application |
| `i` | Add to .gitignore |
| `S` | Stash all changes |
| `Enter` | Focus on file to see diff hunks |
### Branches Panel
| Key | Action |
|-----|--------|
| `Space` | Checkout branch |
| `n` | New branch |
| `d` | Delete branch |
| `M` | Merge into current branch |
| `r` | Rebase current branch onto selected |
| `R` | Rename branch |
| `f` | Fetch branch |
| `P` | Push |
| `p` | Pull |
### Commits Panel
| Key | Action |
|-----|--------|
| `s` | Squash commit into one below |
| `r` | Reword commit message |
| `R` | Reword with editor |
| `d` | Delete commit |
| `e` | Edit commit (interactive rebase) |
| `c` | Copy commit (cherry-pick) |
| `v` | Paste (cherry-pick) commit |
| `F` | Create fixup commit |
| `S` | Squash all fixup commits |
| `g` | Reset to this commit |
| `t` | Tag commit |
### Stash Panel
| Key | Action |
|-----|--------|
| `Space` | Apply stash (keep in list) |
| `g` | Pop stash (apply + remove) |
| `d` | Drop stash entry |
### Global
| Key | Action |
|-----|--------|
| `?` | Show keybindings for current panel |
| `+` | Show command log |
| `@` | Show command log menu |
| `P` | Push |
| `p` | Pull |
| `z` / `Ctrl+z` | Undo last action |
| `q` | Quit lazygit |
!!! tip "Accessing lazygit"
lazygit is available only when the optional `git-ui` addon selects
`lazygit`. In generated layouts, aibox adds it as a fullscreen **git**
tab after any AI-agent tabs.
5 - Compatibility
Compatibility
aibox ↔ processkit Version Matrix
Each aibox release is tested against a specific processkit version. The table below shows the minimum compatible processkit version for each aibox release.
| aibox version | Min. processkit | Notes |
|---|---|---|
| 0.29.0 | v0.28.5 | adds Tau as a first-class multi-provider coding-agent harness with pinned installation, persistent runtime state, AGENTS.md discovery, Agent Skills projection, and explicit reporting that Tau does not currently expose a built-in MCP client |
| 0.28.19 | v0.28.5 | preserves prerelease identifiers when resolving the latest published GHCR image so v1.0.0-alpha.1 is not rewritten to the nonexistent v1.0.0 tag |
| 0.28.18 | v0.28.5 | restores Codex processkit MCP startup by preserving uv run --script in gateway daemon-proxy commands, integrates processkit’s MCP 1.x compatibility bound, and restores zero-warning clippy under Rust 1.97 |
| 0.28.17 | v0.28.4 | repairs Go, Typst, AWS CLI, and Node.js add-on installers and adds a clean companion-container build gate for download-based add-on defaults |
| 0.28.16 | v0.28.4 | installs Node.js from checksum-verified official release archives after the NodeSource signing-key endpoint became unavailable and refreshes generated runtime and processkit package-selection state |
| 0.28.14 | v0.28.4 | ensures pk-reconcile and pk-repo-reconcile install their project-reconciliation and repo-management skill dependencies |
| 0.28.15 | v0.28.4 | refreshes bundled maintenance tools, locks cargo-audit installation for Rust compatibility, and publishes the Hugo/Docsy documentation site |
| 0.28.13 | v0.28.4 | adds open GitHub Discussion counts to the tmux Forge status segment and restores the complete generated Codex command projection set |
| 0.28.12 | v0.28.4 | integrates processkit v0.28.4 and makes companion E2E validation work from linked release worktrees |
| 0.28.11 | v0.28.3 | adds the cloudflare addon, which installs cloudflared from Cloudflare’s signed package repository rather than Debian’s archive |
| 0.28.10 | v0.28.3 | reconciles standard processkit skills, recommends tooling-linked skills interactively, upgrades prerelease processkit surfaces, and serializes release Tier 2 E2E validation |
| 0.28.6 | v0.28.3 | fixes Kubernetes addon checksum verification for Helm, Kustomize, and k9s archives on amd64 and arm64; and integrates processkit v0.28.3 authenticated GitHub repository reconciliation |
| 0.28.5 | v0.28.1 | fixes Hermes Agent installation under the non-root runtime model; restores configured lazygit runtime surfaces; completes processkit reconciliation; and enforces traceable ports between maintained v0.x and v1.x lines |
| 0.28.4 | v0.28.1 | integrates processkit v0.28.1 and refreshes the maintained v0.x processkit compatibility baseline |
| 0.28.3 | v0.27.6 | integrates processkit v0.27.6; makes GitHub CLI authoritative for github.com HTTPS credentials; exposes exact GitHub SSH aliases through Forge; and preserves LaTeX preview state across rebuilds |
| 0.28.2 | v0.27.5 | integrates derived-project doctor applicability fixes, Git-ignore-aware sensitive-data scanning, 30-day archive-age enforcement, generated schema foundations, migration drafting, repository portfolio review, and refreshed gateway metadata |
| 0.28.1 | v0.27.4 | restores Codex processkit aliases through /prompts:pk-*; adds local fuzzy documentation search; moves LaTeX build and watch ownership into the development container; and adds a hardened read-only, multi-document preview sidecar with full lifecycle coverage |
| 0.28.0 | v0.27.4 | adds named LaTeX build, watch, status, and EmbedPDF live-preview workflows; manages preview lifecycle through aibox up/down; generates project-local agent guidance; and documents persistent, least-privilege GitHub authentication with explicit per-destination tokens |
| 0.27.8 | v0.27.2 | integrates processkit derived-project remediation: project-local pk-commands preservation/schema validation, timestamped role-slot binding IDs, explicit doctor confirmation forwarding, archive remediation metadata, migration archive policy documentation, and refreshed gateway metadata |
| 0.27.7 | v0.27.1 | fixes the TeX Live historic installer mirror, resolves pk-doctor false positives, preserves disabled harness state, and accepts context mode in schema validation |
| 0.27.6 | v0.27.1 | refreshes tool and harness pins, updates generated runtime/docs references, and adds the GitHub CLI credential-helper integration for HTTPS Git operations |
| 0.27.5 | v0.27.1 | refreshes the shipped docs-hugo pin to Hugo 0.162.1 and aligns release-state/docs inventory with the current addon and harness defaults from v0.27.4 |
| 0.27.4 | v0.27.1 | refreshes all shipped addon and harness tool defaults to current upstream releases; fixes Yarn 4 and Python 3.14 installation paths; moves Hermes to the current hermes-agent package installer; updates Rust/docs dependencies; and quiets actionable pk-doctor false positives while making release-integrity checks bounded |
| 0.27.3 | v0.27.1 | integrates processkit v0.27.1 derived-project health cleanup, including quieter pk-doctor sensitive-data checks, gateway-aware preauth validation, sqlite-vec availability for pk-doctor MCP runs, supply-chain policy no-policy INFO handling, and a Codex processkit-gateway startup timeout so uv-backed gateway startup does not trip Codex’s 30-second default |
| 0.27.2 | v0.27.0 | fixes the docs-hugo addon checksum verification so Hugo archives downloaded to /tmp/hugo.tar.gz are checked against the matching release checksum entry instead of the upstream asset filename |
| 0.27.1 | v0.27.0 | refreshes addon and user-facing toolchain pins, including documentation generators, language package managers, infrastructure tooling, Kubernetes tools, Helm, and OpenCode; adds release-state coverage for addon pins plus LaTeX and apt-managed inputs; keeps Python interpreter selection tied to the Debian base image package set; fixes OpenCode release asset naming and checksum verification; updates docs-site dependencies and clears npm audit findings |
| 0.27.0 | v0.27.0 | integrates processkit v0.27.0 and the v0.26.17 supply-chain audit surface; switches the next-minor GHCR image scheme to foundation/runtime tags, stops publishing public source-hash marker tags, preserves legacy base-debian-v0.26.x compatibility, adds GHCR source-tag cleanup tooling, adds release LICENSE guardrails, and fixes pasted host newlines by removing global tmux C-j navigation |
| 0.26.8 | v0.26.16 | integrates processkit v0.26.16; refreshes the processkit template mirror, provenance, MCP manifest, TeamMember privacy defaults, and team consistency checks; makes latest image resolution skip GHCR tags whose multi-arch manifest children have been pruned |
| 0.26.7 | v0.26.15 | integrates processkit v0.26.15; adds provider-neutral AI execution policy axes and per-harness overrides, maps execution policy to Codex settings, preserves the processkit MCP manifest in derived installs, and refreshes documentation recordings |
| 0.26.6 | v0.26.14 | integrates processkit v0.26.14; updates processkit metadata to the new release and preserves tmux/Vim/cheatsheet and clipboard behavior consistency |
| 0.26.5 | v0.26.13 | re-architects theme selection around theme families plus mode/variant, adds the 61-theme gallery and per-theme recordings, ships PowerKit/cheatsheet/runtime theme fixes, and preserves legacy concrete theme intent during standardization |
| 0.26.4 | v0.26.10 | integrates processkit v0.26.10; makes explicit tmux model-provider status elements render even without global provider polling; preserves Claude Code OAuth/state across container rebuilds via Claude XDG cache/config/state mounts; enables terminal extended-key passthrough for Alt-Enter; adds PowerKit GitHub issue/PR counts; and fixes aibox-status AI agent counting so vendor helper processes do not inflate provider instance totals |
| 0.26.3 | v0.26.9 | fixes GHCR latest-version resolution by requesting larger tag-list pages and following Docker Registry v2 pagination links so freshly-published images are visible to aibox apply |
| 0.26.2 | v0.26.9 | fixes duplicate [customization.tmux.status] table parsing, routes tmux helper scripts through the managed socket, removes structurally broken capture-pane visual tests, and keeps visual layout/theme work tracked for asciinema coverage |
| 0.26.1 | v0.26.9 | verifies GHCR release-host image pushes, fixes Yazi rich-preview API/cache behavior, suppresses recurring legitimate processkit template mirror repair warnings, emits migration affected files, and integrates processkit v0.26.9 |
| 0.26.0 | v0.26.7 | refreshes themes, live tmux layout/theme choosers, Yazi rich preview, Vim Alt-key handling, model-provider agent counts, statusline structure, and processkit v0.26.7 integration |
| 0.25.14 | v0.26.5 | integrates processkit v0.26.5; restores generated and image fallback Alt-word movement in Vim/readline; adds managed .inputrc runtime projection; carries tmux clipboard/terminal feature improvements into generated and image fallback configs; keeps Rust cache mounts from shadowing image-provided cargo/rustc shims; and keeps the stricter processkit schema/file-layout migration path clean under pk-doctor |
| 0.25.13 | v0.26.2 | fixes stale runtime-home propagation by making aibox-managed .aibox-home files authoritative on apply and clean runtime recreation; broadens generated runtime mounts for Vim and Cargo cache directories; updates generated compose/docs coverage; and adds regression coverage for stale tmux/Yazi managed file refresh |
| 0.25.12 | v0.26.2 | fixes fresh-project tmux/PowerKit runtime projection by using broad writable runtime-home mounts, refreshing managed theme/Yazi/Codex files on apply, scoping preauth/MCP writes to enabled harnesses, recognizing nested processkit skill catalogs in doctor, and reducing host-side doctor probes for container-owned dependencies |
| 0.25.11 | v0.26.2 | fixes source-checkout addon discovery, PowerKit status cache writability, generated runtime writability diagnostics, disabled-harness migration schema metadata, and tmux/Yazi status glyph defaults |
| 0.25.10 | v0.26.2 | integrates processkit v0.26.2; adds configurable tmux status labels/layouts and model-provider health segments; reduces PowerKit refresh churn; stabilizes runtime MCP diagnostics; verifies release checksum sidecars; and improves image layer/cache reuse across apply/up and host release publishing |
| 0.25.9 | v0.26.1 | integrates processkit v0.26.1; retires yazi-omp runtime support; migrates tmux status configuration to list-based slot ordering; preserves user-selected themes during standardization; suppresses Kubernetes/cloud PowerKit auth/probe flashes; and improves Yazi directory git status behavior |
| 0.25.8 | v0.26.0 | improves the tmux log viewer, filters aibox log counts to the current container session, emits low-volume diagnostics sidecar lifecycle samples, moves PowerKit metrics into the owner-specified two-row layout, and updates generated tmux layouts around ordered harness semantics |
| 0.25.7 | v0.25.8 | introduces generated-container cleanup controls, prunes SSH companion nested runtime state around Tier 2 E2E tests, adds aibox prune, and documents managed runtime cleanup policy |
| 0.25.6 | v0.25.8 | expands tmux/PowerKit theme coverage with light/dark partner handling, generated theme comments, Docusaurus theme documentation, and runtime border/status color improvements |
| 0.25.5 | v0.25.8 | refreshes managed tmux runtime files when recreating sessions so aibox.toml status/layout settings take effect, preserves the delayed Yazi pane startup path, and suppresses stale default-socket tmux kill-session noise on host attach |
| 0.25.4 | v0.25.8 | repairs tmux release-host smoke probing after the managed tmux socket migration and fixes generated tmux status-right rendering by preserving the aibox runtime status segment |
| 0.25.3 | v0.25.8 | fixes Yazi e editor handoff for tmux by targeting the existing Vim pane/window, documents tmux status modes and element toggles, makes skill-finder discover deselected skills from the template catalog, and tightens SSH companion guidance |
| 0.25.2 | v0.25.8 | adds tmux-native prefix ? keybinding popup, upgrades the two-line PowerKit status with pane context/mode detail, labels status metrics in aibox-status, fixes startup layout targeting by selecting named tmux windows instead of $session:1, extends release/runtime caching behavior, and documents provider endpoint base URL hints (ANTHROPIC_BASE_URL, OPENAI_BASE_URL, GEMINI_BASE_URL, MISTRAL_BASE_URL) |
| 0.25.0 | v0.25.8 | replaces the prior multiplexer runtime with tmux-native layouts and status, keeps the diagnostics sidecar and visual testing gates, documents TPM as a user convenience layer only, preinstalls and pins aibox-managed tmux plugins, and ships tmux-resurrect/tmux-continuum installed but disabled by default until persistence policy is decided |
| 0.24.1 | v0.25.8 | fixes generated compose so the main service starts with the image default root entrypoint user again, allowing entrypoint.sh to remap/drop to aibox instead of failing with failed switching to "aibox": operation not permitted during release-host runtime smoke |
| 0.24.0 | v0.25.8 | adds the bounded diagnostics sidecar, replaces the shell fan-out aibox-status helper with Rust snapshot readers, wires sidecar-backed Zellij status rows, adds aibox emergency <harness>, keeps legacy native/hidden status aliases while emitting sidecar/disabled, and reduces host release smoke to a minimal default tier with opt-in addon/full tiers |
| 0.23.21 | v0.25.8 | repairs generated Yazi git/status initialization for Yazi 26; preserves native Zellij plugin permission caches across runtime starts; adds doctor and E2E guardrails for native Zellij permission-cache projection drift; installs the Yazi ya companion entrypoint in runtime images; slims visual E2E release gates with per-case progress logging and an opt-in exhaustive matrix |
| 0.23.20 | v0.25.8 | makes the release runtime smoke harness host-safe by defaulting to shell Zellij status mode, capturing raw TUI output into logs instead of streaming escape sequences to the host terminal, and asserting on structured probe markers rather than terminal transcripts |
| 0.23.19 | v0.25.8 | hardens generated runtime startup by keeping Vim eager while disabling its startup cursor-position probe; removes suspended generated AI panes; pre-seeds native Zellij plugin permissions; fixes service-specific Codex bubblewrap seccomp fallback; updates Yazi git/preview config; adds generated-runtime and opt-in visual E2E release gates |
| 0.23.18 | v0.25.8 | updates generated Yazi config and theme filetype rules for Yazi 26’s url/mime matcher schema; provides writable XDG state mounts for lazygit and similar TUIs; records follow-up runtime diagnostics and host-phase runtime smoke work |
| 0.23.17 | v0.25.8 | installs Claude Code from Anthropic’s signed apt repository with a stable /usr/local/bin/claude path; makes the native aibox Zellij status/key-hint plugin the generated default; starts shell and lazygit tabs hot across layouts; refreshes Zellij, Yazi, uv, and Cargo dependencies; improves release-state reporting and harness version-pin support |
| 0.23.16 | v0.25.8 | moves Claude processkit command shims to Claude Code’s current Skills layout, cleans legacy managed .claude/commands files, fixes native Zellij key-hint rendering, keeps Vim editor panes hot for Yazi edit handoff, and adds a pre-release dependency/harness state report |
| 0.23.15 | v0.25.8 | fixes a 0.23.14 --standardize-config regression where a blank [ai.harness.<name>] table could re-enable a commented-out harness; standard config rewrites also restore the standard processkit skill list instead of leaving every skill commented |
| 0.23.14 | v0.25.8 | canonical generated aibox.toml now uses [ai.harness.<name>] tables instead of the compact harness list; aibox apply --standardize-config performs an opt-in schema-clean canonical rewrite; stale/deprecated generated comments were removed; Yazi e again opens files in the dedicated Vim pane/tab |
| 0.23.13 | v0.25.8 | fixes 0.23.11-to-0.23.12 generated-config upgrades where a moved tool, such as gh, still sits under its old addon owner; aibox apply now migrates misplaced addon tool entries to their unique current catalog owner before strict validation and comment refresh |
| 0.23.12 | v0.25.8 | processkit v0.25.8 Xiaomi MiMo model-routing content and cleanup-hint provenance, native aibox Zellij key/status bar refinements, semantic AI/audio config sections, stable Claude CLI install path, addon tool validation, and stale processkit-managed skill detection |
| 0.23.11 | v0.25.7 | grouped aibox.toml schema around aibox, container, processkit, and ai sections; catalog-style AI harness/model-provider controls; generated path settings; product skill defaults; and managed Zellij status runtime repair |
| 0.23.10 | v0.25.7 | processkit v0.25.7 model-routing content, apply-time aibox.toml structure migration, self-documenting generated config comments, addon-backed image-slimming switches, and generated-runtime release finalization |
| 0.23.9 | v0.25.6 | restores shell-backed Zellij status rows as the default, hardens aibox-status against /proc races, fixes Yazi edit actions, applies addon dependency fallback handling to aibox up, and integrates processkit v0.25.6 provider-neutral pk command projections |
| 0.23.8 | v0.25.5 | native aibox Zellij status plugin now exports the literal WASM entrypoints Zellij loads, uses theme-default readable foreground text, and has no-container E2E coverage for the load/visibility regression |
| 0.23.7 | v0.25.5 | host-generated Codex processkit-gateway MCP paths now target the devcontainer workspace mount, preserving subagent-safe absolute paths without leaking host-only paths; doctor warns about stale host-side Codex MCP script paths |
| 0.23.6 | v0.25.5 | processkit v0.25.5 active interlocutor runtime binding, subagent MCP lifecycle guardrails, Codex MCP path fixes, addon fallback migrations, doctor schema/runtime-template diagnostics, lazygit-disabled cleanup, native Zellij status visibility, and stronger E2E coverage |
| 0.23.5 | v0.25.4 | generated Dockerfile lazygit disablement cleanup no longer aborts when lazygit is absent as an apt package, while still removing inherited lazygit binaries |
| 0.23.4 | v0.25.4 | processkit v0.25.4 gateway stdio-proxy daemon startup fixes, Codex pre_tool_use hook generation, Zellij status presentation control, and stale status-layout runtime sync repair |
| 0.23.3 | v0.25.3 | processkit v0.25.3 model-spec/model-profile migrations and Codex seccomp fallback for bubblewrap |
| 0.23.2 | v0.25.1 | processkit v0.25.1 model-recommender lifecycle metadata, task suitability classes, task-class-aware routing, and refreshed model roster |
| 0.23.1 | v0.25.0 | stale runtime cleanup for old Compose project names, lazygit disablement fixes, and procps runtime diagnostics |
| 0.23.0 | v0.25.0 | processkit v0.25.0 gateway integration, daemon-proxy mode, runtime pressure diagnostics, init reaping, optional git UI tools, and profile-aware environment metadata |
| 0.22.0 | v0.24.0 | processkit v0.24.0: context archiving, richer model routing metadata, semantic task-router scoring, archive-aware index metadata |
| 0.21.2 | v0.23.1 | processkit v0.23.1 release-audit cleanup and skill metadata fixes |
| 0.21.1 | v0.23.0 | processkit v0.23.0 model governance and release-audit integration |
| 0.21.0 | v0.22.0 | multi-harness slash-command scaffolding and content-diff safety fixes |
| 0.20.0 | v0.22.0 | processkit install integrity, preauth merge, and no-container scaffold mode |
| 0.19.0 | v0.21.0 | MCP permission configuration and processkit v0.21 content integration |
| 0.17.16 | v0.13.0 | BREAKING: rename providers = ["codex"] → ["openai"]; fix zellij --layout flag; fix Rust x86_64 cross-compile target |
| 0.17.15 | v0.13.0 | MCP config model, zjstatus hints, Zellij Ctrl+q, processkit v0.13.0 |
| 0.17.5 | v0.8.0 | processkit v0.8.0 GrandLily src/ restructure |
| 0.17.4 | v0.6.0 | content migration documents (pending/in-progress/applied) |
| 0.17.3 | v0.6.0 | Claude Code slash-command adapters |
| 0.17.2 | v0.6.0 | core skill enforcement, processkit v0.6.0 compat |
| 0.17.0 | v0.5.0 | aibox.lock sectioned format |
| 0.16.1 | v0.4.0 | sync auto-install added |
| 0.16.0 | v0.4.0 | initial processkit integration |
How compatibility is enforced
In processkit mode, aibox apply compares the [processkit].version in your
aibox.toml against the minimum required version for the running aibox binary.
If the pinned processkit version is older than the minimum, a warning is
emitted:
Warning: processkit v0.24.0 is below the minimum recommended version v0.25.0 for aibox v0.23.0 ...
This is a warning, not an error — older processkit versions can still install
successfully when their layout is still supported. The warning is a nudge to
upgrade, not a blocker. Harness-only projects do not install processkit content,
so this matrix only matters when [context].mode = "processkit".
Upgrading processkit
To upgrade processkit in an existing project:
Edit
aibox.toml:[processkit] version = "v0.25.5"Run
aibox applyon the host — the 3-way diff will show changed content and generate processkit content migration documents incontext/migrations/pending/.Review and apply the pending migrations.
6 -
Security Reference
This page documents aibox’s security model and trust boundaries.
Support and vulnerability reporting
aibox is actively maintained. The latest minor release line is supported;
security and correctness fixes are released on the newest version rather than
backported across older minor lines. See the repository
SECURITY.md
for private reporting instructions and response expectations.
Dependency and asset provenance review
The project uses several independent integrity layers:
| Surface | Provenance control | Release validation |
|---|---|---|
| Rust CLI | cli/Cargo.lock pins the complete dependency graph | cargo test, Clippy with warnings denied, and cargo audit |
| Documentation | docs-site/package-lock.json and the Docsy submodule pin dependencies | clean npm ci, production Hugo build, and npm audit |
| processkit | source, version, and release-asset SHA-256 are recorded in aibox.lock and live provenance | installer hash verification, three-way content comparison, and pk-doctor integrity checks |
| Base images | release-specific image tags, OCI source/profile labels, and generated version markers | cross-platform build, GHCR publication verification, and downstream runtime smoke |
| Addon downloads | pinned versions plus SHA-256, signed checksum, or upstream sidecar verification where available | release-state inventory and real container lifecycle tests |
| Release binaries | locally cross-compiled artifacts attached to a signed release tag | version smoke tests and evidence-bound artifact checksums |
The release-state report records floating inputs and available updates before each release. A clean security audit is mandatory; routine non-security drift may be deferred only into a processkit WorkItem. Provenance exceptions are documented next to the relevant installer instead of being silently accepted.
This review was consolidated for aibox issue #80. It is kept current through the local release gate and the public maintenance guide.
Data handling review
aibox does not provide a hosted service and does not send product telemetry. The CLI operates on the local project, generates container configuration, and contacts external services only for requested dependency, image, processkit, GitHub, documentation, or release operations.
aibox.toml, generated.devcontainer/files, and processkit context are project data and are normally committed..aibox-local.toml,.aibox-home/,.aibox/, authentication state, SSH material, local caches, diagnostics, and release evidence are local state and must remain ignored unless a specific artifact has been reviewed for publication.- Tokens enter containers through explicit local environment configuration. Prefer separate least-privilege tokens and select cross-account tokens per command instead of exposing a human account’s full authorization.
- Enabled AI harnesses and MCP servers execute with the container user’s access to the workspace and mounted credentials. Their providers may receive prompt, tool, and file content according to the provider’s own service terms.
aibox doctorand pk-doctor inspect local state. Diagnostic reports must be reviewed and redacted before they are attached to public issues.
No generated local credential, cache, or diagnostic directory belongs in a release artifact. The release process builds from tracked source, verifies the exact commit, and publishes only the declared binaries, documentation output, and container images.
MCP Gateway Trust Scope
How processkit skills are registered
When [context].mode = "processkit" and aibox apply registers processkit
skills (such as processkit-gateway, workitem-management, etc.), it calls
into cli/src/mcp_registration.rs. For Codex, the generated project config
sets:
[project]
trust_level = "trusted"
This means every installed skill’s mcp/server.py runs with project-user
trust inside the aibox container — the same trust level as the project owner
who launched the container. The MCP server process inherits the container
filesystem and environment, including any mounted credentials.
When [context].mode = "harness-only", aibox does not install or register
processkit skills, processkit hooks, processkit preauth rules, or the
processkit MCP gateway. Team and personal MCP servers configured under
[ai.mcp] / .aibox-local.toml [[mcp.servers]] are still generated for
enabled harnesses and carry their own trust review burden.
Implications
- A skill’s
mcp/server.pycan read, write, and execute within the container with the same permissions as the project user. - Skills can access mounted SSH keys (
~/.ssh), API key env vars, and the full workspace at/workspace. - Skills are registered at the Codex/Claude
projectscope — they are active for every session in the container.
Third-party skill review checklist
Before installing a skill from a third party (outside the processkit core), verify:
- Source code is auditable: the skill’s
mcp/server.py(and any imported modules) are readable and understandable. - No unexpected outbound network calls: the skill should not exfiltrate data to external endpoints.
- No credential access beyond stated purpose: check for reads of
~/.ssh/, env vars (ANTHROPIC_API_KEY, etc.), or~/.claude/~/.codex. - Tool list is minimal: the
allowed_toolsset registered by the skill should match only the capabilities the skill claims to need. - Dependency supply chain: if the skill uses
uvorpipto install Python packages, reviewpyproject.toml/requirements.txtfor unexpected dependencies. - Immutable or pinned source: prefer skills pinned to a specific git SHA
or release tag over floating
main/latestreferences.
Opting out of a skill
To remove a skill and deregister its MCP server:
- Remove the skill from
context/skills/or update[processkit]config. - Run
aibox apply— this rewrites the harness MCP configuration files and removes the skill’sallowed_toolsentries. - Recreate the container (
docker compose up -d --force-recreate) so the new MCP configuration takes effect.
seccomp=unconfined Consent Gate
The Codex CLI uses bubblewrap for Linux sandboxing. Some container runtime
seccomp profiles block unprivileged user namespace creation before bubblewrap
can set up its own sandbox. To work around this, aibox apply can emit
seccomp=unconfined in the generated docker-compose.yml.
Explicit consent is required. Without the acknowledgement flag, aibox apply
will error with a remediation pointer. To opt in, add to aibox.toml:
[security]
acknowledge_seccomp_unconfined = true
This setting:
- Allows
aibox applyto emitseccomp=unconfinedindocker-compose.yml. - Suppresses the
aibox doctorwarning about unapproved seccomp relaxation. - Documents in source control that the project owner has accepted the
trade-off: reduced seccomp filtering in exchange for Codex bubblewrap
user-namespace sandboxing, avoiding the broader
privileged=trueorCAP_SYS_ADMINescalations.
seccomp=unconfined does not grant root or additional Linux capabilities —
it only lifts the seccomp syscall filter, allowing bubblewrap to create
user namespaces.