Sign inSign up

socone/happy-claude:latest

Manifest digest

sha256:9eec21d3ff54cf1ed6dfc24a042442af69f00b4a4b377a78fd1e340787d58898

Last pushed

5 days by socone

Type

Sandbox Kit

Manifest digest

sha256:9eec21d3ff54cf1ed6dfc24a042442af69f00b4a4b377a78fd1e340787d58898

yaml
schemaVersion: "2"
kind: sandbox
name: happy-claude
displayName: Happy + Claude Code
description: Claude Code driven through Happy, controllable from phone or web
sandbox:
    image: socone/sbx-claude-happy:latest
    entrypoint:
        - sbx-session
    command:
        default:
            - happy
            - claude
            - --dangerously-skip-permissions
        interactive:
            - happy
            - claude
            - --dangerously-skip-permissions
agentInstructions:
    filename: CLAUDE.md
    content: |
        ## This session runs under Happy

        The Claude Code process you are running in was started by `happy claude`,
        so the session is mirrored to the Happy mobile/web app over an
        end-to-end encrypted relay. The person driving the session may be on a
        phone rather than at this terminal, and the sandbox keeps running when
        nobody is attached.

        Practical consequences:

        - Do not assume anyone is watching the terminal right now. Prefer
          finishing a unit of work and reporting it over asking a question that
          blocks until someone reads it.
        - Long-running commands are fine; the session survives a detached
          terminal.
        - `/home/agent/.happy` holds Happy's identity key. Never print its
          contents, and never commit it.
permissions:
    network:
        allow:
            - api.anthropic.com:443
            - platform.claude.com:443
            - downloads.claude.ai:443
            - claude.com:443
            - code.claude.com:443
            - mcp-proxy.anthropic.com:443
            - bridge.claudeusercontent.com:443
            - api.cluster-fluster.com:443
            - app.happy.engineering:443
            - happy.engineering:443
            - registry.npmjs.org:443
volumes:
    - path: /home/agent/.happy
      size: 512m
    - path: /home/agent/.claude/projects
      size: 2g
    - path: /home/agent/.claude/sessions
      size: 512m
    - path: /home/agent/.claude/todos
      size: 512m
    - path: /home/agent/.claude/shell-snapshots
      size: 512m
    - path: /home/agent/.claude/statsig
      size: 512m
credentials:
    - service: anthropic
      apiKey:
        name: ANTHROPIC_API_KEY
        inject:
            - domain: api.anthropic.com
              header: x-api-key
              format: '%s'
            - domain: console.anthropic.com
              header: x-api-key
              format: '%s'
            - domain: claude.ai
              header: x-api-key
              format: '%s'
            - domain: mcp-proxy.anthropic.com
              header: x-api-key
              format: '%s'
      oauth:
        tokenEndpoint:
            host: platform.claude.com
            path: /v1/oauth/token
        sentinels:
            accessToken: sk-ant-oat01-proxy-managed
            refreshToken: sk-ant-ort01-proxy-managed
        credentialFile:
            path: ~/.claude/.credentials.json
            template: '{"claudeAiOauth":{"accessToken":"{{.AccessToken}}","refreshToken":"{{.RefreshToken}}","expiresAt":{{.ExpiresAt}},"scopes":{{.ScopesJSON}}}{{if .PrimaryApiKey}},"primaryApiKey":"{{.PrimaryApiKey}}"{{end}}}'
        skipIfEnv:
            - ANTHROPIC_API_KEY
environment:
    variables:
        IS_SANDBOX: "1"
setup:
    install:
        - command: |
            set -e
            ws="${WORKSPACE_DIR:-/}"
            esc=$(printf '%s' "$ws" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\t/\\t/g; s/\r/\\r/g')
            projects="\"/\": { \"hasTrustDialogAccepted\": true }"
            [ "$ws" = "/" ] || projects="$projects, \"$esc\": { \"hasTrustDialogAccepted\": true }"
            printf '%s\n' "{
              \"bypassPermissionsModeAccepted\": true,
              \"hasCompletedOnboarding\": true,
              \"projects\": { $projects }
            }" > /home/agent/.claude.json
            chown agent:agent /home/agent/.claude.json
          user: "0"
          description: Seed Claude bypass/trust flags (root; overwrites image-shipped file)
        - command: |
            set -e
            mkdir -p /home/agent/.claude
            HELPER=''
            if [ "${SBX_CRED_ANTHROPIC_MODE:-none}" != none ]; then
              HELPER='  "apiKeyHelper": "echo proxy-managed",
            '
            fi
            printf '%s' "{
              \"themeId\": 1,
              \"alwaysThinkingEnabled\": true,
            ${HELPER}  \"permissions\": { \"defaultMode\": \"bypassPermissions\" },
              \"bypassPermissionsModeAccepted\": true,
              \"skipDangerousModePermissionPrompt\": true
            }
            " > /home/agent/.claude/settings.json
          user: agent
          description: Seed Claude settings.json from SBX_CRED_ANTHROPIC_MODE
        - command: |
            set -e
            [ -n "$MCP_GATEWAY_URL" ] || exit 0
            export PATH="$HOME/.local/bin:$HOME/.claude/local:$PATH"
            claude mcp add mcp-gateway "$MCP_GATEWAY_URL" \
              --transport http \
              --scope user \
              --header "Authorization: Bearer $MCP_SENTINEL_TOKEN_NAME" || true
          user: agent
          description: Register the sandbox MCP gateway with claude
    startup:
        - command:
            - sh
            - -c
            - chown -R agent:agent /home/agent/.happy /home/agent/.claude/projects /home/agent/.claude/sessions /home/agent/.claude/todos /home/agent/.claude/shell-snapshots /home/agent/.claude/statsig 2>/dev/null || true
          user: "0"
          description: Re-own volume mount roots to agent