Skip to content

Conversation

@vncntt
Copy link

@vncntt vncntt commented Jan 14, 2026

Summary

  • Add fallback to existing Docker images when devcontainer build fails
  • Automatically install Claude if not found in container
  • Sync Claude config (settings, plugins) from host to container

Problem

  1. Build failures: The devcontainer CLI's --additional-features generates a Dockerfile-with-features that breaks SSH agent forwarding. This causes builds to fail for repos with private git dependencies.

  2. Cached images: When using cached images, the claude-code feature isn't applied, so Claude isn't installed.

  3. Config not syncing: The claude-config-mount feature doesn't work when features aren't applied. User settings like model: opus aren't transferred, and plugins don't work because their paths point to host locations.

Changes

Build failure fallback

  • Detect when devcontainer up fails
  • Find existing Docker image for the workspace (named vsc-<workspace>-*)
  • Start container directly from existing image with workspace mounted

Manual Claude installation

  • After container starts, check if Claude is available
  • If not found, install via curl -fsSL https://claude.ai/install.sh | bash

Config sync

  • Copy ~/.claude.json (authentication state)
  • Copy ~/.claude/settings.json (user preferences)
  • Copy plugins with path translation:
    • installed_plugins.json: Replace host paths with container paths
    • known_marketplaces.json: Replace host paths with container paths
    • Copy marketplaces/ and cache/ directories
  • Fix permissions after docker cp (files are copied as root)

PATH handling

  • Check both PATH and ~/.local/bin for Claude detection
  • Launch claude with PATH including ~/.local/bin

Test plan

  • Test on a devcontainer that fails to build (SSH issues)
  • Verify fallback to existing image works
  • Test on a devcontainer without Claude installed
  • Verify config sync transfers settings (e.g., model: opus is preserved)
  • Verify plugins work in container

Note

This PR includes PATH handling changes that overlap with PR #1. If PR #1 is merged first, this PR will need rebasing. Alternatively, this PR can be merged independently as it includes all necessary fixes.

🤖 Generated with Claude Code

This PR adds robustness improvements for ccind:

1. Build failure fallback:
   - When devcontainer up fails (often due to SSH agent forwarding issues
     with Dockerfile-with-features), ccind now looks for an existing Docker
     image and starts a container directly from it
   - This handles the common case where the image was previously built but
     rebuilding fails due to SSH issues

2. Manual Claude installation:
   - If Claude Code isn't found in the container (common with cached images),
     ccind automatically installs it using the official install script
   - No more manual intervention needed

3. Config sync from host:
   - Copies ~/.claude.json (authentication state)
   - Copies ~/.claude/settings.json (user preferences like model selection)
   - Copies plugins with path translation (host paths -> container paths)
   - Fixes file permissions after docker cp (copies as root, chowns to user)

4. PATH handling for Claude:
   - Check both PATH and ~/.local/bin when detecting Claude
   - Launch claude with PATH set correctly

Note: This PR includes changes that overlap with PR pipmc#1 (PATH handling).
If PR pipmc#1 is merged first, this PR will need rebasing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@vncntt
Copy link
Author

vncntt commented Jan 14, 2026

Code Review

Found 2 critical issues that need to be fixed before merging:

Issue 1: Missing --additional-features in start_devcontainer() (Bug)

The refactored start_devcontainer() function does not include --additional-features "$ADDITIONAL_FEATURES", meaning the Claude Code feature and config mount feature will never be installed via devcontainer features.

Location: bin/ccind L175-183

Current code:

start_devcontainer() {
    if [ "$REBUILD" = true ]; then
        echo_info "Starting devcontainer (forcing rebuild)..."
        devcontainer up --workspace-folder "$WORKSPACE" --remove-existing-container 2>&1
    else
        echo_info "Starting devcontainer..."
        devcontainer up --workspace-folder "$WORKSPACE" 2>&1
    fi
}

Fix: Add --additional-features "$ADDITIONAL_FEATURES" to both devcontainer up calls:

start_devcontainer() {
    if [ "$REBUILD" = true ]; then
        echo_info "Starting devcontainer (forcing rebuild)..."
        devcontainer up --workspace-folder "$WORKSPACE" --remove-existing-container --additional-features "$ADDITIONAL_FEATURES" 2>&1
    else
        echo_info "Starting devcontainer..."
        devcontainer up --workspace-folder "$WORKSPACE" --additional-features "$ADDITIONAL_FEATURES" 2>&1
    fi
}

Issue 2: Version mismatch - referencing non-existent version (CLAUDE.md compliance)

The PR references claude-config-mount:0.1.6 in bin/ccind but the actual version in src/claude-config-mount/devcontainer-feature.json is 0.1.5. This will cause runtime failures when users try to pull a version that doesn't exist.

Location: bin/ccind L48

Fix: Update src/claude-config-mount/devcontainer-feature.json to bump version from 0.1.5 to 0.1.6.


Checked for bugs and CLAUDE.md compliance.

The refactored start_devcontainer() function was missing the
--additional-features argument, which meant the Claude Code feature
and config mount feature were never installed via the devcontainer
feature mechanism.

Also reverted config-mount feature version to 0.1.5 (the currently
published version) to avoid "feature not found" errors.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
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