Skip to content

claude-code template: plugins added to init-plugins.sh never reach existing containers unless the script is run by hand #171

Description

@gatezh

Problem

Since #58 the default variant has no postCreateCommand: the claude CLI calls in init-plugins.sh raced the extension's OAuth sign-in, so the template now expects users to run bash .devcontainer/init-plugins.sh once after signing in. The only pointer is a comment in devcontainer.json.

In practice a project picks up a template update, for example the new cloudflare@cloudflare plugin and its MCP server, and rebuilds. After the rebuild:

  • ~/.claude is a persistent volume, so the container still has whatever plugins an earlier run installed.
  • Nothing runs the new init-plugins.sh, so new marketplaces and plugins are silently missing.
  • claude mcp list shows no new servers, and nothing tells the user why.

The sandbox variant doesn't have this problem, because it still runs the script in postCreateCommand.

Proposal

Run init-plugins.sh automatically once sign-in has already happened, which is exactly when the #58 race can't occur.

postStartCommand could start it in the background, guarded on the credentials file, before the Playwright MCP patch:

"postStartCommand": "if [ -f \"$CLAUDE_CONFIG_DIR/.credentials.json\" ] && [ -f .devcontainer/init-plugins.sh ]; then (bash .devcontainer/init-plugins.sh > /tmp/init-plugins.log 2>&1; /usr/local/bin/patch-playwright-mcp) & else /usr/local/bin/patch-playwright-mcp; fi"
  • Rebuilds of an already signed-in project: plugins install or update on start. Logs go to /tmp/init-plugins.log.
  • First start, not signed in yet: nothing runs during sign-in, so the behaviour is unchanged from today. The next start picks it up.
  • Order: the Playwright MCP patch runs after the install/update, because an update can rewrite the plugin's .mcp.json.

An alternative is a SessionStart hook in managed-settings.json. It would compare the installed plugins with the list in init-plugins.sh and either run the script or print a one-line reminder. It fires only in a signed-in session, so it avoids the race by design.

Acceptance

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions