ov-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:doctor (Hardware Detection) for the probe side, /ov-foundation:nvidia (DRINODE Auto-Injection) for the NVIDIA consumer, and /ov-foundation: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-advanced: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: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-advanced:cdp -- Chrome DevTools Protocol automation/ov-advanced:wl (sway subgroup) -- Sway compositor control/ov-core:doctor -- Host hardware probe that feeds appendAutoDetectedEnv() (DRINODE, HSA_OVERRIDE_GFX_VERSION)/ov-build:settings -- Engine and bind address settings/ov-build: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-foundation:nvidia, /ov-foundation: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.
tools
OpenCharly CLI (charly) binary installed into container/VM images for in-container use. Use when working with charly binary deployment inside containers, native D-Bus support, or the full charly toolchain (charly binary + virtualization + gocryptfs + socat).
development
Operator CachyOS workstation profile — a kind:local template + target:local deploy that installs the full dev stack (30 candies) onto a CachyOS host via ShellExecutor. Lives in the overthinkos/cachyos submodule. MUST be invoked before editing or applying the charly-cachyos workstation profile.
tools
Fedora box with the full charly toolchain using shared candies. Rootless-first — runs as uid=1000 with passwordless sudo (no root, no cap_add: ALL). Same candy list as charly-arch. Includes NVIDIA GPU runtime. MUST be invoked before building, deploying, configuring, or troubleshooting the charly-fedora box.
tools
Arch Linux box with the full charly toolchain. Rootless-first — runs as uid=1000 with passwordless sudo (no root, no cap_add: ALL). Composes /charly-coder:charly-mcp so the box is reachable as an MCP gateway on port 18765. NVIDIA GPU runtime composed in. MUST be invoked before building, deploying, configuring, or troubleshooting the charly-arch box.