Skip to content

Ship a status line in the Claude image - #35

Merged
CrypticSwarm merged 1 commit into
masterfrom
claude-default-statusline
Aug 4, 2026
Merged

Ship a status line in the Claude image#35
CrypticSwarm merged 1 commit into
masterfrom
claude-default-statusline

Conversation

@CrypticSwarm

Copy link
Copy Markdown
Owner

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 ~/.claude first.

make build_claude copies anvil/statusline.sh into 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/opencode is bind-mounted from CLAUDE_HOME_DIR at run time, so anything the image puts under ~/.claude is masked. Claude also has no settings layer below the user's own settings.json, so the default has to be written into that file.

anvil/seed_claude_settings.py does 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 own statusLine keeps it, and a settings.json the seeder cannot parse is left exactly as it is rather than replaced.

Note this means an existing CLAUDE_HOME_DIR that already has a statusLine keeps it — the default only reaches sessions that had none.

The script and the seeder are copied into the claude-runtime stage 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 a statusLine a 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.

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.
@CrypticSwarm
CrypticSwarm merged commit 7fb73bb into master Aug 4, 2026
3 checks passed
@CrypticSwarm
CrypticSwarm deleted the claude-default-statusline branch August 4, 2026 05:24
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