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

OptionEnvironment VariableDefaultDescription
--config <PATH>./aibox.tomlPath to configuration file
--log-level <LEVEL>AIBOX_LOG_LEVELinfoLog verbosity
-y, --yesSkip 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
OptionDefaultDescription
[NAME]Current directoryProject/container name
--base <BASE>debianBase image
--profile <PROFILE>human-devUsage profile: human-dev or warning-mode headless-runner
--context-mode <MODE>processkitContext layer: processkit or harness-only
--harness <NAME>claudeAI harness, repeatable
--addon <NAME>Addon name, repeatable
--theme <THEME>gruvboxRuntime UI theme family
--processkit-version <TAG>latest prompt/defaultPin processkit
--include-prereleaseoffInclude 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
OptionDescription
--no-cacheForce a full image rebuild without using cached layers
--rebuildVisible alias for --no-cache
--config-onlyRegenerate files without building the image
--standardize-configRewrite aibox.toml through the current canonical grouped template after compatibility migrations. Recognized schema fields are preserved; unknown keys block the rewrite.
--fix-compliance-contractRewrite the processkit compliance block in AGENTS.md
--no-containerSkip 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:

FieldSourceMeaning
memory_current_bytes/sys/fs/cgroup/memory.currentCurrent cgroup memory usage in bytes
memory_max/sys/fs/cgroup/memory.maxCgroup memory limit, or unlimited when the kernel reports max
oom_kill_count/sys/fs/cgroup/memory.eventsCumulative oom_kill counter for the cgroup
total_process_countnumeric entries under /procTotal visible process count
processkit_mcp_python_process_count/proc/*/cmdlinePython 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.

CommandSchemaContents
describe addon-catalogaibox.addon-catalog.v0Built-in addon metadata, profile intent, automation usage class, exported surfaces, dependencies, and tool versions
describe workspace-manifestaibox.workspace-manifest.v0Sorted projection of aibox.toml: project, context mode/packages, processkit source when enabled, AI harnesses, addons, and MCP server keys
describe provider-backendsaibox.provider-backends.v0-previewSupported AI harness backends, selected status, addon availability, MCP config targets, and permission targets
describe image-provenance-policyaibox.image-provenance-policy.v0-previewGHCR 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.

RemovedUse
aibox syncaibox apply
aibox startaibox up
aibox stopaibox down
aibox statusaibox get runtime
aibox remove / aibox rmaibox 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 updateaibox self update
aibox completionsaibox self completion
aibox uninstallaibox self uninstall
aibox audio check/setupaibox 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.

FieldTypeRequiredDefaultDescription
project_nameStringNocontainer.nameHuman-readable project name
profileStringNo"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.

FieldTypeRequiredDefaultDescription
nameStringYesContainer name (used by compose and runtime inspect)
hostnameStringNo"aibox"Container hostname
userStringNo"aibox"Container user
post_create_commandStringNoCommand to run after container creation
keepaliveBooleanNofalsePeriodic DNS keepalive for development environments with idle network timeouts.
environmentMap (String → String)No{}Environment variables injected into the container. Suitable for non-secret project-wide values; use .aibox-local.toml for secrets.
extra_volumesArray of ExtraVolumeNo[]Additional bind mounts. Each entry has source, target, and optional read_only.
resource_thresholdsTableNosee belowWarning 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.

FieldTypeDefaultDescription
memory_mib_warnIntegerunsetWarn when cgroup memory.current exceeds this many MiB.
process_count_warnInteger400Warn when /proc contains more processes than this. Set to 0 to disable.
processkit_mcp_python_warnInteger50Warn when many Python processkit MCP server processes are live. Only rendered and used in processkit mode. Set to 0 to disable.
oom_kill_warnInteger0Warn 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:

FieldTypeRequiredDefaultDescription
sourceStringYesHost path (supports ~ expansion)
targetStringYesContainer path where the volume is mounted
read_onlyBooleanNofalseMount 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.

.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 of aibox.toml’s [container.environment]. Local values win on conflicts.
  • [[container.extra_volumes]] — appended after any volumes declared in aibox.toml.
  • [[mcp.servers]] — personal MCP servers appended to the team MCP servers from aibox.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.

FieldTypeRequiredDefaultDescription
modeStringNoprocesskitprocesskit installs the processkit-backed project context layer. harness-only skips processkit content and uses only generated container/harness configuration.
packagesArray of stringsNo["product"] in processkit mode, [] in harness-only modeprocesskit package selection. Required to be non-empty in processkit mode. Ignored in harness-only mode.
schema_versionString (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
KeyTypeRequiredDefaultDescription
engineStringNolualatexlualatex, pdflatex, xelatex, or tectonic. Tectonic supports build but not watch.
cache_dirRelative pathNo.latex-cacheRoot for project-local TEXMFVAR and TEXMFCONFIG. Parent traversal is rejected.
optionsArrayNo[]Additional single-line engine arguments.
documents[].nameStringYesUnique command-safe document name.
documents[].sourceRelative pathYesMain TeX source.
documents[].output_dirRelative pathNo.latex-cache/outputPDF, log, and auxiliary output directory.
preview.enabledBooleanNofalseGenerates one shared read-only Compose preview sidecar; host-side aibox up starts it and it serves every configured document.
preview.engineStringNoembedpdfViewer implementation; currently only embedpdf is supported.
preview.bindIP addressNo127.0.0.1Compose host-publish address. Loopback is accessible only from that host; use 0.0.0.0 only for other machines.
preview.portIntegerNo8765Host-published port for the document index and all viewers. It maps to sidecar port 8765.
preview.documentStringNofirst configured documentDefault for legacy /document.pdf and /events routes. All configured documents are served.
preview.allow_publicBooleanNofalseRequired 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.

FieldTypeRequiredDefaultDescription
harnesses[].harnessStringYes for each entrynoneHarness 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[].enableBooleanNofalseInclude this harness in generated runtime, agent, and MCP config. Alias: enabled.
harnesses[].installBooleanNofalseInstall the matching in-container CLI recipe when available. Cursor has no container CLI, so keep this false for cursor.
harnesses[].versionStringNoaddon’s defaultOptional CLI version pin.
model_providersArray of stringsNo[]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:

ProviderAPI key envBase URL env
anthropicANTHROPIC_API_KEYANTHROPIC_BASE_URL
openaiOPENAI_API_KEYOPENAI_BASE_URL
googleGEMINI_API_KEYGEMINI_BASE_URL
mistralMISTRAL_API_KEYMISTRAL_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.

FieldTypeRequiredDefaultDescription
sourceStringNohttps://github.com/projectious-work/processkit.gitGit URL of the content source.
versionStringNounsetSemver tag to consume. The sentinel unset skips fetching until a real tag is set.
src_pathStringNosrcSubdirectory inside the source repo containing the shippable payload. Auto-detected for flat release-asset tarballs.
branchStringNo(none)Optional branch override for testing pre-release work. Discouraged but supported.
release_asset_url_templateStringNo(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.

FieldTypeRequiredDefaultDescription
schema_versionString (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:

  1. Branch override (if branch is set) — git clone --branch <name>.
  2. Release-asset tarball — downloads a purpose-built .tar.gz from the URL built from release_asset_url_template (or the GitHub-style default {source}/releases/download/{version}/{name}-{version}.tar.gz). When a sibling <asset>.sha256 file is present, the tarball bytes are verified against it before extraction. The verified SHA256 is recorded in aibox.lock as release_asset_sha256 for bit-exact reproducibility.
  3. Host auto-tarball — falls back to GitHub / GitLab’s auto-generated archive/refs/tags/<version>.tar.gz when no release asset is available.
  4. 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:

  1. Built-in processkit servers — only in context.mode = "processkit", either the processkit gateway or separate per-skill servers, depending on [ai.mcp.gateway]
  2. aibox.toml [[ai.mcp.servers]] — team-shared servers committed to version control
  3. .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"
ModeBehavior
autoRegister a self-starting processkit gateway daemon when the installed processkit version ships it; otherwise fall back to separate per-skill servers
daemonUse one localhost processkit gateway daemon plus one stdio proxy per harness
stdioRegister processkit-gateway directly as a stdio MCP server
separateAlways 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:

FieldTypeRequiredDefaultDescription
nameStringYesUnique server name (used as the key in generated configs)
commandStringYesExecutable to run (e.g. npx, /usr/local/bin/my-server)
argsArray of stringsNo[]Arguments passed to command
envMap (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:

FieldTypeRequiredDefaultDescription
default_modeStringNo"ask"Default permission when no explicit pattern matches. Use "allow" only when every configured MCP server is trusted.
allow_patternsArray of stringsNo[]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_patternsArray of stringsNo[]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"

[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.).

FieldTypeRequiredDefaultDescription
canonicalStringNo"AGENTS.md"Filename of the canonical agent entry document. Almost no one should override this — the default matches the agents.md ecosystem convention.
provider_modeStringNo"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.

FieldTypeRequiredDefaultDescription
themeStringNo"gruvbox-dark"Color theme. Supports the tmux-powerkit popular theme roster and variants, plus projectious; see Themes.
modeStringNo"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.
promptStringNo"default"Starship preset: default, plain, arrow, minimal, nerd-font, pastel, powerline-pastel, bracketed. Legacy pastel-powerline is accepted as an alias.
layoutStringNo"dev"tmux layout: dev, focus, cowork, ai
tmux.status.modeStringNo"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.styleStringNo"rounded"PowerKit separator style: normal, rounded, slant, slantup, trapezoid, flame, pixel, honeycomb, none.
tmux.status.separators.edge-styleStringNo"rounded"PowerKit edge separator style for status boundaries. Uses the same values as style.
tmux.status.separators.elements-spacingStringNo"both"PowerKit spacing mode: false, true, both, windows, plugins.
tmux.status.forge.github-hostsArray of stringsNo["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.

FieldTypeRequiredDefaultDescription
enabledBooleanNofalseEnable PulseAudio environment setup
backendStringNo"pulseaudio"Audio bridge backend. Only pulseaudio is currently supported.
installBooleanNotrueSelect the internal audio-voice recipe when audio is enabled
pulse_serverStringNo"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.

FieldTypeRequiredDefaultDescription
credential_helperStringNo"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

FieldTypeRequiredDefaultDescription
preserve_disabled_harness_stateBooleanNofalseRecords 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_stateBooleanNofalseExplicitly removes retained state for disabled AI harnesses on the next aibox apply.

Environment Variable Overrides

Some settings can be overridden via environment variables:

VariableOverridesDescription
AIBOX_HOST_ROOT.aibox-home/ pathHost directory for persistent config (default: .aibox-home/)
AIBOX_WORKSPACE_DIRWorkspace mount sourceHost directory mounted as /workspace
AIBOX_LOG_LEVEL--log-levelLog 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

SectionMerge 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.

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.

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

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&#123;char&#125;` | Jump to next &#123;char&#125; 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 `&#123;N&#125;j`/`&#123;N&#125;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 versionMin. processkitNotes
0.29.0v0.28.5adds 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.19v0.28.5preserves 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.18v0.28.5restores 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.17v0.28.4repairs 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.16v0.28.4installs 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.14v0.28.4ensures pk-reconcile and pk-repo-reconcile install their project-reconciliation and repo-management skill dependencies
0.28.15v0.28.4refreshes bundled maintenance tools, locks cargo-audit installation for Rust compatibility, and publishes the Hugo/Docsy documentation site
0.28.13v0.28.4adds open GitHub Discussion counts to the tmux Forge status segment and restores the complete generated Codex command projection set
0.28.12v0.28.4integrates processkit v0.28.4 and makes companion E2E validation work from linked release worktrees
0.28.11v0.28.3adds the cloudflare addon, which installs cloudflared from Cloudflare’s signed package repository rather than Debian’s archive
0.28.10v0.28.3reconciles standard processkit skills, recommends tooling-linked skills interactively, upgrades prerelease processkit surfaces, and serializes release Tier 2 E2E validation
0.28.6v0.28.3fixes 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.5v0.28.1fixes 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.4v0.28.1integrates processkit v0.28.1 and refreshes the maintained v0.x processkit compatibility baseline
0.28.3v0.27.6integrates 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.2v0.27.5integrates 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.1v0.27.4restores 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.0v0.27.4adds 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.8v0.27.2integrates 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.7v0.27.1fixes the TeX Live historic installer mirror, resolves pk-doctor false positives, preserves disabled harness state, and accepts context mode in schema validation
0.27.6v0.27.1refreshes tool and harness pins, updates generated runtime/docs references, and adds the GitHub CLI credential-helper integration for HTTPS Git operations
0.27.5v0.27.1refreshes 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.4v0.27.1refreshes 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.3v0.27.1integrates 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.2v0.27.0fixes 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.1v0.27.0refreshes 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.0v0.27.0integrates 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.8v0.26.16integrates 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.7v0.26.15integrates 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.6v0.26.14integrates processkit v0.26.14; updates processkit metadata to the new release and preserves tmux/Vim/cheatsheet and clipboard behavior consistency
0.26.5v0.26.13re-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.4v0.26.10integrates 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.3v0.26.9fixes 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.2v0.26.9fixes 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.1v0.26.9verifies 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.0v0.26.7refreshes 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.14v0.26.5integrates 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.13v0.26.2fixes 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.12v0.26.2fixes 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.11v0.26.2fixes 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.10v0.26.2integrates 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.9v0.26.1integrates 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.8v0.26.0improves 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.7v0.25.8introduces 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.6v0.25.8expands tmux/PowerKit theme coverage with light/dark partner handling, generated theme comments, Docusaurus theme documentation, and runtime border/status color improvements
0.25.5v0.25.8refreshes 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.4v0.25.8repairs 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.3v0.25.8fixes 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.2v0.25.8adds 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.0v0.25.8replaces 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.1v0.25.8fixes 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.0v0.25.8adds 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.21v0.25.8repairs 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.20v0.25.8makes 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.19v0.25.8hardens 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.18v0.25.8updates 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.17v0.25.8installs 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.16v0.25.8moves 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.15v0.25.8fixes 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.14v0.25.8canonical 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.13v0.25.8fixes 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.12v0.25.8processkit 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.11v0.25.7grouped 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.10v0.25.7processkit 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.9v0.25.6restores 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.8v0.25.5native 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.7v0.25.5host-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.6v0.25.5processkit 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.5v0.25.4generated Dockerfile lazygit disablement cleanup no longer aborts when lazygit is absent as an apt package, while still removing inherited lazygit binaries
0.23.4v0.25.4processkit 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.3v0.25.3processkit v0.25.3 model-spec/model-profile migrations and Codex seccomp fallback for bubblewrap
0.23.2v0.25.1processkit v0.25.1 model-recommender lifecycle metadata, task suitability classes, task-class-aware routing, and refreshed model roster
0.23.1v0.25.0stale runtime cleanup for old Compose project names, lazygit disablement fixes, and procps runtime diagnostics
0.23.0v0.25.0processkit v0.25.0 gateway integration, daemon-proxy mode, runtime pressure diagnostics, init reaping, optional git UI tools, and profile-aware environment metadata
0.22.0v0.24.0processkit v0.24.0: context archiving, richer model routing metadata, semantic task-router scoring, archive-aware index metadata
0.21.2v0.23.1processkit v0.23.1 release-audit cleanup and skill metadata fixes
0.21.1v0.23.0processkit v0.23.0 model governance and release-audit integration
0.21.0v0.22.0multi-harness slash-command scaffolding and content-diff safety fixes
0.20.0v0.22.0processkit install integrity, preauth merge, and no-container scaffold mode
0.19.0v0.21.0MCP permission configuration and processkit v0.21 content integration
0.17.16v0.13.0BREAKING: rename providers = ["codex"]["openai"]; fix zellij --layout flag; fix Rust x86_64 cross-compile target
0.17.15v0.13.0MCP config model, zjstatus hints, Zellij Ctrl+q, processkit v0.13.0
0.17.5v0.8.0processkit v0.8.0 GrandLily src/ restructure
0.17.4v0.6.0content migration documents (pending/in-progress/applied)
0.17.3v0.6.0Claude Code slash-command adapters
0.17.2v0.6.0core skill enforcement, processkit v0.6.0 compat
0.17.0v0.5.0aibox.lock sectioned format
0.16.1v0.4.0sync auto-install added
0.16.0v0.4.0initial 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:

  1. Edit aibox.toml:

    [processkit]
    version = "v0.25.5"
    
  2. Run aibox apply on the host — the 3-way diff will show changed content and generate processkit content migration documents in context/migrations/pending/.

  3. 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:

SurfaceProvenance controlRelease validation
Rust CLIcli/Cargo.lock pins the complete dependency graphcargo test, Clippy with warnings denied, and cargo audit
Documentationdocs-site/package-lock.json and the Docsy submodule pin dependenciesclean npm ci, production Hugo build, and npm audit
processkitsource, version, and release-asset SHA-256 are recorded in aibox.lock and live provenanceinstaller hash verification, three-way content comparison, and pk-doctor integrity checks
Base imagesrelease-specific image tags, OCI source/profile labels, and generated version markerscross-platform build, GHCR publication verification, and downstream runtime smoke
Addon downloadspinned versions plus SHA-256, signed checksum, or upstream sidecar verification where availablerelease-state inventory and real container lifecycle tests
Release binarieslocally cross-compiled artifacts attached to a signed release tagversion 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 doctor and 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.py can 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 project scope — 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:

  1. Source code is auditable: the skill’s mcp/server.py (and any imported modules) are readable and understandable.
  2. No unexpected outbound network calls: the skill should not exfiltrate data to external endpoints.
  3. No credential access beyond stated purpose: check for reads of ~/.ssh/, env vars (ANTHROPIC_API_KEY, etc.), or ~/.claude/~/.codex.
  4. Tool list is minimal: the allowed_tools set registered by the skill should match only the capabilities the skill claims to need.
  5. Dependency supply chain: if the skill uses uv or pip to install Python packages, review pyproject.toml / requirements.txt for unexpected dependencies.
  6. Immutable or pinned source: prefer skills pinned to a specific git SHA or release tag over floating main/latest references.

Opting out of a skill

To remove a skill and deregister its MCP server:

  1. Remove the skill from context/skills/ or update [processkit] config.
  2. Run aibox apply — this rewrites the harness MCP configuration files and removes the skill’s allowed_tools entries.
  3. Recreate the container (docker compose up -d --force-recreate) so the new MCP configuration takes effect.

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 apply to emit seccomp=unconfined in docker-compose.yml.
  • Suppresses the aibox doctor warning 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=true or CAP_SYS_ADMIN escalations.

seccomp=unconfined does not grant root or additional Linux capabilities — it only lifts the seccomp syscall filter, allowing bubblewrap to create user namespaces.