Skip to content
Open
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
27 changes: 27 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
This file provides guidance to codex, Claude Code when working with code in this repository.

## Deva Architecture: Container-Based Agent Sandboxing

**CRITICAL DESIGN PATTERN**: Deva purposely runs ALL agents inside Docker containers. The container IS the sandbox.

- Each agent (claude, codex, gemini) runs in isolated container environment
- Agent internal sandboxes/permission systems are DISABLED:
- claude: `--dangerously-skip-permissions`
- gemini: `--yolo` flag
- codex: equivalent unrestricted mode
- Container provides security boundary instead of agent-level prompts
- Result: No interactive permission prompts while maintaining isolation

**Why**: Avoids permission fatigue in trusted workspaces while keeping agents containerized for safety.

## We're following Issue-Based Development (IBD) workflow
1. Before running any Git/GitHub CLI `Bash` command (`git commit`, `gh issue create`, `gh pr create`, etc.), open the corresponding file in @workflows to review required steps.
2. Always apply the exact templates or conventions from the following files:
Expand Down Expand Up @@ -121,6 +135,19 @@ Model aliases are automatically converted to appropriate formats (API model name
- Requires explicit confirmation (`yes`) to proceed
- Protects users from accidentally giving Claude access to all personal files

**Docker Socket Warning** (SECURITY-SENSITIVE):
By default, `/var/run/docker.sock` is auto-mounted if present. This grants full Docker API access to the container - effectively equivalent to root on the host. The "container as sandbox" model is weakened when Docker socket is mounted.

Implications:
- Agent can start/stop any container on host
- Agent can mount any host path into new containers
- Agent can escape to host via privileged container creation

Mitigations:
- Use `--no-docker` flag to disable auto-mount
- Set `DEVA_NO_DOCKER=1` environment variable
- Only mount when Docker-in-Docker workflows are required

## Docker Architecture Details

### Volume Mounting Strategy
Expand Down
11 changes: 11 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Deva Architecture: Container-Based Agent Sandboxing

**CRITICAL DESIGN PATTERN**: Deva purposely runs ALL agents inside Docker containers. The container IS the sandbox.

- Each agent (claude, codex, gemini) runs in isolated container environment
- Agent internal sandboxes/permission systems are DISABLED (e.g., claude --dangerously-skip-permissions, GEMINI_SANDBOX=false)
- Container provides security boundary instead of agent-level prompts
- Result: No interactive permission prompts while maintaining isolation

**Why**: Avoids permission fatigue in trusted workspaces while keeping agents containerized for safety.

## We're following Issue-Based Development (IBD) workflow
1. Before running any Git/GitHub CLI `Bash` command (`git commit`, `gh issue create`, `gh pr create`, etc.), open the corresponding file in @workflows to review required steps.
2. Always apply the exact templates or conventions from the following files:
Expand Down
5 changes: 5 additions & 0 deletions DEV-LOGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
- Reference issue numbers in the format `#<issue-number>` for easy linking.


# [2025-11-27] Dev Log: Docker-in-Docker auto-mount support
- Why: Common dev workflow need - testing containers, building images, CI/CD simulation inside deva environments
- What: Auto-mount Docker socket (`/var/run/docker.sock`) by default with graceful detection, opt-out via `--no-docker` flag or `DEVA_NO_DOCKER=1`, quick permission fix (chmod 666) for deva user access
- Result: DinD works out-of-box on Linux/macOS/WSL2, no manual socket mounting needed, aligns with YOLO philosophy (make it work, container is the boundary)

# [2025-10-26] Dev Log: Custom credential files via --auth-with
- Why: Users have multiple credential files, needed direct path support beyond predefined auth methods
- What: `--auth-with /path/to/creds.json` now works, auto-backup existing credentials, workspace session tracking in `~/.config/deva/sessions/*.json`
Expand Down
89 changes: 52 additions & 37 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,23 +48,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
RUN curl -fsSL https://bun.sh/install | bash && \
ln -s /root/.bun/bin/bun /usr/local/bin/bun

# Install Copilot API branch with GPT-5 Codex responses support (caozhiyuan fork)
# feature/responses-api adds: GPT-5-Codex support, model reasoning, token caching, enhanced streaming
ARG COPILOT_API_REPO=https://github.com/caozhiyuan/copilot-api.git
ARG COPILOT_API_BRANCH=feature/responses-api
ARG COPILOT_API_COMMIT=83cdfde17d7d3be36bd2493cc7592ff13be4928d

RUN --mount=type=cache,target=/root/.npm,sharing=locked \
npm install -g npm@latest pnpm && \
git clone --branch "${COPILOT_API_BRANCH}" "${COPILOT_API_REPO}" /tmp/copilot-api && \
cd /tmp/copilot-api && \
git checkout "${COPILOT_API_COMMIT}" && \
git log --oneline -5 && \
bun install --frozen-lockfile && bun run build && \
cd /tmp && npm install -g --ignore-scripts /tmp/copilot-api && \
rm -rf /tmp/copilot-api && \
npm cache clean --force

# Install stable runtimes BEFORE volatile packages to maximize cache reuse
RUN curl -LsSf https://astral.sh/uv/install.sh | sh

# Pre-install Python 3.14t (free-threaded) for uv
Expand All @@ -77,6 +61,26 @@ RUN --mount=type=cache,target=/tmp/go-cache,sharing=locked \
wget -q https://go.dev/dl/go1.22.0.linux-${GO_ARCH}.tar.gz && \
tar -C /usr/local -xzf go1.22.0.linux-${GO_ARCH}.tar.gz

# Install Copilot API (ericc-ch fork with latest features)
# Placed at end of runtimes stage to avoid invalidating cache for stable runtimes
ARG COPILOT_API_REPO=https://github.com/ericc-ch/copilot-api.git
ARG COPILOT_API_BRANCH=master
ARG COPILOT_API_COMMIT=master
ARG COPILOT_API_VERSION

LABEL org.opencontainers.image.copilot_api_version=${COPILOT_API_VERSION}

RUN --mount=type=cache,target=/root/.npm,sharing=locked \
npm install -g npm@latest pnpm && \
git clone --branch "${COPILOT_API_BRANCH}" "${COPILOT_API_REPO}" /tmp/copilot-api && \
cd /tmp/copilot-api && \
git checkout "${COPILOT_API_COMMIT}" && \
git log --oneline -5 && \
bun install --frozen-lockfile && bun run build && \
cd /tmp && npm install -g --ignore-scripts /tmp/copilot-api && \
rm -rf /tmp/copilot-api && \
npm cache clean --force

FROM runtimes AS cloud-tools

RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
Expand Down Expand Up @@ -146,31 +150,12 @@ RUN mkdir -p "$DEVA_HOME/.npm-global" && \

# Set npm configuration for deva user and install CLI tooling
USER $DEVA_USER
ARG CLAUDE_CODE_VERSION
ARG CODEX_VERSION

# Record key tool versions as labels for quick inspection
LABEL org.opencontainers.image.claude_code_version=${CLAUDE_CODE_VERSION}
LABEL org.opencontainers.image.codex_version=${CODEX_VERSION}

# Speed up npm installs and avoid noisy audits/funds prompts
ENV NPM_CONFIG_AUDIT=false \
NPM_CONFIG_FUND=false

# Use BuildKit cache for npm to speed up repeated builds
RUN --mount=type=cache,target=/home/deva/.npm,uid=${DEVA_UID},gid=${DEVA_GID},sharing=locked \
npm config set prefix "$DEVA_HOME/.npm-global" && \
npm install -g --no-audit --no-fund \
@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION} \
@mariozechner/claude-trace \
@openai/codex@${CODEX_VERSION} && \
npm cache clean --force && \
npm list -g --depth=0 @anthropic-ai/claude-code @openai/codex || true

# Install Go tools for Atlassian integration (Confluence/Jira/Bitbucket)
RUN go install github.com/lroolle/atlas-cli/cmd/atl@5f6a20c4d164bf6fe6f5c60f9ac12dfccf210758 && \
sudo mv $HOME/go/bin/atl /usr/local/bin/

# Install stable components BEFORE ARG declarations to maximize cache reuse
RUN git clone --depth=1 https://github.com/ohmyzsh/ohmyzsh "$DEVA_HOME/.oh-my-zsh" && \
git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions "$DEVA_HOME/.oh-my-zsh/custom/plugins/zsh-autosuggestions" && \
git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git "$DEVA_HOME/.oh-my-zsh/custom/plugins/zsh-syntax-highlighting"
Expand All @@ -186,6 +171,36 @@ RUN echo 'export ZSH="$HOME/.oh-my-zsh"' > "$DEVA_HOME/.zshrc" && \
RUN curl -LsSf https://astral.sh/uv/install.sh | sh && \
$DEVA_HOME/.local/bin/uv python install 3.14t

# Declare ARGs immediately before usage to minimize cache invalidation
ARG CLAUDE_CODE_VERSION
ARG CODEX_VERSION
ARG GEMINI_CLI_VERSION=latest

# Record key tool versions as labels for quick inspection
LABEL org.opencontainers.image.claude_code_version=${CLAUDE_CODE_VERSION}
LABEL org.opencontainers.image.codex_version=${CODEX_VERSION}
LABEL org.opencontainers.image.gemini_cli_version=${GEMINI_CLI_VERSION}

# Use BuildKit cache for npm to speed up repeated builds
RUN --mount=type=cache,target=/home/deva/.npm,uid=${DEVA_UID},gid=${DEVA_GID},sharing=locked \
npm config set prefix "$DEVA_HOME/.npm-global" && \
npm install -g --no-audit --no-fund \
@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION} \
@mariozechner/claude-trace \
@openai/codex@${CODEX_VERSION} \
@google/gemini-cli@${GEMINI_CLI_VERSION} && \
npm cache clean --force && \
npm list -g --depth=0 @anthropic-ai/claude-code @openai/codex @google/gemini-cli || true

# Volatile packages: Install at the end to avoid cascading rebuilds
ARG ATLAS_CLI_VERSION=main

LABEL org.opencontainers.image.atlas_cli_version=${ATLAS_CLI_VERSION}

# Install Go tools for Atlassian integration (Confluence/Jira/Bitbucket)
RUN go install github.com/lroolle/atlas-cli/cmd/atl@${ATLAS_CLI_VERSION} && \
sudo mv $HOME/go/bin/atl /usr/local/bin/

USER root

COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
Expand Down
Loading