Ship a status line in the Claude image - #35
Merged
Conversation
A container now starts with the model, directory, turn count, context percentage, and session token/cost totals on screen, rather than each host having to install a status line into its own ~/.claude first. Claude has no settings layer below ~/.claude/settings.json, so the default has to be written into that file. The entrypoint seeds it after the config layers merge and only when no layer set statusLine, so a layer that picked its own status line keeps it, and settings the seeder cannot parse are left untouched rather than replaced. The script and the seeder are copied into the claude-runtime stage alone; the shared entrypoint skips the seed when either is missing, so the OpenCode image is unchanged.
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.
A Claude container now starts with the model, directory, turn count, context percentage, and session token/cost totals on screen, instead of every host having to install a status line into its own
~/.claudefirst.make build_claudecopiesanvil/statusline.shinto the image at/usr/local/bin/swarmforge-statusline, and the entrypoint turns it on.Why a seeder rather than a settings.json in the image
/home/opencodeis bind-mounted fromCLAUDE_HOME_DIRat run time, so anything the image puts under~/.claudeis masked. Claude also has no settings layer below the user's ownsettings.json, so the default has to be written into that file.anvil/seed_claude_settings.pydoes that after the config layers have merged, and only for a key no layer set. That keeps the precedence the layers already have: a layer that chose its ownstatusLinekeeps it, and asettings.jsonthe seeder cannot parse is left exactly as it is rather than replaced.Note this means an existing
CLAUDE_HOME_DIRthat already has astatusLinekeeps it — the default only reaches sessions that had none.The script and the seeder are copied into the
claude-runtimestage alone; the shared entrypoint skips the seed when either path is missing, so the OpenCode image is unchanged.Tests
make test(489 tests) passes. New coverage:scripts/test_seed_claude_settings.py— the seeder creates a missing file, leaves other settings alone, keeps astatusLinea config layer set, is a no-op on re-run, and refuses to overwrite settings it cannot parse.scripts/test_image_layout.py— the paths the Dockerfile installs the script and the seeder to are the paths the entrypoint names. A mismatch there is silent: the entrypoint skips the seed and Claude just comes up without a status line.The image build itself is not covered by the suite; it was verified by rebuilding and confirming both files land in the image.