Environment Skill
When to use this skill:
- You need to understand the environment architecture (for troubleshooting, modifications, or curiosity)
- You're modifying or extending the environment setup
- You encounter environment-related errors and need deeper context than error messages provide
When NOT to use this skill:
- Normal thesis work (build, test, commit) - error messages explain limitations
- You encounter a "local devcontainer only" error - the error message is sufficient
Environment Architecture
This project supports two environments:
1. Local Devcontainer (Jörn's machine)
- Defined by:
.devcontainer/Dockerfile, .devcontainer/devcontainer.json, scripts/devcontainer-post-create.sh
- What it does: Pre-installs all dependencies (TexLive, Rust, Python, Node.js, etc.) in a Docker image
- Special features:
- Bind mounts for cache persistence (
/srv/devhome/* → /home/vscode/*)
- Worktrees support (
/workspaces/worktrees for git worktree isolation)
- Shared Rust build cache via
CARGO_TARGET_DIR=/workspaces/worktrees/shared/target
2. Claude Code Web Environment
- Defined by: Ubuntu 24.04 base with pre-installed language runtimes (see Claude Code docs)
- What it does: Provides a clean environment accessible from anywhere via web browser
- What's pre-installed: Rust, Python (with uv), Node.js, Git, build-essential
- What's NOT pre-installed: TexLive, latexml
- Key difference: No devcontainer files run, no bind mounts, no worktrees directory
Critical limitation (known bug as of Jan 2026):
- apt-get does NOT work in web environment (DNS blocked by proxy architecture)
- See: GitHub issue #14538
- Consequence: TexLive cannot be installed, LaTeX builds are local-only
- What works: cargo, uv/pip, npm (HTTP proxy compatible)
- What doesn't work: apt-get, dpkg, any system packages
Dependency Installation
Progressive Disclosure Strategy
Level 1: Error messages explain the situation
- Build/lint scripts check for dependencies and print clear errors
- Example:
pdflatex not found (TexLive is local devcontainer only)
Level 2: This skill (understanding)
- Explains environment architecture
- Documents conventions for modifications
Level 3: Detailed implementation
- Devcontainer config files (
.devcontainer/*)
- Reference docs in
references/ subdirectory (if any)
What's Available Where
| Dependency |
Local Devcontainer |
Web Environment |
| TexLive (pdflatex, chktex) |
Pre-installed in Dockerfile |
NOT available (apt-get blocked) |
| latexml |
Pre-installed in Dockerfile |
NOT available (apt-get blocked) |
| Rust (cargo, rustc) |
Pre-installed |
Pre-installed |
| Python + uv |
Pre-installed |
Pre-installed |
| Python packages |
uv sync --extra dev |
uv sync --extra dev |
| gh CLI |
Pre-installed |
Auto-installed by .claude/hooks/web-env-setup.sh |
Conventions for Modifying Environments
When you need to add dependencies or modify environment setup:
1. Document with Progressive Disclosure
- CLAUDE.md: Add one-line note to Environment Dependencies section
- This skill: Explain architecture changes if significant
- Config files: Keep comments factual, avoid speculation
2. Install Script Conventions
If you create install scripts:
- Make scripts idempotent (check before installing)
- Print helpful messages about time/disk usage
- Support
--help flag
- Point build/lint scripts to install script in error messages
3. Never Make False Claims
- Future agents will believe documentation literally
- Example: Don't call a 2GB install "slim"
- Example: Don't say "everywhere" when you mean "in local devcontainer"
- When uncertain, be explicit about what you don't know
4. Keep It Simple (KISS)
- Follow standard patterns (cargo, npm, pip/uv; apt-get in local only)
- Don't over-engineer for hypothetical future requirements
- Don't add noise to config files that agents don't need
5. Maintain Both Environments
- Local devcontainer: Bake dependencies into Dockerfile when reasonable
- Web environment: Only cargo/uv/npm work (no apt-get due to DNS bug)
- Test changes in both environments (or document what's untested)
6. DRY - Don't Repeat Yourself
- Information should live in ONE canonical place
- Link to that place rather than duplicating
- Exception: Error messages can repeat key info (like "local devcontainer only") for convenience
Common Tasks
Detecting Which Environment You're In
# Web environment has this variable
if [[ -n "${CLAUDE_CODE_REMOTE:-}" ]]; then
echo "Running in web environment"
else
echo "Running in local environment (or other)"
fi
Adding a New Dependency
For Python packages (works in both environments):
- Add to
packages/python_viterbo/pyproject.toml
- Run
uv sync --extra dev
For system dependencies (local devcontainer only):
- Add to
.devcontainer/Dockerfile
- Update build scripts to fail gracefully with clear error in web environment
- Update CLAUDE.md: Add one line to Environment Dependencies section
Fixing Environment-Specific Issues
Example: Rust builds depend on CARGO_TARGET_DIR=/workspaces/worktrees/shared/target in local, but that dir doesn't exist in web.
Approach:
- Identify the constraint (worktrees mount only exists in local)
- Make it environment-aware (unset CARGO_TARGET_DIR in web, or create dir)
- Document the difference in this skill if non-obvious
- Test both environments
Files to Read
.devcontainer/Dockerfile - What's baked into local devcontainer image
.devcontainer/devcontainer.json - Local devcontainer configuration
scripts/devcontainer-post-create.sh - Local environment initialization
.claude/CLAUDE.md - Top-level environment guidance for agents
1---2name: environment3description: Understanding and maintaining the development environments for this thesis project. Use for environment architecture, troubleshooting, or modifying environment setup.4---5
6# Environment Skill
7
8**When to use this skill**:
9- You need to understand the environment architecture (for troubleshooting, modifications, or curiosity)
10- You're modifying or extending the environment setup
11- You encounter environment-related errors and need deeper context than error messages provide
12
13**When NOT to use this skill**:
14- Normal thesis work (build, test, commit) - error messages explain limitations
15- You encounter a "local devcontainer only" error - the error message is sufficient
16
17---
18
19## Environment Architecture
20
21This project supports two environments:
22
23### 1. Local Devcontainer (Jörn's machine)
24- **Defined by**: `.devcontainer/Dockerfile`, `.devcontainer/devcontainer.json`, `scripts/devcontainer-post-create.sh`
25- **What it does**: Pre-installs all dependencies (TexLive, Rust, Python, Node.js, etc.) in a Docker image
26- **Special features**:
27 - Bind mounts for cache persistence (`/srv/devhome/*` → `/home/vscode/*`)
28 - Worktrees support (`/workspaces/worktrees` for git worktree isolation)
29 - Shared Rust build cache via `CARGO_TARGET_DIR=/workspaces/worktrees/shared/target`
30
31### 2. Claude Code Web Environment
32- **Defined by**: Ubuntu 24.04 base with pre-installed language runtimes (see Claude Code docs)
33- **What it does**: Provides a clean environment accessible from anywhere via web browser
34- **What's pre-installed**: Rust, Python (with uv), Node.js, Git, build-essential
35- **What's NOT pre-installed**: TexLive, latexml
36- **Key difference**: No devcontainer files run, no bind mounts, no worktrees directory
37
38**Critical limitation (known bug as of Jan 2026):**
39- apt-get does NOT work in web environment (DNS blocked by proxy architecture)
40- See: [GitHub issue #14538](https://github.com/anthropics/claude-code/issues/14538)
41- **Consequence**: TexLive cannot be installed, LaTeX builds are local-only
42- **What works**: cargo, uv/pip, npm (HTTP proxy compatible)
43- **What doesn't work**: apt-get, dpkg, any system packages
44
45---
46
47## Dependency Installation
48
49### Progressive Disclosure Strategy
50
51**Level 1: Error messages explain the situation**
52- Build/lint scripts check for dependencies and print clear errors
53- Example: `pdflatex not found (TexLive is local devcontainer only)`
54
55**Level 2: This skill (understanding)**
56- Explains environment architecture
57- Documents conventions for modifications
58
59**Level 3: Detailed implementation**
60- Devcontainer config files (`.devcontainer/*`)
61- Reference docs in `references/` subdirectory (if any)
62
63### What's Available Where
64
65| Dependency | Local Devcontainer | Web Environment |
66|------------|-------------------|-----------------|
67| TexLive (pdflatex, chktex) | Pre-installed in Dockerfile | NOT available (apt-get blocked) |
68| latexml | Pre-installed in Dockerfile | NOT available (apt-get blocked) |
69| Rust (cargo, rustc) | Pre-installed | Pre-installed |
70| Python + uv | Pre-installed | Pre-installed |
71| Python packages | `uv sync --extra dev` | `uv sync --extra dev` |
72| gh CLI | Pre-installed | Auto-installed by `.claude/hooks/web-env-setup.sh` |
73
74---
75
76## Conventions for Modifying Environments
77
78When you need to add dependencies or modify environment setup:
79
80### 1. Document with Progressive Disclosure
81- **CLAUDE.md**: Add one-line note to Environment Dependencies section
82- **This skill**: Explain architecture changes if significant
83- **Config files**: Keep comments factual, avoid speculation
84
85### 2. Install Script Conventions
86If you create install scripts:
87- Make scripts idempotent (check before installing)
88- Print helpful messages about time/disk usage
89- Support `--help` flag
90- Point build/lint scripts to install script in error messages
91
92### 3. Never Make False Claims
93- Future agents will believe documentation literally
94- Example: Don't call a 2GB install "slim"
95- Example: Don't say "everywhere" when you mean "in local devcontainer"
96- When uncertain, be explicit about what you don't know
97
98### 4. Keep It Simple (KISS)
99- Follow standard patterns (cargo, npm, pip/uv; apt-get in local only)
100- Don't over-engineer for hypothetical future requirements
101- Don't add noise to config files that agents don't need
102
103### 5. Maintain Both Environments
104- **Local devcontainer**: Bake dependencies into Dockerfile when reasonable
105- **Web environment**: Only cargo/uv/npm work (no apt-get due to DNS bug)
106- Test changes in both environments (or document what's untested)
107
108### 6. DRY - Don't Repeat Yourself
109- Information should live in ONE canonical place
110- Link to that place rather than duplicating
111- Exception: Error messages can repeat key info (like "local devcontainer only") for convenience
112
113---
114
115## Common Tasks
116
117### Detecting Which Environment You're In
118```bash
119# Web environment has this variable
120if [[ -n "${CLAUDE_CODE_REMOTE:-}" ]]; then
121 echo "Running in web environment"
122else
123 echo "Running in local environment (or other)"
124fi
125```
126
127### Adding a New Dependency
128
129**For Python packages** (works in both environments):
1301. Add to `packages/python_viterbo/pyproject.toml`
1312. Run `uv sync --extra dev`
132
133**For system dependencies** (local devcontainer only):
1341. Add to `.devcontainer/Dockerfile`
1352. Update build scripts to fail gracefully with clear error in web environment
1363. **Update CLAUDE.md**: Add one line to Environment Dependencies section
137
138### Fixing Environment-Specific Issues
139
140Example: Rust builds depend on `CARGO_TARGET_DIR=/workspaces/worktrees/shared/target` in local, but that dir doesn't exist in web.
141
142**Approach**:
1431. Identify the constraint (worktrees mount only exists in local)
1442. Make it environment-aware (unset CARGO_TARGET_DIR in web, or create dir)
1453. Document the difference in this skill if non-obvious
1464. Test both environments
147
148---
149
150## Files to Read
151
152- `.devcontainer/Dockerfile` - What's baked into local devcontainer image
153- `.devcontainer/devcontainer.json` - Local devcontainer configuration
154- `scripts/devcontainer-post-create.sh` - Local environment initialization
155- `.claude/CLAUDE.md` - Top-level environment guidance for agents