core/skills/shell/SKILL.md
MUST be invoked before any work involving: ov shell command, interactive shells, command execution in containers, workspace mounts, TTY allocation, or port relay.
npx skillsauth add overthinkos/overthink-plugins shellInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
ov shell runs an interactive shell or executes commands inside containers. Supports workspace mounting, device auto-detection, environment injection, and TTY allocation for automation tools.
| Action | Command | Description |
|--------|---------|-------------|
| Interactive shell | ov shell <image> | Bash shell in container |
| Bind workspace | ov shell <image> --bind workspace=~/project | Mount host dir as workspace volume |
| Volume config | ov shell <image> -v name:type[:path] | Configure volume backing (volume|bind|encrypted) |
| Run command | ov shell <image> -c "cmd" | Execute command and exit |
| Force TTY | ov shell <image> --tty -c "cmd" | PTY allocation for automation |
| Specific version | ov shell <image> --tag v1.0.0 | Use specific image tag |
| No devices | ov shell <image> --no-autodetect | Disable device auto-detection |
| Set env var | ov shell <image> -e KEY=VALUE | Inject environment variable |
| Load env file | ov shell <image> --env-file .env | Load env from file |
| Named instance | ov shell <image> -i runner-1 | Use named instance |
| Force build | ov shell <image> --build | Build locally before running |
Note: ov shell does not accept remote refs (@github.com/...). Remote
refs are handled exclusively by ov image pull (build-mode). Pull first,
then ov shell <image-name> works via labels. See /ov-build:pull.
ExtractMetadata (never image.yml)deploy.yml overlay (volumes, env, sidecars, tunnel)<engine> exec into it<engine> run with full configurationIf the image isn't in local storage, ExtractMetadata/EnsureImage return
ErrImageNotLocal and the CLI surfaces:
Error: image "X" is not available locally.
Run 'ov image pull X' to fetch it first
See /ov-build:pull for the full sentinel pattern.
ov shell <image> --bind workspace=~/project # Bind ~/project as workspace volume
ov shell <image> --bind workspace=. # Bind PWD as workspace volume
ov shell <image> # No host mount (named volume)
The --bind flag overrides volume backing for the session. For finer control, use -v name:type[:path] where type is volume, bind, or encrypted. The container working directory is ~/workspace (resolved from the workspace volume). If a .env file exists in the bound directory, it is auto-loaded.
Forces TTY allocation even when stdout is not a terminal. Uses script(1) from util-linux to provide a real PTY.
# Without --tty: "not a tty" errors from interactive commands
ov shell my-app -c "interactive-cli auth login" # fails in CI/automation
# With --tty: script(1) wraps the command in a PTY
ov shell my-app --tty -c "interactive-cli auth login" # works everywhere
Essential for automation tools (Claude Code, CI runners) where stdout is a pipe, not a terminal. Many interactive CLI commands (OAuth flows, prompts) require a TTY.
Works for both new containers (<engine> run) and exec into running containers (<engine> exec).
When ov shell detects the container is already running (via <engine> inspect), it uses <engine> exec instead of <engine> run. The same flags work:
ov start my-app # Start background service
ov shell my-app -c "cat /etc/hostname" # Exec into running container
ov shell my-app # Interactive shell in running container
The port_relay field in layer.yml solves the problem of services that bind only to 127.0.0.1 inside the container (e.g., Chrome 146+ DevTools). Container port mappings only forward to interfaces visible from outside, so a loopback-only service is unreachable from the host.
# In layer.yml:
port_relay:
- 9222
How it works:
eth0:<port> and forwards to 127.0.0.1:<port>init.<name>.relay_template) with priority 1 (starts before other services)This makes loopback-only services accessible through normal podman/docker port mappings and tailscale serve.
Source: ov/generate.go (relay service generation), ov/layers.go (PortRelayYAML).
By default, ov shell auto-detects available host devices and passes them through. Use --no-autodetect to disable.
Auto-detected devices:
nvidia-smi) -- --gpus all (Docker) or --device nvidia.com/gpu=all (Podman)amdgpu driver) -- --device /dev/kfd + --group-add keep-groups + auto-detected HSA_OVERRIDE_GFX_VERSION from KFD topology/dev/dri/renderD* -- GPU render nodes/dev/kfd -- AMD Kernel Fusion Driver (ROCm compute)/dev/kvm -- KVM virtualization/dev/vhost-net, /dev/vhost-vsock -- virtio networking/dev/fuse -- FUSE filesystem/dev/net/tun -- TUN/TAP networking/dev/hwrng -- hardware RNGWhen an AMD GPU is detected, keep-groups is auto-added to preserve host supplementary groups (video, render) inside the container, and HSA_OVERRIDE_GFX_VERSION is auto-set from the GPU's KFD topology (e.g., 10.3.0 for RDNA2). Additionally, the first detected /dev/dri/renderD* device is auto-injected as DRINODE and DRI_NODE env vars (used by selkies for VAAPI encoding). All auto-detected env vars can be overridden via -e.
Shared code path: ov shell calls appendAutoDetectedEnv() in ov/devices.go — the same function used by ov config and ov start. That means the three commands produce an identical env set on every run, eliminating drift that used to exist when DRINODE injection was scattered across 10 different call sites before commit 8f6f322. See /ov-core:ov-doctor (Hardware Detection) for the probe side, /ov-distros:nvidia (DRINODE Auto-Injection) for the NVIDIA consumer, and /ov-distros:rocm (Runtime Environment) for the AMD consumer.
Source: ov/devices.go (DetectHostDevices, DetectGPU, DetectAMDGPU, appendAutoDetectedEnv).
Runtime environment variables are injected from multiple sources. Resolution priority (last wins for duplicate keys):
env: (image.yml / deploy.yml) -- lowest priorityenv_file: (image.yml / deploy.yml).env file -- auto-loaded from -w directory--env-file flag-e flags -- highest priorityov shell <image> -e DB_HOST=localhost -e DB_PORT=5432
ov shell <image> --env-file production.env
Kong sep:"none" on -e means commas in values are safe (e.g., NO_PROXY=localhost,127.0.0.1).
.env file format (Docker-compatible): KEY=VALUE, KEY="VALUE", KEY='VALUE', KEY (inherits from host), # comments, blank lines ignored.
Source: ov/envfile.go (ParseEnvFile, ResolveEnvVars, LoadWorkspaceEnv).
ov shell does not accept @github.com/... remote refs. Pre-refactor
versions did; post-refactor, deploy-mode commands read only from local OCI
labels, so remote refs are rejected with a redirect:
Error: remote refs are not accepted here;
run 'ov image pull @github.com/org/repo/my-app' first,
then 'ov shell my-app'
To run a shell on a remote image, pull it first (via ov image pull) and
then invoke ov shell <short-name>. See /ov-build:pull for the full remote-ref
workflow.
When engine.build differs from engine.run, images are automatically transferred between engines on demand via <src> save | <dst> load.
Source: ov/transfer.go.
All containers are connected to a shared ov network by default, enabling inter-container DNS resolution by container name. Override with network: host in image.yml.
Source: ov/network.go.
ov cmd vs ov shell -cov cmd <image> "command" is a dedicated single-command tool for running containers only. Key differences from ov shell -c:
| | ov cmd | ov shell -c |
|---|---------|--------------|
| Container state | Running only | Running or starts new |
| Notification | Yes (--[no-]notify) | No |
| Process model | exec.Command (returns) | syscall.Exec (replaces) |
| Workspace mount | No | Yes (-w) |
| Device auto-detect | No | Yes |
| Use case | Quick commands + notification | Full container setup + command |
Use ov cmd for quick operations on running services. Use ov shell -c when you need workspace mounts, device passthrough, or need to start a new container.
/ov-build:pull -- Required before ov shell can work on a fresh host. Fetches the image into local storage so ExtractMetadata can read its OCI labels. Handles remote refs (@github.com/...) that ov shell itself rejects./ov-core:cmd -- Single command execution with D-Bus notification (running containers only)/ov-automation:tmux -- Persistent tmux sessions (survives disconnects, needed for TTY-dependent TUI programs)/ov-core:service -- Starting background services before exec/ov-core:start -- Same appendAutoDetectedEnv() injection at service-start time/ov-core:ov-config -- Deployment setup + same appendAutoDetectedEnv() at deploy time; --no-autodetect flag disables it/ov-core:deploy -- deploy.yml overlay applied to labels before shell spawns/ov-eval:cdp -- Chrome DevTools Protocol automation/ov-eval:wl (sway subgroup) -- Sway compositor control/ov-core:ov-doctor -- Host hardware probe that feeds appendAutoDetectedEnv() (DRINODE, HSA_OVERRIDE_GFX_VERSION)/ov-build:settings -- Engine and bind address settings/ov-image:image -- Image definitions (ports, volumes, env) in image.yml; authoritative source before a pull/ov-build:build -- Build the image you intend to shell into/ov-distros:nvidia, /ov-distros:rocm -- GPU layers consuming the auto-injected envMUST be invoked when the task involves ov shell command, interactive shells, command execution in containers, workspace mounts, TTY allocation, or port relay. Invoke this skill BEFORE reading source code or launching Explore agents.
Workflow position: Any time. Interactive access to running or stopped containers.
development
Claude Code multi-agent support in Overthink — sub-agents, dynamic workflows, and agent teams, and how each drives the existing `ov eval` disposable beds to test and verify. MUST be invoked before authoring or invoking an ov sub-agent / dynamic workflow / agent team, wiring agent-lifecycle hooks, or asking "which primitive should drive the R10 beds?".
tools
Mounts a virtiofs share tagged `workspace` at /workspace inside a VM guest via a systemd .mount unit. Use when a kind:vm entity shares a host directory into the guest and you need it auto-mounted (and re-mounted at every boot).
development
MUST be invoked before any work involving: the `kind: android` schema kind, a `target: android` deploy, the `apk:` layer package format (installing Android apps declaratively), AndroidDeployTarget, an in-pod emulator OR a remote/physical adb-endpoint device, or nested `pod → android` deployment. The first-class Android device + app surface that sits above `ov eval adb`/`appium`.
tools
Use when committing, branching, pushing, merging, tagging, creating PRs, or approving/merging PRs with gh — the feat/-branch, R10-gated, never-force-push landing workflow across the main repo + the plugins submodule + image/<distro> submodules. Covers sync-to-upstream, branch/worktree pruning, the fork+PR path for contributors without write access, and cross-repo @github landing order.