Skip to content

Commit 6c3325a

Browse files
lroolleclaude
andcommitted
feat(build): selective tool upgrade + dedicated cctrace layer
cctrace ships faster than everything else; upgrading it should not cost a full-manifest re-resolve or a full image rebuild. - version-upgrade.sh --only tool[,tool] / ONLY= env: selected tools get latest, everything else folds into the pinned pathway via versions.env (manifest shows them as pinned; no downstream changes needed) - make versions-up ONLY=cctrace passthrough - install-agent-tooling.sh DEVA_TOOLING_STAGE=agents|cctrace|all - both Dockerfiles: cctrace gets its own RUN with ARG+LABEL declared adjacent. ARGs poison the cache of every later RUN when changed; declared early, a cctrace bump rebuilt the whole npm layer (and the rust image's Playwright layer). Now it rebuilds one small layer. Closes #419 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent 6216c0d commit 6c3325a

6 files changed

Lines changed: 93 additions & 11 deletions

File tree

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## [Unreleased]
99

1010
### Added
11+
- Selective tool upgrade: `make versions-up ONLY=cctrace` upgrades one
12+
tool (comma list supported) while everything else stays pinned to
13+
versions.env (#419)
14+
- cctrace installs in its own Docker layer in both images, with its ARG
15+
declared adjacent — a cctrace-only bump no longer rebuilds the npm
16+
agent layer or (rust image) the Playwright layer (#419)
1117
- `--trace` for codex and grok via cctrace client profiles (#418).
1218
`deva codex -- --trace exec "..."` / `deva grok -- --trace -p "..."`
1319
wrap the agent with `cctrace <client> --no-open --`; always MITM capture

Dockerfile

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,12 @@ FROM agent-base AS final
209209

210210
# Declare ARGs immediately before usage to minimize cache invalidation
211211
ARG CLAUDE_CODE_VERSION=2.1.143
212-
ARG CCTRACE_VERSION=0.11.0
213212
ARG CODEX_VERSION=0.131.0
214213
ARG GEMINI_CLI_VERSION=0.42.0
215214
ARG GROK_CLI_VERSION=0.2.93
216215

217216
# Record key tool versions as labels for quick inspection
218217
LABEL org.opencontainers.image.claude_code_version=${CLAUDE_CODE_VERSION}
219-
LABEL org.opencontainers.image.cctrace_version=${CCTRACE_VERSION}
220218
LABEL org.opencontainers.image.codex_version=${CODEX_VERSION}
221219
LABEL org.opencontainers.image.gemini_cli_version=${GEMINI_CLI_VERSION}
222220
LABEL org.opencontainers.image.grok_cli_version=${GROK_CLI_VERSION}
@@ -228,7 +226,15 @@ LABEL org.opencontainers.image.ccx_version=${CCX_VERSION}
228226
COPY --chown=deva:deva scripts/install-agent-tooling.sh /tmp/install-agent-tooling.sh
229227

230228
RUN --mount=type=cache,target=/home/deva/.npm,uid=${DEVA_UID},gid=${DEVA_GID},sharing=locked \
231-
bash /tmp/install-agent-tooling.sh && \
229+
DEVA_TOOLING_STAGE=agents bash /tmp/install-agent-tooling.sh
230+
231+
# cctrace moves fast: own ARG + layer, declared here so a pin bump
232+
# rebuilds only this layer, not the npm agent layer above.
233+
ARG CCTRACE_VERSION=0.11.0
234+
LABEL org.opencontainers.image.cctrace_version=${CCTRACE_VERSION}
235+
236+
RUN --mount=type=cache,target=/home/deva/.npm,uid=${DEVA_UID},gid=${DEVA_GID},sharing=locked \
237+
DEVA_TOOLING_STAGE=cctrace bash /tmp/install-agent-tooling.sh && \
232238
rm -f /tmp/install-agent-tooling.sh
233239

234240
USER root

Dockerfile.rust

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ LABEL org.opencontainers.image.title="deva-rust"
99
LABEL org.opencontainers.image.description="Rust development environment with full toolchain"
1010

1111
ARG CLAUDE_CODE_VERSION=2.1.143
12-
ARG CCTRACE_VERSION=0.11.0
1312
ARG CODEX_VERSION=0.131.0
1413
ARG GEMINI_CLI_VERSION=0.42.0
1514
ARG GROK_CLI_VERSION=0.2.93
@@ -20,7 +19,6 @@ ARG RUST_DEFAULT_TOOLCHAIN="stable"
2019
ARG RUST_TARGETS="wasm32-unknown-unknown"
2120

2221
LABEL org.opencontainers.image.claude_code_version=${CLAUDE_CODE_VERSION}
23-
LABEL org.opencontainers.image.cctrace_version=${CCTRACE_VERSION}
2422
LABEL org.opencontainers.image.codex_version=${CODEX_VERSION}
2523
LABEL org.opencontainers.image.gemini_cli_version=${GEMINI_CLI_VERSION}
2624
LABEL org.opencontainers.image.grok_cli_version=${GROK_CLI_VERSION}
@@ -115,8 +113,7 @@ USER $DEVA_USER
115113
COPY --chown=deva:deva scripts/install-agent-tooling.sh /tmp/install-agent-tooling.sh
116114

117115
RUN --mount=type=cache,target=/home/deva/.npm,uid=${DEVA_UID},gid=${DEVA_GID},sharing=locked \
118-
bash /tmp/install-agent-tooling.sh && \
119-
rm -f /tmp/install-agent-tooling.sh
116+
DEVA_TOOLING_STAGE=agents bash /tmp/install-agent-tooling.sh
120117

121118
# Install Playwright + both chromium binaries. Runs after install-agent-tooling.sh
122119
# so npm prefix ($DEVA_HOME/.npm-global) is already configured. System deps are
@@ -148,6 +145,15 @@ RUN --mount=type=cache,target=/home/deva/.npm,uid=${DEVA_UID},gid=${DEVA_GID},sh
148145
test -d "$(find "$PLAYWRIGHT_BROWSERS_PATH" -maxdepth 1 -type d -name 'chromium_headless_shell-*' -print -quit)" && \
149146
npm cache clean --force
150147

148+
# cctrace moves fast: own ARG + layer, declared last among the tool layers
149+
# so a pin bump rebuilds only this, not npm tooling or playwright above.
150+
ARG CCTRACE_VERSION=0.11.0
151+
LABEL org.opencontainers.image.cctrace_version=${CCTRACE_VERSION}
152+
153+
RUN --mount=type=cache,target=/home/deva/.npm,uid=${DEVA_UID},gid=${DEVA_GID},sharing=locked \
154+
DEVA_TOOLING_STAGE=cctrace bash /tmp/install-agent-tooling.sh && \
155+
rm -f /tmp/install-agent-tooling.sh
156+
151157
USER root
152158

153159
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ versions-up:
247247
RUST_IMAGE=$(RUST_IMAGE) \
248248
DOCKERFILE=$(DOCKERFILE) \
249249
RUST_DOCKERFILE=$(RUST_DOCKERFILE) \
250+
ONLY=$(ONLY) \
250251
$(VERSION_QUERY_OVERRIDES) \
251252
./scripts/version-upgrade.sh
252253

@@ -406,6 +407,7 @@ help:
406407
@echo " toolchains List pinned toolchains and managed build tools"
407408
@echo " versions Compare built vs latest versions with changelogs"
408409
@echo " versions-up Build both images with latest upstream agent versions"
410+
@echo " ONLY=cctrace upgrades one tool, rest stay pinned"
409411
@echo " versions-pin Refresh $(VERSION_PINS_FILE) from upstream"
410412
@echo " scripts List repo helper scripts"
411413
@echo " commands Alias for help"
@@ -458,3 +460,4 @@ help:
458460
@echo " make versions # Check current versions"
459461
@echo " make PLAYWRIGHT_VERSION=1.60.0 build-rust # Override rust browser tooling"
460462
@echo " make versions-up # Upgrade to latest upstream versions"
463+
@echo " make versions-up ONLY=cctrace # Upgrade just cctrace, rest pinned"

scripts/install-agent-tooling.sh

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -315,12 +315,29 @@ install_cctrace() {
315315
log "cctrace installed"
316316
}
317317

318+
# DEVA_TOOLING_STAGE splits installs across Docker layers so fast-moving
319+
# tools (cctrace) can bump without busting the big npm layer.
318320
main() {
319321
ensure_safe_cwd
320-
log "Installing shared agent tooling into $DEVA_HOME"
321-
install_npm_agent_tooling
322-
install_ccx
323-
install_cctrace
322+
local stage="${DEVA_TOOLING_STAGE:-all}"
323+
log "Installing shared agent tooling into $DEVA_HOME (stage: $stage)"
324+
case "$stage" in
325+
agents)
326+
install_npm_agent_tooling
327+
install_ccx
328+
;;
329+
cctrace)
330+
install_cctrace
331+
;;
332+
all)
333+
install_npm_agent_tooling
334+
install_ccx
335+
install_cctrace
336+
;;
337+
*)
338+
die "unknown DEVA_TOOLING_STAGE: $stage (agents|cctrace|all)"
339+
;;
340+
esac
324341
}
325342

326343
main "$@"

scripts/version-upgrade.sh

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,14 @@ Usage: $(basename "$0") [OPTIONS]
5858
5959
Options:
6060
-y, --yes Skip confirmation countdown
61+
--only LIST Upgrade only these tools (comma-separated); the rest
62+
stay pinned to versions.env. Tools: claude-code,
63+
cctrace, codex, gemini-cli, grok-cli, ccx,
64+
copilot-api, playwright
6165
-h, --help Show this help
6266
6367
Environment:
68+
ONLY Same as --only (e.g. make versions-up ONLY=cctrace)
6469
MAIN_IMAGE Main image name (default: ghcr.io/thevibeworks/deva:latest)
6570
CORE_IMAGE Core image name (default: ghcr.io/thevibeworks/deva:core)
6671
RUST_IMAGE Rust image name (default: ghcr.io/thevibeworks/deva:rust)
@@ -76,16 +81,55 @@ Environment:
7681
EOF
7782
}
7883

84+
ONLY="${ONLY:-}"
85+
7986
while [[ $# -gt 0 ]]; do
8087
case $1 in
8188
-y|--yes) AUTO_YES=1; shift ;;
89+
--only) ONLY="${2:-}"; [[ -n $ONLY ]] || { echo "--only requires a tool list"; exit 1; }; shift 2 ;;
90+
--only=*) ONLY="${1#--only=}"; shift ;;
8291
-h|--help) usage; exit 0 ;;
8392
*) echo "Unknown option: $1"; usage; exit 1 ;;
8493
esac
8594
done
8695

96+
tool_selected() {
97+
[[ -z $ONLY ]] || [[ ",$ONLY," == *",$1,"* ]]
98+
}
99+
100+
# --only: fold every non-selected tool into the "pinned" pathway by
101+
# treating its versions.env pin as a CLI override. Downstream resolution,
102+
# manifest display, and build args need no changes.
103+
apply_only_filter() {
104+
[[ -n $ONLY ]] || return 0
105+
106+
local tool
107+
local known="claude-code cctrace codex gemini-cli grok-cli ccx copilot-api playwright"
108+
for tool in ${ONLY//,/ }; do
109+
case " $known " in
110+
*" $tool "*) ;;
111+
*) echo "error: unknown tool in --only: $tool" >&2
112+
echo "known: $known" >&2
113+
exit 1 ;;
114+
esac
115+
done
116+
117+
tool_selected claude-code || _CLI_CLAUDE_CODE="${_CLI_CLAUDE_CODE:-$CLAUDE_CODE_VERSION}"
118+
tool_selected cctrace || _CLI_CCTRACE="${_CLI_CCTRACE:-$CCTRACE_VERSION}"
119+
tool_selected codex || _CLI_CODEX="${_CLI_CODEX:-$CODEX_VERSION}"
120+
tool_selected gemini-cli || _CLI_GEMINI="${_CLI_GEMINI:-$GEMINI_CLI_VERSION}"
121+
tool_selected grok-cli || _CLI_GROK="${_CLI_GROK:-$GROK_CLI_VERSION}"
122+
tool_selected ccx || _CLI_CCX="${_CLI_CCX:-$CCX_VERSION}"
123+
tool_selected copilot-api || _CLI_COPILOT="${_CLI_COPILOT:-$COPILOT_API_VERSION}"
124+
tool_selected playwright || _CLI_PLAYWRIGHT="${_CLI_PLAYWRIGHT:-$PLAYWRIGHT_VERSION}"
125+
126+
echo "Selective upgrade: $ONLY (all other tools pinned to versions.env)"
127+
echo ""
128+
}
129+
87130
main() {
88131
load_version_pins
132+
apply_only_filter
89133

90134
echo -e "${CYAN}${BOLD}╔════════════════════════════════════════════════════╗${RESET}"
91135
echo -e "${CYAN}${BOLD}║ Upgrading to Latest Versions ║${RESET}"

0 commit comments

Comments
 (0)