Skip to content

Commit c2064d4

Browse files
lroolleclaude
andcommitted
feat(name): embed agent CLI version in container names
deva--claude-v2.1.204--auth-file-max--proj..hash Persistent containers pin the image they were created from. When the image's CLI version moves, the old name matched and deva silently attached a stale CLI to the same mounted config home — state schema drift between CLI versions corrupts shared state. A version bump now produces a distinct name, so a fresh container is created and the stale one stays visible in deva ps. - version read from org.opencontainers.image.<agent>_version image label, cached per run; check_image guarantees the image exists locally before any name is built - label-less images keep the bare agent name (backward compatible) - ps parsing unaffected: the version lives inside the agent segment, segments still split on double dash Closes #420 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent ba30e5d commit c2064d4

2 files changed

Lines changed: 48 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Added
11+
- Container names embed the agent CLI version from the image label:
12+
`deva--claude-v2.1.204--auth-file-max--proj..hash`. Persistent
13+
containers pin old images; a CLI bump now creates a distinct container
14+
instead of silently attaching a stale CLI to the same config home.
15+
Label-less images keep the bare agent name (#420)
16+
1017
## [0.14.1] - 2026-07-13
1118

1219
### Added

deva.sh

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,41 @@ compute_shape_hash() {
929929
short_hash "$combined" 8
930930
}
931931

932+
# Agent CLI version from the image label. Persistent containers pin the
933+
# image they were created from; embedding the CLI version in the name keeps
934+
# version drift visible and stops silent attach to a stale-version container
935+
# sharing the same config home (#420). check_image runs before any name is
936+
# built, so the inspect is reliable; label-less images fall back to the
937+
# bare agent name.
938+
AGENT_VERSION_TAG_CACHE="__unset__"
939+
agent_version_tag() {
940+
local agent="$1"
941+
942+
if [ "$AGENT_VERSION_TAG_CACHE" != "__unset__" ]; then
943+
printf '%s' "$AGENT_VERSION_TAG_CACHE"
944+
return
945+
fi
946+
947+
local label=""
948+
case "$agent" in
949+
claude) label="org.opencontainers.image.claude_code_version" ;;
950+
codex) label="org.opencontainers.image.codex_version" ;;
951+
gemini) label="org.opencontainers.image.gemini_cli_version" ;;
952+
grok) label="org.opencontainers.image.grok_cli_version" ;;
953+
esac
954+
955+
local ver=""
956+
if [ -n "$label" ]; then
957+
ver=$(docker image inspect --format "{{ index .Config.Labels \"$label\" }}" "$(docker_image_ref)" 2>/dev/null | head -1)
958+
[ "$ver" = "<no value>" ] && ver=""
959+
# Container names allow [a-zA-Z0-9_.-]; drop anything else (keep dots)
960+
ver=$(printf '%s' "$ver" | tr -cd 'a-zA-Z0-9._-')
961+
fi
962+
963+
AGENT_VERSION_TAG_CACHE="$ver"
964+
printf '%s' "$ver"
965+
}
966+
932967
build_container_name() {
933968
local prefix="$1"
934969
local agent="$2"
@@ -938,7 +973,12 @@ build_container_name() {
938973
local ephemeral="${6:-false}"
939974
local pid="${7:-}"
940975

941-
local name="${prefix}--${agent}--${auth_tag}--${slug}..${shape_hash}"
976+
local agent_seg="$agent"
977+
local agent_ver
978+
agent_ver="$(agent_version_tag "$agent")"
979+
[ -n "$agent_ver" ] && agent_seg="${agent}-v${agent_ver}"
980+
981+
local name="${prefix}--${agent_seg}--${auth_tag}--${slug}..${shape_hash}"
942982
if [ "$ephemeral" = true ] && [ -n "$pid" ]; then
943983
name="${name}--${pid}"
944984
fi

0 commit comments

Comments
 (0)