Skip to content

DevContainer performance optimizations#35

Merged
AnExiledDev merged 4 commits intomainfrom
worktree-perf-optimizations
Feb 27, 2026
Merged

DevContainer performance optimizations#35
AnExiledDev merged 4 commits intomainfrom
worktree-perf-optimizations

Conversation

@AnExiledDev
Copy link
Owner

@AnExiledDev AnExiledDev commented Feb 27, 2026

Summary

  • Comment out Rust toolchain + ccms — saves ~1.53 GB image size and ~127s build time. Rust/ccms can be re-enabled by uncommenting in devcontainer.json. Replacement tool for ccms pending.
  • Fix Bun PATH — Bun was installed but unreachable in non-interactive shells (scripts, Bash tool calls). Added /etc/profile.d/bun.sh via postStart hook. Updated to latest version (was pinned to 1.3.9).
  • npm cache cleanup — added npm cache clean --force to 6 features (agent-browser, ast-grep, biome, claude-session-dashboard, lsp-servers, tree-sitter). Saves ~96 MB runtime disk.
  • Documentation — updated 12 docs pages + CLAUDE.md to reflect Rust/ccms as opt-in/disabled.

Projected savings: ~1.53 GB image, ~127s build time, ~265 MB runtime disk.

Files changed (22)

Area Files Change
Core config devcontainer.json Comment out Rust + ccms features, update install order, bump Bun
Setup scripts/setup.sh Bun PATH fix via /etc/profile.d/bun.sh
Features (6) agent-browser, ast-grep, biome, claude-session-dashboard, lsp-servers, tree-sitter npm cache cleanup
Docs (12) Commands, tools, features, installation, architecture, etc. Mark ccms as disabled, Rust as opt-in
Meta CHANGELOG.md, CLAUDE.md Changelog entries, commands table update

Test plan

  • Container builds without Rust feature — which rustc should fail
  • which ccms should fail (expected — replacement pending)
  • bash -c 'which bun' succeeds in non-interactive shell; bun --version shows current version
  • After rebuild, du -sh /home/vscode/.npm/ shows minimal cache size
  • docker images shows image size reduction (target: ~6.9 GB, down from 8.5 GB)
  • No regressions: agent-browser --version, node --version, python3 --version all work

Summary by CodeRabbit

  • New Features

    • Dynamic port forwarding now covers all ports with user notification.
  • Bug Fixes

    • Fixed Bun PATH for non-interactive shells.
    • Added npm cache cleanup across multiple installers to reduce setup issues.
    • Improved session commit reminders and related tool hooks.
    • Updated Bun feature to use the latest version.
  • Documentation

    • Rust is now opt-in (disabled by default); ccms marked as disabled pending replacement.
    • Extensive updates to installation, getting-started, reference, and troubleshooting docs.

…n, clean npm cache

- Comment out Rust toolchain (~1.23 GB) and ccms (~301 MB) features — replacement
  tool for ccms pending; Rust can be re-enabled in devcontainer.json
- Fix Bun PATH for non-interactive shells via /etc/profile.d/bun.sh in setup.sh
- Update Bun feature to install latest version (was pinned to outdated 1.3.9)
- Add npm cache cleanup to 6 features (agent-browser, ast-grep, biome,
  claude-session-dashboard, lsp-servers, tree-sitter) — saves ~96 MB runtime disk
- Update 12 docs pages to reflect Rust/ccms as opt-in/disabled
- Update CLAUDE.md commands table and CHANGELOG.md

Projected savings: ~1.53 GB image, ~127s build time, ~265 MB runtime disk.
@coderabbitai
Copy link

coderabbitai bot commented Feb 27, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6c07263 and 1bc3bd6.

📒 Files selected for processing (1)
  • .devcontainer/scripts/setup.sh

📝 Walkthrough

Walkthrough

This PR comments out Rust and ccms in the DevContainer, bumps Bun to "latest", adds silent npm cache clean --force steps in multiple feature install scripts, adds a Bun PATH fix for non-interactive shells, and updates docs to mark ccms disabled and Rust/Go as opt-in.

Changes

Cohort / File(s) Summary
DevContainer config & changelog
.devcontainer/devcontainer.json, .devcontainer/CHANGELOG.md, .devcontainer/CLAUDE.md
Commented-out/removed Rust and ccms from feature lists and override order; updated Bun feature to include "version": "latest"; expanded changelog entries and marked ccms disabled in CLAUDE.
Install scripts — npm cache cleanup
.devcontainer/features/agent-browser/install.sh, .devcontainer/features/ast-grep/install.sh, .devcontainer/features/biome/install.sh, .devcontainer/features/claude-session-dashboard/install.sh, .devcontainer/features/lsp-servers/install.sh, .devcontainer/features/tree-sitter/install.sh
Inserted `npm cache clean --force 2>/dev/null
Setup script (Bun PATH fix)
.devcontainer/scripts/setup.sh
Added idempotent logic to symlink bun/bunx and create /etc/profile.d/bun.sh to export BUN_INSTALL and prepend its bin to PATH for non-interactive shells (guarded by Bun install dir existence).
Getting Started docs
docs/src/content/docs/getting-started/* (first-session.md, index.md, installation.md, requirements.md)
Updated installation order, expected tools, troubleshooting, and requirements: ccms marked disabled (replacement pending); Rust and Go documented as opt-in.
Features & tools docs
docs/src/content/docs/features/index.md, docs/src/content/docs/features/tools.md
Annotated ccms as "(currently disabled — replacement pending)"; marked Rust toolchain as opt-in/commented-out by default.
Reference & customization docs
docs/src/content/docs/reference/*, docs/src/content/docs/customization/* (architecture.md, commands.md, environment.md, index.md, configuration.md, rules.md)
Propagated status updates across architecture, commands, environment variable notes, and customization examples to reflect ccms disabled and Rust opt-in status.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

🐰
Rust takes a nap, ccms hides away,
Bun winks "latest" and clears crumbs of day,
Cache swept quiet, PATH set for the night,
Tiny fixes hop — everything runs light,
A rabbit twitches whiskers, then bounds away. 🥕

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'DevContainer performance optimizations' accurately and concisely summarizes the main change: optimizing devcontainer performance through feature toggling, caching, and path fixes.
Description check ✅ Passed The PR description comprehensively covers the required template sections: clear summary of changes, related files with context, type of change (maintenance/refactor), and a detailed test plan.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch worktree-perf-optimizations

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/src/content/docs/customization/configuration.md (1)

183-193: ⚠️ Potential issue | 🟡 Minor

Example code shows Rust as active, but it's now opt-in.

The example on line 187 includes "ghcr.io/devcontainers/features/rust:1.5.0" as an active feature, which contradicts the actual devcontainer.json where Rust is now commented out. Consider updating the example for consistency:

📝 Suggested fix
   "features": {
     "ghcr.io/devcontainers/features/node:1.7.1": { "version": "lts" },
-    "ghcr.io/devcontainers/features/rust:1.5.0": { "version": "latest" },
+    // "ghcr.io/devcontainers/features/rust:1.5.0": { "version": "latest" },  // Opt-in
     "ghcr.io/anthropics/devcontainer-features/claude-code:1.0.5": {},
     "./features/ruff": { "version": "latest" },
     // "./features/ccms": {}        // Currently disabled — replacement pending
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/src/content/docs/customization/configuration.md` around lines 183 - 193,
Update the example JSON so Rust is shown as opt-in (commented out) instead of
active: remove or comment out the "ghcr.io/devcontainers/features/rust:1.5.0"
entry in the features object (the string
"ghcr.io/devcontainers/features/rust:1.5.0" is the symbol to change) and, if
desired, add a brief inline comment like "// rust feature is opt-in" to mirror
the actual devcontainer.json and keep consistency with the other commented
example entries.
🧹 Nitpick comments (2)
.devcontainer/scripts/setup.sh (1)

165-174: Consider POSIX-compatible syntax for /etc/profile.d scripts.

The [[ ]] construct on line 169 is bash-specific. Scripts in /etc/profile.d/ are sourced by various shells (including /bin/sh on some systems), so POSIX-compatible syntax is safer:

♻️ Proposed POSIX-compatible fix
 sudo tee /etc/profile.d/bun.sh > /dev/null <<'BUNEOF'
 export BUN_INSTALL="/home/vscode/.bun"
-if [[ "${PATH}" != *"${BUN_INSTALL}/bin"* ]]; then
+case ":${PATH}:" in
+  *:"${BUN_INSTALL}/bin":*) ;;
+  *) export PATH="${BUN_INSTALL}/bin:${PATH}" ;;
+esac
-    export PATH="${BUN_INSTALL}/bin:${PATH}"
-fi
 BUNEOF
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/scripts/setup.sh around lines 165 - 174, The
/etc/profile.d/bun.sh snippet uses the bash-only [[ ]] test which can break
non-bash shells; update the heredoc content written by the setup script to use
POSIX-compatible syntax to check PATH (e.g., use a case pattern like case
":${PATH}:" in *":${BUN_INSTALL}/bin:"*) or a POSIX test/grep approach instead
of [[ ... ]], keeping the BUN_INSTALL variable and the PATH modification logic
otherwise identical so /etc/profile.d/bun.sh remains portable.
.devcontainer/CHANGELOG.md (1)

32-34: Good entry, minor improvement opportunity.

The Bun section follows the changelog guidelines with proper subheading organization under "Fixed." The problem is clearly described from the user's perspective ("Bun PATH not available in non-interactive shells").

The fix description includes some implementation detail ("via postStart hook"), but the overall entry is clear and useful. As per coding guidelines, you could make it slightly more user-focused by emphasizing the result rather than the mechanism (e.g., "— Bun is now available in all shell contexts" or "— fixed by ensuring PATH is configured system-wide").

Optional refinement for user perspective

If you want to be strictly user-focused per the guidelines:

 #### Bun
-- Bun PATH not available in non-interactive shells — added `/etc/profile.d/bun.sh` via postStart hook
+- Bun PATH not available in non-interactive shells — Bun is now accessible in all shell contexts

The current version is perfectly acceptable and provides useful context. This is only a suggestion for maximum alignment with the "user perspective, not implementation" guideline.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/CHANGELOG.md around lines 32 - 34, Update the "#### Bun"
changelog entry to be user-focused: replace the implementation-detail phrase
"added `/etc/profile.d/bun.sh` via postStart hook" with a result-oriented
description such as "Bun is now available in non-interactive shells" or "fixed
by ensuring Bun PATH is configured system-wide" while keeping the original
problem phrasing; locate the "#### Bun" heading in .devcontainer/CHANGELOG.md
and edit that line accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@docs/src/content/docs/customization/configuration.md`:
- Around line 183-193: Update the example JSON so Rust is shown as opt-in
(commented out) instead of active: remove or comment out the
"ghcr.io/devcontainers/features/rust:1.5.0" entry in the features object (the
string "ghcr.io/devcontainers/features/rust:1.5.0" is the symbol to change) and,
if desired, add a brief inline comment like "// rust feature is opt-in" to
mirror the actual devcontainer.json and keep consistency with the other
commented example entries.

---

Nitpick comments:
In @.devcontainer/CHANGELOG.md:
- Around line 32-34: Update the "#### Bun" changelog entry to be user-focused:
replace the implementation-detail phrase "added `/etc/profile.d/bun.sh` via
postStart hook" with a result-oriented description such as "Bun is now available
in non-interactive shells" or "fixed by ensuring Bun PATH is configured
system-wide" while keeping the original problem phrasing; locate the "#### Bun"
heading in .devcontainer/CHANGELOG.md and edit that line accordingly.

In @.devcontainer/scripts/setup.sh:
- Around line 165-174: The /etc/profile.d/bun.sh snippet uses the bash-only [[
]] test which can break non-bash shells; update the heredoc content written by
the setup script to use POSIX-compatible syntax to check PATH (e.g., use a case
pattern like case ":${PATH}:" in *":${BUN_INSTALL}/bin:"*) or a POSIX test/grep
approach instead of [[ ... ]], keeping the BUN_INSTALL variable and the PATH
modification logic otherwise identical so /etc/profile.d/bun.sh remains
portable.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 59438d4 and bc65519.

📒 Files selected for processing (22)
  • .devcontainer/CHANGELOG.md
  • .devcontainer/CLAUDE.md
  • .devcontainer/devcontainer.json
  • .devcontainer/features/agent-browser/install.sh
  • .devcontainer/features/ast-grep/install.sh
  • .devcontainer/features/biome/install.sh
  • .devcontainer/features/claude-session-dashboard/install.sh
  • .devcontainer/features/lsp-servers/install.sh
  • .devcontainer/features/tree-sitter/install.sh
  • .devcontainer/scripts/setup.sh
  • docs/src/content/docs/customization/configuration.md
  • docs/src/content/docs/customization/rules.md
  • docs/src/content/docs/features/index.md
  • docs/src/content/docs/features/tools.md
  • docs/src/content/docs/getting-started/first-session.md
  • docs/src/content/docs/getting-started/index.md
  • docs/src/content/docs/getting-started/installation.md
  • docs/src/content/docs/getting-started/requirements.md
  • docs/src/content/docs/reference/architecture.md
  • docs/src/content/docs/reference/commands.md
  • docs/src/content/docs/reference/environment.md
  • docs/src/content/docs/reference/index.md

- Use POSIX-compatible case/esac in /etc/profile.d/bun.sh (was bash-only [[]])
- Make changelog Bun entry user-focused (result over mechanism)
- Comment out Rust in docs configuration.md example to match devcontainer.json
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
.devcontainer/scripts/setup.sh (1)

166-173: Use $HOME instead of hardcoding /home/vscode in the Bun profile script for consistency.

The rest of setup.sh uses $HOME for user paths (Claude config, lines 23–74). The Bun section (line 166–168) breaks this pattern by hardcoding /home/vscode. Since postStartCommand runs as the remoteUser (vscode), $HOME already resolves correctly and is more portable if remoteUser changes.

Replace line 166–168:

if [ -d "/home/vscode/.bun/bin" ] && [ ! -f /etc/profile.d/bun.sh ]; then
    sudo tee /etc/profile.d/bun.sh > /dev/null <<'BUNEOF'
export BUN_INSTALL="/home/vscode/.bun"

With:

if [ -d "$HOME/.bun/bin" ] && [ ! -f /etc/profile.d/bun.sh ]; then
    sudo tee /etc/profile.d/bun.sh > /dev/null <<'BUNEOF'
export BUN_INSTALL="$HOME/.bun"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.devcontainer/scripts/setup.sh around lines 166 - 173, The Bun profile
script hardcodes /home/vscode instead of using the user's $HOME; update the
conditional and the BUN_INSTALL export so the if check that references the
.bun/bin directory and the BUN_INSTALL variable use $HOME (i.e., change the if [
-d "/home/vscode/.bun/bin" ] check and the export
BUN_INSTALL="/home/vscode/.bun" to use $HOME) while keeping the existing tee to
/etc/profile.d/bun.sh and the heredoc marker BUNEOF intact.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In @.devcontainer/scripts/setup.sh:
- Around line 166-173: The Bun profile script hardcodes /home/vscode instead of
using the user's $HOME; update the conditional and the BUN_INSTALL export so the
if check that references the .bun/bin directory and the BUN_INSTALL variable use
$HOME (i.e., change the if [ -d "/home/vscode/.bun/bin" ] check and the export
BUN_INSTALL="/home/vscode/.bun" to use $HOME) while keeping the existing tee to
/etc/profile.d/bun.sh and the heredoc marker BUNEOF intact.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc65519 and 29007f5.

📒 Files selected for processing (3)
  • .devcontainer/CHANGELOG.md
  • .devcontainer/scripts/setup.sh
  • docs/src/content/docs/customization/configuration.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • .devcontainer/CHANGELOG.md
  • docs/src/content/docs/customization/configuration.md

More portable if remoteUser changes. The single-quoted heredoc preserves
$HOME for expansion at source-time, which is the standard pattern for
/etc/profile.d/ scripts.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.devcontainer/scripts/setup.sh:
- Around line 166-175: The current install block only skips creating the profile
hook if the file exists, which leaves stale/broken content in the existing hook;
change the logic to be content-idempotent by computing the expected hook content
(using the same BUN_INSTALL, PATH manipulation and the BUNEOF template) and then
compare it against the current file contents and only write/overwrite when they
differ; implement this by generating the expected content into a temp file or
heredoc, using a content comparison (e.g., cmp/diff) against the existing hook
file and only run sudo tee and sudo chmod +x when the contents differ or the
file is missing, referencing the existing BUN_INSTALL/BUNEOF/PATH template in
the script so updates replace stale hooks.
- Around line 165-173: The /etc/profile.d/bun.sh approach doesn't cover
non-interactive shells; keep that file but also create a global executable
symlink so Bun is available regardless of shell type: detect
"$HOME/.bun/bin/bun" (and optionally related executables) and, if present and
not already linked, run sudo ln -s "$HOME/.bun/bin/bun" /usr/local/bin/bun (and
similar for bunx/bunw if needed); reference the existing /etc/profile.d/bun.sh
creation in this change and add the symlink logic immediately after it so all
execution contexts can find the bun binary.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 29007f5 and 6c07263.

📒 Files selected for processing (1)
  • .devcontainer/scripts/setup.sh

/etc/profile.d/ is only sourced by login shells — bash -c, container exec, and
CI jobs skip it. Add symlinks in /usr/local/bin for bun/bunx to cover all
execution contexts. Also make the profile hook content-idempotent so stale
content is corrected on upgrade.
@AnExiledDev AnExiledDev merged commit 862437e into main Feb 27, 2026
4 of 5 checks passed
@AnExiledDev AnExiledDev deleted the worktree-perf-optimizations branch February 27, 2026 03:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant