Skip to content
Closed
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
5 changes: 4 additions & 1 deletion .planning/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@
"plan_check": true,
"verifier": true
},
"granularity": "coarse"
"granularity": "coarse",
"graphify": {
"enabled": true
}
}
41 changes: 31 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,6 @@ Docker-based dev containers with Claude Code, MCP servers, and common tooling pr

environment:
- CONTEXT7_API_KEY=your-key
- AUTOMEM_ENDPOINT=your-endpoint
- AUTOMEM_API_KEY=your-key
- NTFY_URL=https://ntfy.sh/your-topic
- NTFY_TOKEN=your-token
- ENABLE_TOOL_SEARCH=true
Expand All @@ -52,6 +50,12 @@ Docker-based dev containers with Claude Code, MCP servers, and common tooling pr
- ..:/workspace:cached
- home:/home
- /var/run/docker.sock:/var/run/docker.sock
# Host credentials (see "Host Credentials" section below)
- ~/.claude:/home/dev/.claude
- ~/.ssh:/home/dev/.ssh:ro
- ~/.gitconfig:/home/dev/.gitconfig:ro
- ~/.config/gh:/home/dev/.config/gh:ro
- ~/.config/github-copilot:/home/dev/.config/github-copilot:ro

# Overrides default command so things don't
# shut down after the process ends
Expand Down Expand Up @@ -159,8 +163,10 @@ All images extend a shared base (`base/Dockerfile` — `debian:trixie`) and run
- **Node.js** via NVM (default: 24.12.0)
- **UV** (Python package manager)
- **Claude Code** CLI + plugins (ECC, Superpowers, official plugin suite)
- **MCP servers**: Serena, Context7, Automem
- **GSD** (Get Shit Done for Claude Code)
- **MCP servers**: Serena, Context7
- **GSD** — Get Shit Done coding workflow (Claude Code via [get-shit-done-cc](https://github.com/gsd-build/get-shit-done-cc), Pi via [gsd-pi](https://github.com/gsd-build/gsd-2))
- **MemPalace** — local AI memory; mines projects and conversations into a searchable palace, no API key required ([MemPalace/mempalace](https://github.com/MemPalace/mempalace))
- **Graphify** — knowledge-graph skill; turns any folder of code, docs, papers, images, or videos into a queryable graph ([safishamsi/graphify](https://github.com/safishamsi/graphify))
- **Agent Browser** + Chrome
- **gstack** — 28 specialized Claude Code engineering skills ([garrytan/gstack](https://github.com/garrytan/gstack))
- **Bun** runtime (`bun`, `bunx`)
Expand All @@ -174,8 +180,8 @@ All images extend a shared base (`base/Dockerfile` — `debian:trixie`) and run
- **ttyd** (web terminal)
- **Database clients**: postgresql-client, default-mysql-client, redis-tools
- **ntfy** notification hooks (Notification + Stop events)
- **pi** a minimal terminal coding harness
- **CliDeck** one dashboard for all your AI coding agents
- **pi** minimal terminal coding harness, with `pi-agent-browser` for browser automation
- **CliDeck** one dashboard for all your AI coding agents

### Bun (`trixie-bun-nvm-uv-claude`)

Expand Down Expand Up @@ -223,13 +229,30 @@ Secret-dependent MCP servers and ntfy hooks are configured at **runtime** (first
| Variable | Description |
|----------|-------------|
| `CONTEXT7_API_KEY` | [Context7](https://context7.com) MCP server API key (skipped if empty) |
| `AUTOMEM_ENDPOINT` | [Automem](https://github.com/verygoodplugins/mcp-automem) MCP server endpoint URL (skipped if empty) |
| `AUTOMEM_API_KEY` | [Automem](https://github.com/verygoodplugins/mcp-automem) MCP server API key (skipped if empty) |
| `NTFY_URL` | [ntfy](https://ntfy.sh) server/topic URL for notification hooks (skipped if empty) |
| `NTFY_TOKEN` | [ntfy](https://ntfy.sh) authentication token for notification hooks (skipped if empty) |

> Optional MCP servers and ntfy hooks are only configured when their corresponding environment variables are set.

## Host Credentials

Mount host directories to forward credentials and settings into the container. The entrypoint automatically merges image-built tooling (plugins, skills, rules, GSD) with your host files — nothing is lost.

| Host Path | Container Path | Purpose |
|-----------|---------------|---------|
| `~/.claude` | `/home/dev/.claude` | Claude Code auth, settings, memory, and projects |
| `~/.ssh` | `/home/dev/.ssh:ro` | SSH keys for git and remote access |
| `~/.gitconfig` | `/home/dev/.gitconfig:ro` | Git identity and config |
| `~/.config/gh` | `/home/dev/.config/gh:ro` | GitHub CLI auth tokens |
| `~/.config/github-copilot` | `/home/dev/.config/github-copilot:ro` | GitHub Copilot OAuth tokens |
| `~/.gnupg` | `/home/dev/.gnupg:ro` | GPG keys for signed commits |

> **How the `~/.claude` merge works:** At build time, the image snapshots all tooling to `/opt/devcontainer-claude/`. When a host `~/.claude` bind-mount is detected at container start, the entrypoint copies missing tooling (plugins, skills, rules, GSD) into the mounted directory without overwriting host files. The image's `CLAUDE.md` is appended if the host version lacks the DevContainer section. The merge is idempotent — container restarts won't duplicate content.

> **Note:** Use `:ro` (read-only) for credentials you don't want the container to modify. `~/.claude` is mounted read-write because Claude Code writes memory, session state, and settings at runtime.

> **Important:** Ensure host files exist before first launch. If a mounted path doesn't exist on the host, Docker creates it as an empty directory, which may cause unexpected behavior.

## CI/CD

Two GitHub Actions workflows build and verify images:
Expand Down Expand Up @@ -278,8 +301,6 @@ Then run with your API keys as environment variables:
```bash
docker run -it \
-e CONTEXT7_API_KEY=your-key \
-e AUTOMEM_ENDPOINT=your-endpoint \
-e AUTOMEM_API_KEY=your-key \
-e NTFY_URL=https://ntfy.sh/your-topic \
-e NTFY_TOKEN=your-token \
trixie-bun-nvm-uv-claude
Expand Down
13 changes: 8 additions & 5 deletions base/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -214,21 +214,18 @@ ENV PATH="/home/dev/.bun/bin:${PATH}"

# Claude Plugins, MCP, Hooks
ARG CONTEXT7_API_KEY=""
ARG AUTOMEM_ENDPOINT=""
ARG AUTOMEM_API_KEY=""
ARG NTFY_URL=""
ARG NTFY_TOKEN=""

ENV CONTEXT7_API_KEY=${CONTEXT7_API_KEY}
ENV AUTOMEM_ENDPOINT=${AUTOMEM_ENDPOINT}
ENV AUTOMEM_API_KEY=${AUTOMEM_API_KEY}
ENV NTFY_URL=${NTFY_URL}
ENV NTFY_TOKEN=${NTFY_TOKEN}

COPY --chown=dev:dev scripts/ntfy-hook.sh $HOME/.local/bin/ntfy-hook.sh
COPY --chown=dev:dev scripts/suggest-context7-hook.sh $HOME/.local/bin/suggest-context7-hook.sh
COPY --chown=dev:dev scripts/init-claude-mcp.sh $HOME/.local/bin/init-claude-mcp.sh
COPY --chown=dev:dev scripts/merge-claude-home.sh $HOME/.local/bin/merge-claude-home.sh
COPY --chown=dev:dev base/ttyd-overlay.html $HOME/ttyd-overlay.html
RUN chmod +x $HOME/.local/bin/ntfy-hook.sh $HOME/.local/bin/suggest-context7-hook.sh $HOME/.local/bin/init-claude-mcp.sh $HOME/.local/bin/merge-claude-home.sh

COPY --chown=dev:dev scripts/setup-claude.sh /tmp/setup-claude.sh
Expand Down Expand Up @@ -258,7 +255,13 @@ RUN echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
# agent-browser
WORKDIR /workspace

RUN npm install -y -g agent-browser clideck @mariozechner/pi-coding-agent
RUN npm install -y -g agent-browser clideck @mariozechner/pi-coding-agent gsd-pi@latest

RUN pi install npm:pi-agent-browser

RUN pip install --break-system-packages mempalace graphifyy

RUN graphify install

RUN agent-browser install --with-deps

Expand Down
1 change: 0 additions & 1 deletion base/devcontainer-claude.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ MCP servers are configured on first shell login via `init-claude-mcp.sh`. Option

- `serena` — semantic code analysis (symbols, references, overview)
- `context7` — library documentation lookup (if CONTEXT7_API_KEY is set)
- `memory` — persistent memory via Automem (if AUTOMEM_ENDPOINT is set)

## Plugins & Skills
- GSD (`/gsd:*`) — project management and execution workflow
Expand Down
4 changes: 4 additions & 0 deletions base/ttyd-overlay.html

Large diffs are not rendered by default.

20 changes: 2 additions & 18 deletions scripts/init-claude-mcp.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,6 @@ if [ -n "$CONTEXT7_API_KEY" ]; then
fi
fi

# --- Automem MCP ---
if [ -n "$AUTOMEM_ENDPOINT" ] && [ -n "$AUTOMEM_API_KEY" ]; then
if ! grep -q '"memory"' "$CLAUDE_JSON" 2>/dev/null; then
$CLAUDE mcp add --transport stdio -s user \
--env="AUTOMEM_ENDPOINT=$AUTOMEM_ENDPOINT" \
--env="AUTOMEM_API_KEY=$AUTOMEM_API_KEY" \
memory -- npx -y @verygoodplugins/mcp-automem
fi
fi

# --- Ntfy Hooks ---
if [ -n "$NTFY_URL" ] && [ -n "$NTFY_TOKEN" ]; then
if ! grep -q 'ntfy-hook' "$CLAUDE_JSON" 2>/dev/null; then
Expand All @@ -62,17 +52,11 @@ if [ -n "$NTFY_URL" ] && [ -n "$NTFY_TOKEN" ]; then
fi

# --- Serena user-scope config ---
# Exclude Serena memory tools via user config
# Disable Serena memory mutation tools via user config
SERENA_USER="$HOME/.serena/user.yml"
mkdir -p "$HOME/.serena"
if [ ! -f "$SERENA_USER" ] || grep -q '^excluded_tools: \[\]' "$SERENA_USER"; then
if [ -n "$AUTOMEM_ENDPOINT" ] && [ -n "$AUTOMEM_API_KEY" ]; then
# Automem replaces all Serena memory/onboarding tools
TOOLS=(write_memory read_memory edit_memory delete_memory list_memories check_onboarding_performed onboarding)
else
# No Automem backend: disable memory mutation tools
TOOLS=(write_memory delete_memory read_memory)
fi
TOOLS=(write_memory delete_memory read_memory)

YAML="excluded_tools:"
for t in "${TOOLS[@]}"; do
Expand Down
10 changes: 3 additions & 7 deletions scripts/setup-claude.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ CLAUDE="$HOME/.local/bin/claude"
# --- Claude Plugins ---

if [ -x "$CLAUDE" ]; then
$CLAUDE plugin marketplace add affaan-m/everything-claude-code
$CLAUDE plugin install everything-claude-code@everything-claude-code
# ECC — low-context / no-hooks install (rules + agents + commands + core skills, no hooks-runtime)
npx -y ecc-install --profile minimal --target claude

$CLAUDE plugin marketplace add obra/superpowers
$CLAUDE plugin install superpowers@superpowers-dev
Expand Down Expand Up @@ -47,11 +47,7 @@ HOOKIFY_DIR="$HOME/.claude/plugins/cache/claude-code-plugins/hookify/0.1.0"

# --- ECC Rules ---

git clone https://github.com/affaan-m/everything-claude-code.git /tmp/everything-claude-code
mkdir -p "$HOME/.claude/rules"
cp -r /tmp/everything-claude-code/rules/common/* "$HOME/.claude/rules/"
cp -r /tmp/everything-claude-code/rules/typescript/* "$HOME/.claude/rules/"
rm -rf /tmp/everything-claude-code


# --- GSD ---

Expand Down
Loading