Repository navigation
fix(claude-code): fix template lifecycle wiring and persist gh config - #165
Merged
Merged
Conversation
…gh config The default template set "waitFor": "postCreateCommand" but defined no postCreateCommand, so init-plugins.sh never ran for consumers who copied the template verbatim, despite the README, script header and Dockerfile comments all assuming it did. Wire it in. The sandbox variant appends it to its existing postCreateCommand, which runs before postStartCommand brings the firewall up, so marketplace/plugin installs still have network. bun install fails without a package.json, which aborted the rest of the lifecycle for static or not-yet-scaffolded projects. Skip it until one exists (updateContentCommand in default, postCreateCommand in sandbox). gh stores auth in ~/.config/gh/hosts.yml on the ephemeral layer, so every rebuild logged the user out. Add a shared myproject-gh-config volume to both variants, extend the chown safety net to it, and pre-create the mount point node-owned in the image so Docker seeds a fresh volume correctly (otherwise Docker creates the missing dir as root). CI and post-build verify now assert that ownership. Fixes #107 Fixes #114
…ommand The previous commit wired init-plugins.sh into the default variant's postCreateCommand (#107 option a). That is the configuration #58 removed: before #58 the repo-root default ran init-plugins.sh from postCreateCommand with waitFor already set, and claude CLI calls there raced the Claude Code extension's OAuth sign-in and corrupted auth state. Apply #107 option (b) to the default variant instead: drop the dangling waitFor (its default, updateContentCommand, is correct) and document running the script once after sign-in. The sandbox keeps the script in postCreateCommand, matching the repo-root sandbox, now guarded so a consumer without the optional script doesn't fail container creation.
Missed by #163: the variant summary still said the token must be injected from the host.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fixes three problems in the
claude-codetemplate's lifecycle config:waitForbun installfailing without apackage.jsonghlogin being lost on every rebuildWhy
"waitFor": "postCreateCommand"but nopostCreateCommand. The README, theinit-plugins.shheader and a Dockerfile comment all said to putinit-plugins.shthere.bun installexits 1 without apackage.json, which aborts the remaining lifecycle commands for static or not-yet-scaffolded projects.ghkeeps its credentials in~/.config/gh/hosts.yml, which sits on the ephemeral container layer. Every rebuild logged the user out, unlike~/.claude, which is on a volume.Changes
devcontainer.json:waitFor. Its default,updateContentCommand, is correct.bun installwithif [ -f package.json ].devcontainer.json: the samebun installguard, plusinit-plugins.sh(if present) at the end ofpostCreateCommand. That runs beforepostStartCommandbrings up the firewall, matching the repo-root sandbox.myproject-gh-config-${localWorkspaceFolderBasename}volume at/home/node/.config/gh, shared between the variants by name./home/node/.config/gh, owned by node, next to the other mount points. Docker then seeds a fresh volume with node ownership instead of root. Checked by experiment: without this the mount comes up root-owned.ci.yml,build-claude-code.yml): assertsstat -c %U /home/node/.config/ghisnodefor both variants.init-plugins.shheader: document the gh volume and howinit-plugins.shruns in each variant.Notes
init-plugins.shintopostCreateCommand, is exactly the setup fix(devcontainer): theme, login, node_modules isolation, self-contained claude-code config #58 removed. Before 6c72403 the repo-root default raninit-plugins.shfrompostCreateCommandwithwaitFor: postCreateCommandalready set. TheclaudeCLI calls raced the Claude Code extension's OAuth sign-in and corrupted auth state. So the default variant now says "runbash .devcontainer/init-plugins.shonce after signing in", which is also what the repo-root default says. The branch's first commit tried (a); the second reverts that part, with the reasoning in its message.postCreateCommand, because interactive OAuth can't run behind its firewall anyway.bun installguard exits 0 in an empty dir and runsbun installwhen apackage.jsonexists (tested inclaude-code:latest).hadolintv2.12.0 (CI's version),actionlintandshellcheckall pass.docker buildof the image (deb.debian.orgwas unreachable from this host's Docker), and a live VS Code create/rebuild. CI's build and verify steps are the first real test of the Dockerfile change.node_modulesdirs" note in claude-code template: waitFor points at an undefined postCreateCommand, and updateContentCommand's unguarded bun install breaks package.json-less consumers #107 is out of scope.Fixes #107
Fixes #114