Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .deva.example
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,10 @@ EPHEMERAL=false
# Hybrid Agent Setup:
#
# Hybrid is the DEFAULT. deva walks every populated subdir under
# ~/.config/deva/ (claude, codex, gemini, grok, kimi, opencode, pi) and mounts each agent's
# ~/.config/deva/ (claude, codex, gemini, grok, kimi, opencode, pi, dsh) and mounts each agent's
# canonical entries into the container. Populated = you either
# hand-created the subdir or autolink symlinked it from legacy
# ~/.claude, ~/.codex, ~/.gemini, ~/.grok, ~/.kimi-code, ~/.pi, or the
# ~/.claude, ~/.codex, ~/.gemini, ~/.grok, ~/.kimi-code, ~/.pi, ~/.dsh, or the
# opencode XDG dirs (~/.config/opencode + ~/.local/share/opencode +
# ~/.local/state/opencode) on first run.
#
Expand Down
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ jobs:
--build-arg KIMI_CODE_VERSION="${{ steps.pins.outputs.kimi_code_version }}" \
--build-arg OPENCODE_VERSION="${{ steps.pins.outputs.opencode_version }}" \
--build-arg PI_CODING_AGENT_VERSION="${{ steps.pins.outputs.pi_coding_agent_version }}" \
--build-arg DSH_VERSION="${{ steps.pins.outputs.dsh_version }}" \
--build-arg CCX_VERSION="${{ steps.pins.outputs.ccx_version }}" \
--build-arg COPILOT_API_VERSION="${{ steps.pins.outputs.copilot_api_version }}" \
.
Expand All @@ -111,6 +112,7 @@ jobs:
KIMI_CODE_VERSION="${{ steps.pins.outputs.kimi_code_version }}" \
OPENCODE_VERSION="${{ steps.pins.outputs.opencode_version }}" \
PI_CODING_AGENT_VERSION="${{ steps.pins.outputs.pi_coding_agent_version }}" \
DSH_VERSION="${{ steps.pins.outputs.dsh_version }}" \
CCX_VERSION="${{ steps.pins.outputs.ccx_version }}" \
COPILOT_API_VERSION="${{ steps.pins.outputs.copilot_api_version }}" \
PLAYWRIGHT_VERSION="${{ steps.pins.outputs.playwright_version }}" \
Expand Down Expand Up @@ -139,6 +141,7 @@ jobs:
deva.sh kimi -Q -- --version
deva.sh opencode -Q -- --version
deva.sh pi -Q -- --version
deva.sh dsh -Q -- --version

- name: Smoke Claude --chrome mount assembly
shell: bash
Expand Down Expand Up @@ -208,6 +211,14 @@ jobs:
DEVA_DOCKER_TAG=ci \
./scripts/test-pi-auth.sh

- name: Smoke dsh auth wiring
shell: bash
run: |
set -euo pipefail
DEVA_DOCKER_IMAGE=deva-smoke \
DEVA_DOCKER_TAG=ci \
./scripts/test-dsh-auth.sh

- name: Smoke version targets
shell: bash
run: |
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/nightly-images.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ jobs:
kimi_code_version: ${{ steps.versions.outputs.kimi_code_version }}
opencode_version: ${{ steps.versions.outputs.opencode_version }}
pi_coding_agent_version: ${{ steps.versions.outputs.pi_coding_agent_version }}
dsh_version: ${{ steps.versions.outputs.dsh_version }}
ccx_version: ${{ steps.versions.outputs.ccx_version }}
copilot_api_version: ${{ steps.versions.outputs.copilot_api_version }}
steps:
Expand Down Expand Up @@ -88,6 +89,7 @@ jobs:
- Kimi Code: \`${{ steps.versions.outputs.kimi_code_version }}\`
- opencode: \`${{ steps.versions.outputs.opencode_version }}\`
- pi: \`${{ steps.versions.outputs.pi_coding_agent_version }}\`
- dsh: \`${{ steps.versions.outputs.dsh_version }}\`
- ccx: \`${{ steps.versions.outputs.ccx_version }}\`
- Copilot API: \`${{ steps.versions.outputs.copilot_api_version }}\`
- Stamp: \`${{ steps.versions.outputs.stamp }}\`
Expand Down Expand Up @@ -152,6 +154,7 @@ jobs:
KIMI_CODE_VERSION=${{ needs.resolve-versions.outputs.kimi_code_version }}
OPENCODE_VERSION=${{ needs.resolve-versions.outputs.opencode_version }}
PI_CODING_AGENT_VERSION=${{ needs.resolve-versions.outputs.pi_coding_agent_version }}
DSH_VERSION=${{ needs.resolve-versions.outputs.dsh_version }}
CCX_VERSION=${{ needs.resolve-versions.outputs.ccx_version }}
COPILOT_API_VERSION=${{ needs.resolve-versions.outputs.copilot_api_version }}

Expand Down Expand Up @@ -209,6 +212,7 @@ jobs:
KIMI_CODE_VERSION=${{ needs.resolve-versions.outputs.kimi_code_version }}
OPENCODE_VERSION=${{ needs.resolve-versions.outputs.opencode_version }}
PI_CODING_AGENT_VERSION=${{ needs.resolve-versions.outputs.pi_coding_agent_version }}
DSH_VERSION=${{ needs.resolve-versions.outputs.dsh_version }}
CCX_VERSION=${{ needs.resolve-versions.outputs.ccx_version }}
PLAYWRIGHT_VERSION=${{ needs.load-version-pins.outputs.playwright_version }}
RUST_TOOLCHAINS=${{ needs.load-version-pins.outputs.rust_toolchains }}
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
kimi_code_version: ${{ steps.pins.outputs.kimi_code_version }}
opencode_version: ${{ steps.pins.outputs.opencode_version }}
pi_coding_agent_version: ${{ steps.pins.outputs.pi_coding_agent_version }}
dsh_version: ${{ steps.pins.outputs.dsh_version }}
ccx_version: ${{ steps.pins.outputs.ccx_version }}
copilot_api_version: ${{ steps.pins.outputs.copilot_api_version }}
playwright_version: ${{ steps.pins.outputs.playwright_version }}
Expand Down Expand Up @@ -93,6 +94,7 @@ jobs:
- Kimi Code: \`${{ steps.pins.outputs.kimi_code_version }}\`
- opencode: \`${{ steps.pins.outputs.opencode_version }}\`
- pi: \`${{ steps.pins.outputs.pi_coding_agent_version }}\`
- dsh: \`${{ steps.pins.outputs.dsh_version }}\`
- ccx: \`${{ steps.pins.outputs.ccx_version }}\`
- Copilot API: \`${{ steps.pins.outputs.copilot_api_version }}\`
- Playwright: \`${{ steps.pins.outputs.playwright_version }}\`
Expand Down Expand Up @@ -160,6 +162,7 @@ jobs:
KIMI_CODE_VERSION=${{ needs.load-version-pins.outputs.kimi_code_version }}
OPENCODE_VERSION=${{ needs.load-version-pins.outputs.opencode_version }}
PI_CODING_AGENT_VERSION=${{ needs.load-version-pins.outputs.pi_coding_agent_version }}
DSH_VERSION=${{ needs.load-version-pins.outputs.dsh_version }}
CCX_VERSION=${{ needs.load-version-pins.outputs.ccx_version }}
COPILOT_API_VERSION=${{ needs.load-version-pins.outputs.copilot_api_version }}

Expand Down Expand Up @@ -219,6 +222,7 @@ jobs:
KIMI_CODE_VERSION=${{ needs.load-version-pins.outputs.kimi_code_version }}
OPENCODE_VERSION=${{ needs.load-version-pins.outputs.opencode_version }}
PI_CODING_AGENT_VERSION=${{ needs.load-version-pins.outputs.pi_coding_agent_version }}
DSH_VERSION=${{ needs.load-version-pins.outputs.dsh_version }}
CCX_VERSION=${{ needs.load-version-pins.outputs.ccx_version }}
PLAYWRIGHT_VERSION=${{ needs.load-version-pins.outputs.playwright_version }}
RUST_TOOLCHAINS=${{ needs.load-version-pins.outputs.rust_toolchains }}
Expand Down
20 changes: 20 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
scripts/test-help-surface.sh pins the routing (24 asserts)

### Added
- dsh (deepseek-ai/deepseek-harness, DeepSeek's official agent harness,
launched 2026-08-13) as the 8th agent: `deva.sh dsh` (#556). One
dot-dir — everything persists under `~/.dsh` (`$DSH_HOME`, pinned by
deva; the issue's `~/n` worry was a docs misread): .credentials.yaml,
settings.yaml, profiles/, skills/. Default `credentials` mounts
`~/.dsh` writable; `--auth-with api-key` passes DEEPSEEK_API_KEY as
env and mounts nothing — dsh reads env BEFORE .credentials.yaml
(reverse of pi), so the injected key always decides billing and no
blank overlay is needed; for the same reason a host key is scrubbed
from credentials-mode runs. Unattended posture via
DSH_PERMISSION_MODE=danger-full-access (env is the only switch; dsh
scrubs DSH_* from project env, so only deva's injection counts).
No updater to neutralize (plain npm distribution, no phone-home).
Skills interop free of charge: dsh reads ~/.agents/skills +
<project>/.agents/skills, the dirs deva already wires for claude.
Plugin/marketplace surface deliberately not wired (manifest format
in flux pre-launch). Pinned hard: @deepseek-ai/dsh@0.1.0-rc.6
(DSH_VERSION) — developer preview, every bump is a potential break;
nightly-images tracks drift. scripts/test-dsh-auth.sh (13 asserts).
`--trace` rejected until cctrace ships a dsh profile
- pi (earendil-works/pi, the minimal multi-provider agent harness by
badlogic) as the 7th agent: `deva.sh pi` (#552). One dot-dir —
everything persists under `~/.pi/agent/` (auth.json, sessions,
Expand Down
5 changes: 5 additions & 0 deletions DEV-LOGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
- Minimal markdown markers, no unnecessary formatting, minimal emojis.
- Reference issue numbers in the format `#<issue-number>` for easy linking.

# [2026-08-13] Dev Log: dsh as the 8th agent #556
- Why: DeepSeek shipped its official harness (deepseek-ai/deepseek-harness) on launch day; developer preview with promised breaking changes is exactly what a container posture is for.
- What: agents/dsh.sh (default `credentials` mounts ~/.dsh rw; api-key passes DEEPSEEK_API_KEY, mounts nothing — dsh resolves env BEFORE .credentials.yaml, reverse of pi, so no blank overlay and host-key scrub matters in credentials mode), deva.sh registration (auth tag, dsh_version label, mounts, autolink ~/.dsh, status, env scrub), DSH_PERMISSION_MODE=danger-full-access + DSH_HOME pinned at launch, image pin DSH_VERSION=0.1.0-rc.6 through versions.env/Makefile/scripts/CI, scripts/test-dsh-auth.sh (13 asserts). Traps dodged: DSH_HOME default is ~/.dsh not `~/n` (issue text was a docs misread); DSH_* is scrubbed from project-discovered env by dsh itself, so the permission mode must ride the invoking env — which deva's -e injection is; no updater exists, nothing to neutralize.
- Result: 8 agents. test-dsh-auth 13/13, existing auth suites green. Skills interop (~/.agents/skills) works with the wiring claude already has. --trace deferred (no cctrace dsh profile); plugins surface held back on purpose.

# [2026-08-12] Dev Log: layered help #554
- Why: the help surface was one 130-line wall; `ps --help` printed the same wall; cloak VNC passwords sat next to -v. First shot of the framework-vnext wrapper-UX track (W1).
- What: usage() split into a 43-line summary + usage_full() (`help all`) + usage_command() per management command. Routing rides the existing PRE_ARGS scan: help tokens set HELP_REQUESTED instead of exiting, so the same pass that sees --help already knows MANAGEMENT_MODE — `help ps`, `--help ps`, `ps --help` all converge; `all` only counts after a help token so it stays a free word otherwise. tmux untouched (dispatches before the scan); launch help stays global; sentinel passthrough proven untouched by dry-run assert.
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ ARG GROK_CLI_VERSION=0.2.93
ARG KIMI_CODE_VERSION=0.28.0
ARG OPENCODE_VERSION=1.18.14
ARG PI_CODING_AGENT_VERSION=0.84.1
ARG DSH_VERSION=0.1.0-rc.6

# Record key tool versions as labels for quick inspection
LABEL org.opencontainers.image.claude_code_version=${CLAUDE_CODE_VERSION}
Expand All @@ -224,6 +225,7 @@ LABEL org.opencontainers.image.grok_cli_version=${GROK_CLI_VERSION}
LABEL org.opencontainers.image.kimi_code_version=${KIMI_CODE_VERSION}
LABEL org.opencontainers.image.opencode_version=${OPENCODE_VERSION}
LABEL org.opencontainers.image.pi_coding_agent_version=${PI_CODING_AGENT_VERSION}
LABEL org.opencontainers.image.dsh_version=${DSH_VERSION}

ARG CCX_VERSION=v0.7.0

Expand Down
2 changes: 2 additions & 0 deletions Dockerfile.rust
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ ARG GROK_CLI_VERSION=0.2.93
ARG KIMI_CODE_VERSION=0.28.0
ARG OPENCODE_VERSION=1.18.14
ARG PI_CODING_AGENT_VERSION=0.84.1
ARG DSH_VERSION=0.1.0-rc.6
ARG CCX_VERSION=v0.7.0
ARG PLAYWRIGHT_VERSION=1.60.0
ARG RUST_TOOLCHAINS="stable"
Expand All @@ -28,6 +29,7 @@ LABEL org.opencontainers.image.grok_cli_version=${GROK_CLI_VERSION}
LABEL org.opencontainers.image.kimi_code_version=${KIMI_CODE_VERSION}
LABEL org.opencontainers.image.opencode_version=${OPENCODE_VERSION}
LABEL org.opencontainers.image.pi_coding_agent_version=${PI_CODING_AGENT_VERSION}
LABEL org.opencontainers.image.dsh_version=${DSH_VERSION}
LABEL org.opencontainers.image.ccx_version=${CCX_VERSION}
LABEL org.opencontainers.image.playwright_version=${PLAYWRIGHT_VERSION}

Expand Down
17 changes: 14 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ GROK_CLI_VERSION ?= 0.2.93
KIMI_CODE_VERSION ?= 0.28.0
OPENCODE_VERSION ?= 1.18.14
PI_CODING_AGENT_VERSION ?= 0.84.1
DSH_VERSION ?= 0.1.0-rc.6
CCX_VERSION ?= v0.1.4
COPILOT_API_VERSION ?= 0ea08febdd7e3e055b03dd298bf57e669500b5c1
PLAYWRIGHT_VERSION ?= 1.60.0
Expand Down Expand Up @@ -94,6 +95,7 @@ AGENT_BUILD_ARGS := \
--build-arg KIMI_CODE_VERSION=$(KIMI_CODE_VERSION) \
--build-arg OPENCODE_VERSION=$(OPENCODE_VERSION) \
--build-arg PI_CODING_AGENT_VERSION=$(PI_CODING_AGENT_VERSION) \
--build-arg DSH_VERSION=$(DSH_VERSION) \
--build-arg CCX_VERSION=$(CCX_VERSION)

MAIN_BUILD_ARGS := $(TOOLCHAIN_BUILD_ARGS) $(AGENT_BUILD_ARGS) \
Expand Down Expand Up @@ -123,6 +125,7 @@ VERSION_QUERY_OVERRIDES := \
$(if $(filter command line environment environment\ override override,$(origin KIMI_CODE_VERSION)),KIMI_CODE_VERSION=$(KIMI_CODE_VERSION)) \
$(if $(filter command line environment environment\ override override,$(origin OPENCODE_VERSION)),OPENCODE_VERSION=$(OPENCODE_VERSION)) \
$(if $(filter command line environment environment\ override override,$(origin PI_CODING_AGENT_VERSION)),PI_CODING_AGENT_VERSION=$(PI_CODING_AGENT_VERSION)) \
$(if $(filter command line environment environment\ override override,$(origin DSH_VERSION)),DSH_VERSION=$(DSH_VERSION)) \
$(if $(filter command line environment environment\ override override,$(origin CCX_VERSION)),CCX_VERSION=$(CCX_VERSION)) \
$(if $(filter command line environment environment\ override override,$(origin COPILOT_API_VERSION)),COPILOT_API_VERSION=$(COPILOT_API_VERSION)) \
$(if $(filter command line environment environment\ override override,$(origin PLAYWRIGHT_VERSION)),PLAYWRIGHT_VERSION=$(PLAYWRIGHT_VERSION)) \
Expand Down Expand Up @@ -171,17 +174,19 @@ build-main: build-network-check
prev_kimi=$$(docker inspect --format='{{ index .Config.Labels "org.opencontainers.image.kimi_code_version" }}' $(MAIN_IMAGE) 2>/dev/null || true); \
prev_opencode=$$(docker inspect --format='{{ index .Config.Labels "org.opencontainers.image.opencode_version" }}' $(MAIN_IMAGE) 2>/dev/null || true); \
prev_pi=$$(docker inspect --format='{{ index .Config.Labels "org.opencontainers.image.pi_coding_agent_version" }}' $(MAIN_IMAGE) 2>/dev/null || true); \
prev_dsh=$$(docker inspect --format='{{ index .Config.Labels "org.opencontainers.image.dsh_version" }}' $(MAIN_IMAGE) 2>/dev/null || true); \
fmt() { v="$$1"; if [ -z "$$v" ] || [ "$$v" = "<no value>" ]; then echo "-"; else case "$$v" in v*) echo "$$v";; *) echo "v$$v";; esac; fi; }; \
curC=$$(fmt "$$prev_claude"); curX=$$(fmt "$$prev_codex"); curG=$$(fmt "$$prev_gemini"); curK=$$(fmt "$$prev_grok"); curKi=$$(fmt "$$prev_kimi"); curO=$$(fmt "$$prev_opencode"); curP=$$(fmt "$$prev_pi"); \
tgtC=$$(fmt "$(CLAUDE_CODE_VERSION)"); tgtX=$$(fmt "$(CODEX_VERSION)"); tgtG=$$(fmt "$(GEMINI_CLI_VERSION)"); tgtK=$$(fmt "$(GROK_CLI_VERSION)"); tgtKi=$$(fmt "$(KIMI_CODE_VERSION)"); tgtO=$$(fmt "$(OPENCODE_VERSION)"); tgtP=$$(fmt "$(PI_CODING_AGENT_VERSION)"); \
if [ "$$curC" = "$$tgtC" ] && [ "$$curX" = "$$tgtX" ] && [ "$$curG" = "$$tgtG" ] && [ "$$curK" = "$$tgtK" ] && [ "$$curKi" = "$$tgtKi" ] && [ "$$curO" = "$$tgtO" ] && [ "$$curP" = "$$tgtP" ]; then \
curC=$$(fmt "$$prev_claude"); curX=$$(fmt "$$prev_codex"); curG=$$(fmt "$$prev_gemini"); curK=$$(fmt "$$prev_grok"); curKi=$$(fmt "$$prev_kimi"); curO=$$(fmt "$$prev_opencode"); curP=$$(fmt "$$prev_pi"); curD=$$(fmt "$$prev_dsh"); \
tgtC=$$(fmt "$(CLAUDE_CODE_VERSION)"); tgtX=$$(fmt "$(CODEX_VERSION)"); tgtG=$$(fmt "$(GEMINI_CLI_VERSION)"); tgtK=$$(fmt "$(GROK_CLI_VERSION)"); tgtKi=$$(fmt "$(KIMI_CODE_VERSION)"); tgtO=$$(fmt "$(OPENCODE_VERSION)"); tgtP=$$(fmt "$(PI_CODING_AGENT_VERSION)"); tgtD=$$(fmt "$(DSH_VERSION)"); \
if [ "$$curC" = "$$tgtC" ] && [ "$$curX" = "$$tgtX" ] && [ "$$curG" = "$$tgtG" ] && [ "$$curK" = "$$tgtK" ] && [ "$$curKi" = "$$tgtKi" ] && [ "$$curO" = "$$tgtO" ] && [ "$$curP" = "$$tgtP" ] && [ "$$curD" = "$$tgtD" ]; then \
echo "Claude: $$tgtC (no change)"; \
echo "Codex: $$tgtX (no change)"; \
echo "Gemini: $$tgtG (no change)"; \
echo "Grok: $$tgtK (no change)"; \
echo "Kimi: $$tgtKi (no change)"; \
echo "opencode: $$tgtO (no change)"; \
echo "pi: $$tgtP (no change)"; \
echo "dsh: $$tgtD (no change)"; \
echo "Already up-to-date"; \
else \
if [ "$$curC" = "$$tgtC" ]; then \
Expand Down Expand Up @@ -219,6 +224,11 @@ build-main: build-network-check
else \
echo "pi: $$curP -> $$tgtP"; \
fi; \
if [ "$$curD" = "$$tgtD" ]; then \
echo "dsh: $$tgtD (no change)"; \
else \
echo "dsh: $$curD -> $$tgtD"; \
fi; \
fi
@echo "Hint: override via GO_VERSION=... CLAUDE_CODE_VERSION=... or run 'make versions-pin'"
docker build $(DOCKER_BUILD_FLAGS) -f $(DOCKERFILE) $(MAIN_BUILD_ARGS) -t $(MAIN_IMAGE) .
Expand Down Expand Up @@ -519,6 +529,7 @@ help:
@echo " KIMI_CODE_VERSION Kimi Code CLI version (default: $(KIMI_CODE_VERSION))"
@echo " OPENCODE_VERSION opencode CLI version (default: $(OPENCODE_VERSION))"
@echo " PI_CODING_AGENT_VERSION pi CLI version (default: $(PI_CODING_AGENT_VERSION))"
@echo " DSH_VERSION dsh CLI version (default: $(DSH_VERSION))"
@echo " CCX_VERSION Atlas CLI version (default: $(CCX_VERSION))"
@echo " PLAYWRIGHT_VERSION Playwright version (default: $(PLAYWRIGHT_VERSION))"
@echo " CLOAKBROWSER_WRAPPER_VERSION CloakBrowser npm wrapper version (default: $(CLOAKBROWSER_WRAPPER_VERSION))"
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ English | [简体中文](README.zh-CN.md)
[![Docs](https://img.shields.io/badge/docs-docs.deva.sh-111111)](https://docs.deva.sh)
[![License](https://img.shields.io/github/license/thevibeworks/deva)](LICENSE)

Run Claude Code, Codex, Gemini, Grok, Kimi, opencode, and pi inside Docker without pretending the agents' own permission prompts are the thing keeping you safe.
Run Claude Code, Codex, Gemini, Grok, Kimi, opencode, pi, and dsh inside Docker without pretending the agents' own permission prompts are the thing keeping you safe.

The container is the sandbox, mounts are the contract. What that buys you:

- Full-speed agents. Permission prompts exist because the blast radius is your host. Make the blast radius a container and YOLO stops being reckless — all seven agents run with their permission systems off (`claude --dangerously-skip-permissions`, `codex --dangerously-bypass-approvals-and-sandbox`, `gemini --yolo`, `grok --always-approve`, `kimi --yolo`, opencode via `OPENCODE_PERMISSION` allow-all, pi has no permission system by design). Worst case dies with the container.
- Full-speed agents. Permission prompts exist because the blast radius is your host. Make the blast radius a container and YOLO stops being reckless — all eight agents run with their permission systems off (`claude --dangerously-skip-permissions`, `codex --dangerously-bypass-approvals-and-sandbox`, `gemini --yolo`, `grok --always-approve`, `kimi --yolo`, opencode via `OPENCODE_PERMISSION` allow-all, pi has no permission system by design, dsh via `DSH_PERMISSION_MODE=danger-full-access`). Worst case dies with the container.
- The vendor's code never sees your host. Agent CLIs are fast-moving npm trees with auto-updaters. Here they are born inside the image: no `~/.ssh`, no `~/.aws`, no shell env soup, no browser profiles. Nothing to harvest.
- Everything that crosses the boundary is explicit. Files: mounts. Secrets: the env you pass. Network: the posture you pick — default bridge, your proxy, `--host-net`, or nothing. If you didn't wire it, the agent doesn't have it.
- Identity is a launch flag, not a global singleton. Per-agent config homes under `~/.config/deva/`, `--auth-with` / `--config-home` for the second account or API-key billing. Switch accounts per run; project, sessions, and container state stay put.
Expand Down Expand Up @@ -41,6 +41,7 @@ deva.sh grok
deva.sh kimi
deva.sh opencode
deva.sh pi
deva.sh dsh

deva.sh claude --rm # throwaway container
deva.sh claude --debug --dry-run # inspect the docker run before trusting it
Expand Down
Loading
Loading