|
# Claude Jail Taskfile. Used to run Claude. |
|
# Actual app-related taskfile must be in Taskfile.yml |
|
version: '3' |
|
|
|
vars: |
|
PORT: '{{.PORT | default "9090"}}' |
|
HTTP_HOST: '{{.HTTP_HOST | default "0.0.0.0"}}' |
|
|
|
APP_NAME: '{{ .APP_NAME | default (base .PWD)}}' |
|
WORKSPACE: "{{.APP_NAME}}" |
|
BINARY_NAME: "{{.APP_NAME}}" |
|
COMPOSE: "docker compose -f {{.USER_WORKING_DIR}}/.devcontainer/compose.dev.yml" |
|
RUN: "{{.COMPOSE}} run --remove-orphans -it claude" |
|
CLAUDE: "{{.RUN}} claude --dangerously-skip-permissions" |
|
DB_PATH: ./data/{{.APP_NAME}}.db |
|
|
|
BASE_DIR: "{{ default .USER_WORKING_DIR }}" |
|
|
|
env: |
|
APP_NAME: "{{.APP_NAME}}" |
|
BASE_DIR: "{{.BASE_DIR}}" |
|
|
|
PORT: "{{.PORT}}" |
|
|
|
tasks: |
|
claude: |
|
desc: Run Claude CLI in the dev container |
|
silent: true |
|
deps: |
|
- _generate-all-configs |
|
|
|
cmds: |
|
- | |
|
echo "APP_NAME: {{.APP_NAME}}" |
|
- "{{.CLAUDE}} {{.CLI_ARGS}}" |
|
deploy: |
|
silent: true |
|
cmds: |
|
- | |
|
if ! git remote -v | grep -q "dokku-{{.APP_NAME}}"; then |
|
echo "Error: dokku-{{.APP_NAME}} remote not found" |
|
echo "Please add the remote with: git remote add dokku-{{.APP_NAME}} [email protected]:{{.APP_NAME}}" |
|
exit 1 |
|
fi |
|
git commit --allow-empty -am "WIP" && git push dokku-{{.APP_NAME}} $(git branch --show-current):main |
|
|
|
|
|
########## Generators ########## |
|
_generate-mcp-config: |
|
desc: Generate .mcp.json configuration file |
|
silent: true |
|
cmds: |
|
- | |
|
cat > {{.BASE_DIR}}/.mcp.json << 'EOF' |
|
{ |
|
"mcpServers": { |
|
"kitcut-sse": { |
|
"type": "sse", |
|
"url": "http://host.docker.internal:9090/sse", |
|
"headers": { |
|
"Authorization": "Bearer ${TEST_AUTH_TOKEN}" |
|
} |
|
}, |
|
"kitcut-local": { |
|
"command": "./kitcut/kitcut", |
|
"env": { |
|
"DATA_DIR": "./kitcut/data" |
|
} |
|
} |
|
} |
|
} |
|
EOF |
|
echo "Generated {{.BASE_DIR}}/.mcp.json" |
|
|
|
_generate-app-config: |
|
desc: Generate app.json configuration file |
|
silent: true |
|
cmds: |
|
- | |
|
cat > {{.BASE_DIR}}/app.json << 'EOF' |
|
{ |
|
"healthchecks": { |
|
"web": [ |
|
{ |
|
"type": "startup", |
|
"name": "web check", |
|
"description": "Checking if the app responds to the /healthz endpoint", |
|
"path": "/healthz", |
|
"attempts": 3 |
|
} |
|
] |
|
} |
|
} |
|
EOF |
|
echo "Generated {{.BASE_DIR}}/app.json" |
|
|
|
_generate-devcontainer-compose: |
|
desc: Generate .devcontainer/compose.dev.yml file |
|
silent: true |
|
cmds: |
|
- mkdir -p {{.USER_WORKING_DIR}}/.devcontainer |
|
- | |
|
cat > {{.USER_WORKING_DIR}}/.devcontainer/compose.dev.yml << 'EOF' |
|
--- |
|
services: |
|
claude: |
|
build: |
|
context: . |
|
dockerfile: Dockerfile |
|
working_dir: /${BASE_DIR:-app} |
|
container_name: claude-jail-${APP_NAME:-app} |
|
volumes: |
|
# Mount BASE_DIR under the same path |
|
- ${BASE_DIR}:/${BASE_DIR} |
|
|
|
# Mount the test run directory as workspace |
|
- ${BASE_DIR}:/${APP_NAME:-app} |
|
|
|
|
|
# Mount Claude and host agents |
|
- ${HOME:-}/.claude-sandbox/:/root/ # Host-based sandbox home dir |
|
- ${HOME:-}/.claude/agents:/root/.claude/agents:ro # Host-based agents |
|
- ${HOME:-}/.claude/commands/kitcut:/root/.claude/commands/kitcut:ro # Host-based commands |
|
|
|
|
|
environment: |
|
APP_NAME: ${APP_NAME:-app} |
|
IS_SANDBOX: 1 |
|
WORKSPACE: /${APP_NAME:-app} |
|
TEST_AUTH_TOKEN: ${TEST_AUTH_TOKEN} |
|
command: tail -f /dev/null # Keep container running |
|
networks: |
|
- claude-jail-network |
|
|
|
networks: |
|
claude-jail-network: |
|
driver: bridge |
|
EOF |
|
echo "Generated {{.USER_WORKING_DIR}}/.devcontainer/compose.dev.yml" |
|
|
|
_generate-devcontainer-dockerfile: |
|
desc: Generate .devcontainer/Dockerfile |
|
silent: true |
|
cmds: |
|
- mkdir -p {{.USER_WORKING_DIR}}/.devcontainer |
|
- | |
|
cat > {{.USER_WORKING_DIR}}/.devcontainer/Dockerfile << 'EOF' |
|
FROM public.ecr.aws/docker/library/debian:trixie |
|
|
|
# Install system dependencies |
|
# build-essential is the meta-package that includes gcc, g++, make, libc-dev, etc. |
|
# binutils-gold adds the gold linker that Go prefers |
|
RUN apt-get update && apt-get install -y \ |
|
build-essential \ |
|
binutils-gold \ |
|
curl \ |
|
wget \ |
|
git \ |
|
jq \ |
|
tree \ |
|
ripgrep \ |
|
ca-certificates \ |
|
sqlite3 \ |
|
postgresql-client \ |
|
pkg-config \ |
|
procps \ |
|
htop \ |
|
vim \ |
|
&& rm -rf /var/lib/apt/lists/* |
|
|
|
# Install Go (multi-arch support) |
|
ENV GO_VERSION=1.24.6 |
|
RUN ARCH=$(dpkg --print-architecture) && \ |
|
curl -LO https://go.dev/dl/go${GO_VERSION}.linux-${ARCH}.tar.gz && \ |
|
tar -C /usr/local -xzf go${GO_VERSION}.linux-${ARCH}.tar.gz && \ |
|
rm go${GO_VERSION}.linux-${ARCH}.tar.gz |
|
ENV PATH="/usr/local/go/bin:${PATH}" |
|
ENV GOPATH="/go" |
|
ENV PATH="${GOPATH}/bin:${PATH}" |
|
|
|
# Install Task (Taskfile) |
|
RUN sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b /usr/local/bin |
|
|
|
# Install Node.js and npm (for potential frontend tools) |
|
RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && \ |
|
apt-get install -y nodejs && \ |
|
rm -rf /var/lib/apt/lists/* |
|
|
|
# Install Go development tools |
|
RUN go install github.com/air-verse/air@latest && \ |
|
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest && \ |
|
go install golang.org/x/tools/cmd/goimports@latest |
|
|
|
# Install Docker CLI and Docker Compose v2 (optional - for compose:* tasks) |
|
# Note: Standard tasks (build, start, test) don't require Docker |
|
RUN apt-get update && \ |
|
apt-get install -y \ |
|
apt-transport-https \ |
|
gnupg \ |
|
lsb-release && \ |
|
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \ |
|
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null && \ |
|
apt-get update && \ |
|
apt-get install -y docker-ce-cli docker-compose-plugin && \ |
|
rm -rf /var/lib/apt/lists/* |
|
|
|
# Install Claude CLI |
|
RUN npm install -g @anthropic-ai/claude-code |
|
|
|
|
|
# Set environment variables |
|
ENV CLAUDE_HOME=/root |
|
|
|
WORKDIR /${APP_NAME} |
|
EOF |
|
echo "Generated {{.USER_WORKING_DIR}}/.devcontainer/Dockerfile" |
|
|
|
_generate-devcontainer-config: |
|
desc: Generate .devcontainer/devcontainer.json file |
|
silent: true |
|
cmds: |
|
- mkdir -p {{.USER_WORKING_DIR}}/.devcontainer |
|
- | |
|
cat > {{.USER_WORKING_DIR}}/.devcontainer/devcontainer.json << 'EOF' |
|
{ |
|
"name": "Context Engineering Dev Container", |
|
"dockerComposeFile": "compose.dev.yml", |
|
"service": "claude", |
|
"workspaceFolder": "/workspace", |
|
|
|
// Features to add to the dev container |
|
// Note: JetBrains may not support all features - these are primarily for VS Code |
|
"features": { |
|
"ghcr.io/devcontainers/features/git:1": {}, |
|
"ghcr.io/devcontainers/features/github-cli:1": {} |
|
}, |
|
|
|
// Configure tool-specific properties |
|
"customizations": { |
|
// JetBrains IDE Native Dev Container Support (2024.3+) |
|
// See: https://www.jetbrains.com/help/idea/start-dev-container-inside-ide.html |
|
"jetbrains": { |
|
// Product-specific IDE backend to use |
|
"product": "GO", // Can be "GO" for GoLand, "IU" for IntelliJ Ultimate, "IC" for Community |
|
|
|
// Plugins to install in the IDE backend |
|
"plugins": [ |
|
"com.intellij.plugins.go", |
|
"org.jetbrains.plugins.github", |
|
"Docker", |
|
"com.jetbrains.sh", |
|
"name.kropp.intellij.makefile", |
|
"com.github.copilot", |
|
"org.jetbrains.plugins.terminal", |
|
"org.jetbrains.plugins.yaml", |
|
"com.intellij.tasks" |
|
], |
|
|
|
// IDE backend configuration |
|
"ideOptions": { |
|
"vmoptions": [ |
|
"-Xmx2048m", |
|
"-XX:+UseG1GC", |
|
"-XX:SoftRefLRUPolicyMSPerMB=50" |
|
] |
|
} |
|
}, |
|
|
|
// Codespaces configuration (works with JetBrains Gateway) |
|
"codespaces": { |
|
"openFiles": [ |
|
"README.md" |
|
] |
|
}, |
|
|
|
"vscode": { |
|
"extensions": [ |
|
"golang.Go", |
|
"ms-vscode.makefile-tools", |
|
"esbenp.prettier-vscode", |
|
"dbaeumer.vscode-eslint", |
|
"bradlc.vscode-tailwindcss", |
|
"redhat.vscode-yaml", |
|
"ms-azuretools.vscode-docker", |
|
"GitHub.copilot", |
|
"task.vscode-task" |
|
], |
|
"settings": { |
|
"go.toolsManagement.checkForUpdates": "local", |
|
"go.useLanguageServer": true, |
|
"go.gopath": "/go", |
|
"go.goroot": "/usr/local/go", |
|
"terminal.integrated.defaultProfile.linux": "bash", |
|
"editor.formatOnSave": true, |
|
"editor.rulers": [80, 120], |
|
"files.watcherExclude": { |
|
"**/target/**": true, |
|
"**/node_modules/**": true, |
|
"**/.git/objects/**": true, |
|
"**/vendor/**": true |
|
} |
|
} |
|
} |
|
}, |
|
|
|
// Environment variables |
|
"remoteEnv": { |
|
"GOPATH": "/go", |
|
"PATH": "/usr/local/go/bin:/go/bin:${PATH}", |
|
"DATA_DIR": "/data", |
|
"CLAUDE_HOME": "/home/claude", |
|
"WORKSPACE": "/workspace", |
|
"GO111MODULE": "on" |
|
}, |
|
|
|
// Mount points - these work with both VS Code and JetBrains |
|
// JetBrains will use these if dockerComposeFile is not specified |
|
"mounts": [ |
|
"source=${localWorkspaceFolder},target=/workspace,type=bind", |
|
"source=${localWorkspaceFolder}/mcp-kits-server/data/KITS,target=/kits,type=bind,readonly", |
|
"source=${localWorkspaceFolder}/mcp-kits-server,target=/mcp-server,type=bind,readonly", |
|
"source=/var/run/docker.sock,target=/var/run/docker.sock,type=bind" |
|
], |
|
|
|
// Run as the claude user |
|
"remoteUser": "claude", |
|
|
|
// Commands to run after container is created |
|
"postCreateCommand": "go version && task --version && echo 'Dev container ready!'", |
|
|
|
// Commands to run when attaching to the container |
|
"postAttachCommand": "echo 'Welcome to Context Engineering Development Environment'", |
|
|
|
// Forward ports from container to host |
|
"forwardPorts": [8080, 3000, 5173], |
|
|
|
// Comment out to run as root instead |
|
"containerUser": "claude", |
|
|
|
// Use 'postStartCommand' to run commands after the container is started |
|
"postStartCommand": "git config --global --add safe.directory /workspace", |
|
|
|
// Additional Docker run arguments - needed for debugging |
|
"runArgs": [ |
|
"--cap-add=SYS_PTRACE", |
|
"--security-opt", |
|
"seccomp=unconfined", |
|
"--init" |
|
], |
|
|
|
// JetBrains-specific: Ensure the container stays running |
|
"overrideCommand": false, |
|
|
|
// Ensure compatibility with both VS Code and JetBrains |
|
"updateRemoteUserUID": true |
|
} |
|
EOF |
|
echo "Generated {{.USER_WORKING_DIR}}/.devcontainer/devcontainer.json" |
|
|
|
_generate-all-configs: |
|
desc: Generate all configuration files |
|
silent: true |
|
cmds: |
|
- task: _generate-mcp-config |
|
vars: |
|
BASE_DIR: "{{.BASE_DIR}}" |
|
- task: _generate-app-config |
|
vars: |
|
BASE_DIR: "{{.BASE_DIR}}" |
|
- task: _generate-devcontainer-compose |
|
vars: |
|
BASE_DIR: "{{.BASE_DIR}}" |
|
- task: _generate-devcontainer-dockerfile |
|
vars: |
|
BASE_DIR: "{{.BASE_DIR}}" |
|
- task: _generate-devcontainer-config |
|
vars: |
|
BASE_DIR: "{{.BASE_DIR}}" |
|
- echo "All configuration files generated successfully!" |