Skip to content

Commit 955be27

Browse files
committed
chore: keep extension descriptions and other useful devcontainer comments
Narrow the cleanup to comments that only repeat the line below them. Extension descriptions, the formatter hint, section headers and the explanatory comments return as they were on master.
1 parent 898b4f0 commit 955be27

11 files changed

Lines changed: 145 additions & 33 deletions

File tree

‎.claude/rules/devcontainer.md‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ paths:
1414

1515
## Comments
1616

17-
Comment only what the JSON can't say: a reason, a constraint, an issue number, or what a template adopter must change. A comment that restates the key below it (`// Show workspace folder name in window title` above `"window.title"`) is noise; leave it out.
17+
Skip a comment that only repeats the line below it in other words, such as `// Show workspace folder name in window title` above `"window.title"`. Extension descriptions are not that: they say what an extension ID does.
1818

1919
## node_modules Mount
2020

@@ -28,11 +28,12 @@ Always include to keep node_modules off the host:
2828

2929
## VS Code Extensions
3030

31-
Group by category with a header comment. No per-extension description: the ID names the extension.
31+
Group by category with header comments:
3232

3333
```jsonc
3434
"extensions": [
3535
// **Category Name**
36+
// Extension Description
3637
"publisher.extension-id"
3738
]
3839
```

‎.devcontainer/claude-sandbox/devcontainer.json‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,18 @@
3333
"bash": { "path": "bash", "icon": "terminal-bash" }
3434
},
3535
"extensions.ignoreRecommendations": true,
36+
// ── Formatter settings (customize per project) ──────────────────
37+
// Change "editor.defaultFormatter" to match your tooling:
38+
// Biome: "biomejs.biome" | Prettier: "esbenp.prettier-vscode"
39+
// OXC: "oxc.oxc-vscode" | None: remove these three settings
3640
"editor.formatOnSave": true,
3741
"editor.defaultFormatter": "oxc.oxc-vscode",
3842
"editor.codeActionsOnSave": {
3943
"source.fixAll": "explicit",
4044
"source.organizeImports": "explicit"
4145
},
4246
"window.title": "${localWorkspaceFolderBasename}",
47+
// Sandbox visual identity — Claude Dark theme with coral remote indicator
4348
"workbench.colorTheme": "Claude Dark",
4449
"workbench.colorCustomizations": {
4550
"statusBarItem.remoteBackground": "#C15F3C",

‎.devcontainer/claude-sandbox/init-firewall.sh‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ IFS=$'\n\t'
55
# 1. Extract Docker DNS info BEFORE any flushing
66
DOCKER_DNS_RULES=$(iptables-save -t nat | grep "127\.0\.0\.11" || true)
77

8+
# Flush existing rules and delete existing ipsets
89
iptables -F
910
iptables -X
1011
iptables -t nat -F
@@ -31,8 +32,10 @@ iptables -A INPUT -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT
3132
iptables -A INPUT -i lo -j ACCEPT
3233
iptables -A OUTPUT -o lo -j ACCEPT
3334

35+
# Create ipset with CIDR support
3436
ipset create allowed-domains hash:net
3537

38+
# Fetch GitHub IP ranges
3639
echo "Fetching GitHub IP ranges..."
3740
gh_ranges=$(curl -s https://api.github.com/meta)
3841
if [ -z "$gh_ranges" ]; then

‎.devcontainer/devcontainer.json‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,17 @@
1515
"vscode": {
1616
"extensions": [
1717
// **AI Agents**
18+
// Claude Code - AI assistant
1819
"anthropic.claude-code",
1920

2021
// **General**
22+
// YAML - YAML support (for workflows and docker-compose)
2123
"redhat.vscode-yaml",
24+
// Markdown Preview Github Styles - Markdown preview
2225
"bierner.markdown-preview-github-styles",
26+
// Markdown Preview Mermaid Support - Mermaid diagrams
2327
"bierner.markdown-mermaid",
28+
// Docker - Dockerfile support
2429
"ms-azuretools.vscode-docker"
2530
],
2631
"settings": {
@@ -30,13 +35,18 @@
3035
"bash": { "path": "bash", "icon": "terminal-bash" }
3136
},
3237
"extensions.ignoreRecommendations": true,
38+
// ── Formatter settings (customize per project) ──────────────────
39+
// Change "editor.defaultFormatter" to match your tooling:
40+
// Biome: "biomejs.biome" | Prettier: "esbenp.prettier-vscode"
41+
// OXC: "oxc.oxc-vscode" | None: remove these three settings
3342
"editor.formatOnSave": true,
3443
"editor.defaultFormatter": "oxc.oxc-vscode",
3544
"editor.codeActionsOnSave": {
3645
"source.fixAll": "explicit",
3746
"source.organizeImports": "explicit"
3847
},
3948
"window.title": "${localWorkspaceFolderBasename}",
49+
// Visual identity — Claude Dark theme with coral remote indicator
4050
"workbench.colorTheme": "Claude Dark",
4151
"workbench.colorCustomizations": {
4252
"statusBarItem.remoteBackground": "#C15F3C",

‎bun/.devcontainer/devcontainer.json‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,27 @@
1313

1414
"customizations": {
1515
"vscode": {
16+
// Use zsh as the default shell for better VS Code integration
1617
"settings": {
1718
"terminal.integrated.defaultProfile.linux": "zsh",
19+
// Suppress extension recommendation prompts (e.g., Container Tools in Codespaces)
1820
"extensions.ignoreRecommendations": true
1921
},
22+
// Add the IDs of extensions you want installed when the container is created.
2023
"extensions": [
2124
// **Claude Code**
2225
"anthropic.claude-code",
2326

2427
// **Bun**
2528
"oven.bun-vscode",
2629

30+
// Prettier - Code Formatter
2731
"esbenp.prettier-vscode",
2832

2933
// **Tailwind**
34+
// Tailwind CSS IntelliSense
3035
"bradlc.vscode-tailwindcss",
36+
// Tailwind Fold
3137
"stivo.tailwind-fold"
3238
]
3339
}

‎claude-bun/.devcontainer/devcontainer.json‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@
1818
"mounts": [
1919
// Keep node_modules out of a host machine
2020
"source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume",
21-
// zsh writes its history here (HISTFILE in the Dockerfile); the volume name is legacy.
21+
// Persist shell history between container rebuilds. zsh writes here
22+
// (HISTFILE in the Dockerfile); the volume name is legacy.
2223
"source=claude-code-bashhistory-${devcontainerId},target=/commandhistory,type=volume",
2324
"source=claude-code-config-${devcontainerId},target=/home/bun/.claude,type=volume"
2425
],
2526

2627
"customizations": {
2728
"vscode": {
29+
// Use zsh as the default shell for better VS Code integration
2830
"settings": {
2931
"terminal.integrated.defaultProfile.linux": "zsh",
3032
"terminal.integrated.profiles.linux": {
@@ -36,6 +38,7 @@
3638
"path": "zsh"
3739
}
3840
},
41+
// Suppress extension recommendation prompts (e.g., Container Tools in Codespaces)
3942
"extensions.ignoreRecommendations": true,
4043
"editor.formatOnSave": true,
4144
"editor.defaultFormatter": "biomejs.biome",
@@ -44,6 +47,7 @@
4447
"source.organizeImports.biome": "explicit"
4548
}
4649
},
50+
// Add the IDs of extensions you want installed when the container is created.
4751
"extensions": [
4852
// **Claude Code**
4953
"anthropic.claude-code",
@@ -52,10 +56,13 @@
5256
"oven.bun-vscode",
5357

5458
// **Code Quality**
59+
// Biome - Fast formatter and linter for JavaScript/TypeScript
5560
"biomejs.biome",
5661

5762
// **Tailwind**
63+
// Tailwind CSS IntelliSense
5864
"bradlc.vscode-tailwindcss",
65+
// Tailwind Fold
5966
"stivo.tailwind-fold"
6067
]
6168
}

‎claude-code/.devcontainer/claude-sandbox/devcontainer.json‎

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@
44
"dockerComposeFile": "docker-compose.yml",
55
"service": "devcontainer",
66
"workspaceFolder": "/workspace",
7-
// initializeCommand: see the default variant.
7+
// Pull the prebuilt image on the HOST before the build, so "Rebuild Without
8+
// Cache" always layers on the freshest base. Replaces `pull_policy: always` in
9+
// docker-compose.yml, which breaks on Linux/WSL2 when `updateRemoteUserUID`
10+
// builds a local-only image (issue #109). `|| exit 0` keeps offline/outage opens
11+
// working (valid in POSIX sh and Windows cmd.exe). Keep in sync with the compose image.
812
"initializeCommand": "docker pull ghcr.io/gatezh/devcontainers/claude-code-sandbox:latest || exit 0",
9-
// For the iptables firewall.
13+
// Capabilities required for iptables firewall setup
1014
"capAdd": ["NET_ADMIN", "NET_RAW"],
1115
"init": true,
1216
"updateRemoteUserUID": true,
@@ -16,42 +20,59 @@
1620
"vscode": {
1721
"extensions": [
1822
// **AI Agents**
23+
// Claude Code - AI coding assistant with chat, inline edits, and terminal integration
1924
"anthropic.claude-code",
2025

2126
// **Runtime**
27+
// Bun - Bun runtime support (debugging, lockfile viewer, bundler integration)
2228
"oven.bun-vscode",
2329

2430
// **Code Quality**
31+
// OXC - Fast linter and formatter for JavaScript/TypeScript (Rust-based)
2532
"oxc.oxc-vscode",
2633

2734
// **Tailwind**
35+
// Tailwind CSS IntelliSense - autocomplete, syntax highlighting, linting for Tailwind classes
2836
"bradlc.vscode-tailwindcss",
37+
// Tailwind Fold - collapse long Tailwind class strings in the editor for readability
2938
"stivo.tailwind-fold",
3039

3140
// **General**
41+
// YAML - YAML language support (for workflows and docker-compose)
3242
"redhat.vscode-yaml",
43+
// Markdown Preview Github Styles - renders Markdown preview with GitHub's CSS
3344
"bierner.markdown-preview-github-styles",
45+
// Markdown Preview Mermaid Support - renders Mermaid diagrams in Markdown preview
3446
"bierner.markdown-mermaid",
47+
// Docker - Dockerfile and Compose syntax, linting, and image management
3548
"ms-azuretools.vscode-docker",
3649

3750
// **Spelling**
51+
// Code Spell Checker - catches typos in code and comments
3852
"streetsidesoftware.code-spell-checker",
3953

4054
// **JavaScript / TypeScript**
55+
// npm IntelliSense - autocomplete npm imports in import statements
4156
"christian-kohler.npm-intellisense",
57+
// TypeScript Error Translator - human-readable TS error messages
4258
"mattpocock.ts-error-translator",
4359

4460
// **CSS / Colors**
61+
// Color Info - preview CSS colors on hover
4562
"bierner.color-info",
63+
// Colorize - visualize CSS colors inline in the editor
4664
"kamikillerto.vscode-colorize",
4765

4866
// **Frameworks**
67+
// Drizzle ORM Snippets - code snippets for Drizzle ORM
4968
"drizzle-team.drizzle-orm-snippets",
5069

5170
// **Testing**
71+
// Playwright - run, debug, and generate Playwright tests from VS Code
5272
"ms-playwright.playwright",
5373

5474
// **Sandbox Theme**
75+
// Claude Theme - provides "Claude Dark" referenced by workbench.colorTheme
5576
"SamiHindi.claude-theme-sami-hindi"
5677
],
5778
"settings": {
@@ -68,7 +89,7 @@
6889
"source.organizeImports": "explicit"
6990
},
7091
"window.title": "${localWorkspaceFolderBasename}",
71-
// Tells a sandbox window apart from the default variant at a glance.
92+
// Sandbox visual identity — Claude Dark theme with coral remote indicator
7293
"workbench.colorTheme": "Claude Dark",
7394
"workbench.colorCustomizations": {
7495
"statusBarItem.remoteBackground": "#C15F3C",
@@ -78,35 +99,46 @@
7899
}
79100
}
80101
},
81-
// Volume names end in ${localWorkspaceFolderBasename} so the default and sandbox
82-
// variants share them. Replace "myproject" with your project name in both variants.
102+
// Named volumes keep node_modules OFF the host machine and persist across rebuilds.
103+
// Uses ${localWorkspaceFolderBasename} so default and sandbox variants share volumes.
104+
// Replace "myproject" with your project name (must match across both variants).
83105
"mounts": [
84-
// Every workspace with a package.json needs its own node_modules volume, or
85-
// node_modules lands in the bind mount and shows up on the host.
106+
// ── node_modules isolation (one per workspace) ─────────────────────
107+
// Each workspace with a package.json needs its own volume mount.
108+
// Without one, node_modules lands in the bind mount and shows up on the host.
86109
"source=myproject-node-modules-root-${localWorkspaceFolderBasename},target=/workspace/node_modules,type=volume",
110+
// ── Monorepo: uncomment and customize for your structure ──────────
87111
// "source=myproject-node-modules-api-${localWorkspaceFolderBasename},target=/workspace/services/api/node_modules,type=volume",
88112
// "source=myproject-node-modules-web-${localWorkspaceFolderBasename},target=/workspace/apps/web/node_modules,type=volume",
113+
// ── Persistent config ──────────────────────────────────────────────
89114
"source=myproject-claude-config-${localWorkspaceFolderBasename},target=/home/node/.claude,type=volume",
90115
"source=myproject-zsh-history-${localWorkspaceFolderBasename},target=/commandhistory,type=volume",
116+
// gh CLI auth/state (~/.config/gh/hosts.yml) — keeps `gh auth login` across rebuilds
91117
"source=myproject-gh-config-${localWorkspaceFolderBasename},target=/home/node/.config/gh,type=volume",
92-
// The image has iptables, ipset and the sudo rule but not the script: each project
93-
// mounts its own, with its own domain allowlist.
118+
// ── Firewall script ────────────────────────────────────────────────
119+
// The image provides iptables/ipset packages and sudo rule but NOT the script itself.
120+
// Each project provides its own script via bind mount to customize the domain allowlist.
94121
"source=${localWorkspaceFolder}/.devcontainer/claude-sandbox/init-firewall.sh,target=/usr/local/bin/init-firewall.sh,type=bind"
95122
],
96123
"containerEnv": {
97124
"TZ": "${localEnv:TZ:America/Edmonton}",
98125
"DEVCONTAINER": "true",
99126
"NODE_OPTIONS": "--max-old-space-size=4096",
100127
"CLAUDE_CONFIG_DIR": "/home/node/.claude",
101-
// Only needed without the default variant, whose sign-in lands on the shared
102-
// ~/.claude volume. See "Sandbox Authentication" in the README.
128+
// Optional — only needed when the sandbox is used without the default variant, whose
129+
// sign-in lands on the shared ~/.claude volume. Resolves to "" when the host var is
130+
// unset. See "Sandbox Authentication" section in README.
103131
"CLAUDE_CODE_OAUTH_TOKEN": "${localEnv:CLAUDE_CODE_OAUTH_TOKEN}"
104132
},
105-
// Plugins install here, before postStartCommand brings the firewall up (which is also
106-
// why Chromium comes from the image). The chowns are the same safety net as in the
107-
// default variant.
133+
// The find command chowns all node_modules volume mount points in one pass.
134+
// Chromium is baked into the sandbox image (firewall blocks runtime install).
135+
// bun install and init-plugins.sh are skipped when their file is absent. Plugins
136+
// install here, before postStartCommand brings the firewall up.
108137
"postCreateCommand": "sudo find /workspace -maxdepth 4 -name node_modules -type d -exec chown node {} + && sudo chown -R node /home/node/.claude /commandhistory /home/node/.config/gh && mise install && if [ -f package.json ]; then bun install; fi && if [ -f .devcontainer/init-plugins.sh ]; then bash .devcontainer/init-plugins.sh; fi",
109-
// patch-playwright-mcp: see the default variant.
138+
// Firewall init (bind-mounted from project) + re-patch the Playwright MCP
139+
// plugin's .mcp.json. The patch is defense in depth alongside the SessionStart
140+
// hook in /etc/claude-code/managed-settings.json, which handles the case where
141+
// the plugin auto-updates mid-container-run. See issues #85, #87, #98.
110142
"postStartCommand": "sudo /usr/local/bin/init-firewall.sh && /usr/local/bin/patch-playwright-mcp",
111143
"waitFor": "postStartCommand"
112144
}

0 commit comments

Comments
 (0)