Skip to content

feat(devcontainer): default Claude to max effort and keep more state - #55

Merged
amiralis1365 merged 4 commits into
mainfrom
feat/devcontainer-baseline
Oct 22, 2026
Merged

amiralis1365 merged 4 commits into
mainfrom
feat/devcontainer-baseline

Conversation

@amiralis1365

@amiralis1365 amiralis1365 commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Closes #56.

Summary

  • Claude Code starts every session at max effort. containerEnv sets CLAUDE_CODE_EFFORT_LEVEL=max, because the settings file's effortLevel accepts only low to xhigh and quietly drops max. The variable outranks /effort for the session, so start a lighter one as CLAUDE_CODE_EFFORT_LEVEL=auto claude.
  • A rebuild keeps more. Shell and REPL history (musher-${devcontainerId}-shell-history, wired into zsh and bash by base_setup_shell_history) and the download caches (musher-${devcontainerId}-cache at ~/.cache) join the gh, Claude and Codex logins on per-container volumes (DEVC-08).
  • gh logs in by itself, and git pushes through it. New canonical lib/github-auth.sh:
    • post-create calls github_auth_seed, which stores a token from the host's exported GH_TOKEN (MUSHER_HOST_GH_TOKEN) and writes no git config.
    • A new post-attach.sh calls ensure_github_auth. If gh still has no token, it asks VS Code's forwarded credential helper. Then it clears the helper lines the host's .gitconfig brought for the host's own gh, and runs gh auth setup-git.
    • The split matters. VS Code copies the host's ~/.gitconfig only after post-create, and only when none exists (.gitconfig not copied to remote container microsoft/vscode-remote-release#6810). Its forwarded helper arrives at the same moment. A gh auth setup-git in post-create, as the copies in platform, platform-api, host-agent and host-images run today, creates the file first, and the developer's name and email never arrive.
  • lib/npm-registry.sh ships beside it, for repositories that install @musher-dev/* from GitHub Packages. The template itself doesn't use it.
    • npm_registry_setup never prompts and skips a token without read:packages.
    • npm_registry_auth backs a repo's task setup:registry.
    • In a codespace it writes a ${GITHUB_TOKEN} reference, so the token never goes stale.
  • Docs (docs/configuration.md, README):
    • Git Config, GitHub Credentials and Shell History.
    • The volumes a rebuild keeps, and how to reset one: on the host, because inside the container docker reaches Docker-in-Docker's daemon.
    • Effort, the post-attach hook, and the Directory Map.
  • Corrections:
    • Git config is copied by the VS Code extension, after post-create, not "auto-forwarded by the devcontainer CLI".
    • Stack data survives a rebuild: the docker-in-docker Feature keeps /var/lib/docker and /var/lib/containerd on volumes of its own.
    • The commented dind-data mount said otherwise; it is replaced by that explanation and a commented node_modules example.
  • Also: the Claude Code VS Code extension.

This is the pilot of one dev-container baseline across every musher-dev repository that has a dev container, one PR each. The two scripts in lib/ are the canonical copies those PRs copy verbatim. First consumer: musher-dev/platform-backstage#114, CI green; it also ran a rebuild that kept its volumes and an end-to-end test with the real gh.

Test plan

  • task lint (markdownlint, yamllint, actionlint, codespell).
  • repo check: layout, paths, env, ports, hooks, comments (CMT-01/03).
  • The .repo tests: 45 passed.
  • conventions check --fail-on warning at the pinned 0.8.0: no findings.
  • shellcheck -x --source-path=SCRIPTDIR over every .devcontainer script: clean.
  • devcontainer read-configuration: the merged mounts include the Feature's dind-var-lib-docker-${devcontainerId} and dind-var-lib-containerd-${devcontainerId}.
  • Both libraries, against a stubbed gh and a scratch HOME:
    • Seeding creates no ~/.gitconfig.
    • On attach it clears a host-copied helper, seeds from a forwarded helper, wires gh, and keeps user.name/user.email and VS Code's own helper.
    • An env token (Codespaces) is left alone.
    • A refused token is logged and non-fatal.
    • A token without read:packages skips the registry, and npm_registry_auth asks for the scope.
    • ~/.npmrc is written 0600, with no temp file left behind.
  • Fresh-volume devcontainer up in docker-in-docker (no credentials passed in):
    • post-create, post-start and post-attach all ran. Each logged the non-fatal "no GitHub credential reached the container yet" line.
    • CLAUDE_CODE_EFFORT_LEVEL=max.
    • Every new mount, and ~/.local, is owned by vscode.
    • Exactly one history line per rc file, and interactive zsh sees the new HISTFILE.
    • No ~/.gitconfig after create and attach.
    • verify-toolchain.sh (CI's runCmd) passed.
  • CI green: Lint, Repo Structure, Conventions, ShellCheck, Compose Config, Dev Container Lockfiles and Devcontainer Build.

🤖 Generated with Claude Code

Every Claude Code session starts at max effort: CLAUDE_CODE_EFFORT_LEVEL
in containerEnv, since the settings file's effortLevel has no "max".

A rebuild now keeps shell and REPL history and the download caches, on
musher-${devcontainerId}-shell-history and -cache (DEVC-08), beside the
gh, Claude and Codex logins it already kept.

gh logs in by itself and git's github.com credential points at it, from
the canonical lib/github-auth.sh that every repository copies verbatim.
post-create only seeds a token (base_setup_github_seed); the git wiring
runs in a new post-attach hook, because VS Code copies the host's
~/.gitconfig only after post-create and only when none exists, so
writing one earlier costs the developer their name and email.

lib/npm-registry.sh ships beside it for repositories that install
@musher-dev/* from GitHub Packages; the template itself does not use it.

Docs: what a rebuild keeps and how to reset a volume (on the host:
inside, docker reaches Docker-in-Docker's daemon); the effort default;
the git config copy, which is VS Code's and happens after post-create;
and that stack data does survive a rebuild, in the docker-in-docker
Feature's own volumes. Commented examples for a node_modules volume,
Codespaces repository access and hostRequirements, and the Claude Code
extension.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@amiralis1365
amiralis1365 requested a review from a team as a code owner October 21, 2026 18:19
amiralis1365 and others added 2 commits October 21, 2026 21:32
Codespaces settings are out of scope for this baseline, so the commented
hostRequirements and customizations.codespaces examples go.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The awk line prints each volume's mount root, .../volumes/<name>/_data,
not a bare name; say so, so the reset steps read right.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Docker refuses to remove a volume that any container still uses, even a
stopped one, so the steps remove the container first. Listing the mounts
with docker inspect on the host gives the names directly.

Co-Authored-By: Claude Opus 5.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.

Start Claude at max effort, seed gh and keep history and caches across rebuilds

1 participant