From 535ca1a207a092a3ba4a11e353ed4962e86162db Mon Sep 17 00:00:00 2001 From: Lauro Frei Date: Wed, 29 Apr 2026 10:32:25 +0200 Subject: [PATCH 1/3] Install claude-code-ui from npm instead of vendored tarball Replaces the local .tgz artifact with a direct npm install of @cloudcli-ai/cloudcli@latest so each rebuild picks up the newest version automatically. Co-Authored-By: Claude Opus 4.6 --- Dockerfile | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/Dockerfile b/Dockerfile index 1532f56..7dc5822 100644 --- a/Dockerfile +++ b/Dockerfile @@ -167,14 +167,12 @@ RUN if [ "$VARIANT" = "full" ]; then \ npm i -g opencode-ai; \ fi -COPY vendor/artifacts/siteboon-claude-code-ui-1.26.3.tgz /tmp/vendor/siteboon-claude-code-ui-1.26.3.tgz - # ---------- CloudCLI (web UI for Claude Code) ---------- -RUN npm i -g /tmp/vendor/siteboon-claude-code-ui-1.26.3.tgz && rm -f /tmp/vendor/siteboon-claude-code-ui-1.26.3.tgz -RUN touch /usr/local/lib/node_modules/@siteboon/claude-code-ui/.env +RUN npm i -g @cloudcli-ai/cloudcli@latest +RUN touch /usr/local/lib/node_modules/@cloudcli-ai/cloudcli/.env # ---------- Patch: preserve WebSocket frame type in plugin proxy (Issue #11) ---------- -RUN CLOUDCLI_INDEX="/usr/local/lib/node_modules/@siteboon/claude-code-ui/server/index.js" && \ +RUN CLOUDCLI_INDEX="/usr/local/lib/node_modules/@cloudcli-ai/cloudcli/server/index.js" && \ grep -q "upstream.on('message', (data) =>" "$CLOUDCLI_INDEX" && \ sed -i "s/upstream.on('message', (data) => {/upstream.on('message', (data, isBinary) => {/" "$CLOUDCLI_INDEX" && \ sed -i "s/if (clientWs.readyState === WebSocket.OPEN) clientWs.send(data)/if (clientWs.readyState === WebSocket.OPEN) clientWs.send(data, { binary: isBinary })/" "$CLOUDCLI_INDEX" && \ @@ -184,42 +182,42 @@ RUN CLOUDCLI_INDEX="/usr/local/lib/node_modules/@siteboon/claude-code-ui/server/ echo "[patch] WARNING: WebSocket pattern not found in vendored CloudCLI install, skipping patch" # patch: preserve Shell tab scroll position across periodic refresh (issue #35) -RUN CLOUDCLI_BUNDLE="/usr/local/lib/node_modules/@siteboon/claude-code-ui/dist/assets/index-X3ImjnMV.js" && \ +RUN CLOUDCLI_BUNDLE="/usr/local/lib/node_modules/@cloudcli-ai/cloudcli/dist/assets/index-X3ImjnMV.js" && \ grep -q 'const B=()=>{v.current?.focus()}' "$CLOUDCLI_BUNDLE" && \ perl -pi -e 's/const B=\(\)=>\{v\.current\?\.focus\(\)\}/const B=()=>{const _vp=v.current?.buffer?.active?.viewportY??0;v.current?.focus();v.current?.scrollToLine(_vp)}/g' "$CLOUDCLI_BUNDLE" && \ echo "[patch] Shell scroll position fix applied" || \ echo "[patch] WARNING: Shell scroll pattern not found in vendored CloudCLI bundle, skipping patch" # patch v1.2.2-1: commands.js expose newModel in spawn args (issue #36) -RUN CLOUDCLI_COMMANDS="/usr/local/lib/node_modules/@siteboon/claude-code-ui/server/routes/commands.js" && \ +RUN CLOUDCLI_COMMANDS="/usr/local/lib/node_modules/@cloudcli-ai/cloudcli/server/routes/commands.js" && \ grep -q 'message: args.length > 0' "$CLOUDCLI_COMMANDS" && \ perl -pi -e 's/^(\s+)(message: args\.length > 0)/$1newModel: args.length > 0 ? args[0] : null,\n$1$2/' "$CLOUDCLI_COMMANDS" && \ echo "[patch] commands.js newModel field added" || \ echo "[patch] WARNING: commands.js newModel pattern not found, skipping patch" # patch v1.2.2-2: bundle expose setClaudeModel in claudeModel context spread (issue #36) -RUN CLOUDCLI_BUNDLE="/usr/local/lib/node_modules/@siteboon/claude-code-ui/dist/assets/index-X3ImjnMV.js" && \ +RUN CLOUDCLI_BUNDLE="/usr/local/lib/node_modules/@cloudcli-ai/cloudcli/dist/assets/index-X3ImjnMV.js" && \ grep -q 'claudeModel:W,codexModel:V' "$CLOUDCLI_BUNDLE" && \ perl -pi -e 's/\QclaudeModel:W,codexModel:V\E/claudeModel:W,setClaudeModel:L,codexModel:V/g' "$CLOUDCLI_BUNDLE" && \ echo "[patch] bundle setClaudeModel context spread applied" || \ echo "[patch] WARNING: bundle claudeModel:W pattern not found, skipping patch" # patch v1.2.2-3: bundle wire setClaudeModel:lS2 into cursorModel destructure (issue #36) -RUN CLOUDCLI_BUNDLE="/usr/local/lib/node_modules/@siteboon/claude-code-ui/dist/assets/index-X3ImjnMV.js" && \ +RUN CLOUDCLI_BUNDLE="/usr/local/lib/node_modules/@cloudcli-ai/cloudcli/dist/assets/index-X3ImjnMV.js" && \ grep -q 'cursorModel:o,claudeModel:l,codexModel:c' "$CLOUDCLI_BUNDLE" && \ perl -pi -e 's/\QcursorModel:o,claudeModel:l,codexModel:c\E/cursorModel:o,claudeModel:l,setClaudeModel:lS2,codexModel:c/g' "$CLOUDCLI_BUNDLE" && \ echo "[patch] bundle setClaudeModel:lS2 destructure applied" || \ echo "[patch] WARNING: bundle cursorModel destructure pattern not found, skipping patch" # patch v1.2.2-4: bundle apply newModel on SSE model event (issue #36) -RUN CLOUDCLI_BUNDLE="/usr/local/lib/node_modules/@siteboon/claude-code-ui/dist/assets/index-X3ImjnMV.js" && \ +RUN CLOUDCLI_BUNDLE="/usr/local/lib/node_modules/@cloudcli-ai/cloudcli/dist/assets/index-X3ImjnMV.js" && \ grep -q 'case"model":k({type:"assistant"' "$CLOUDCLI_BUNDLE" && \ perl -pi -e 's/\Qcase"model":k({type:"assistant"\E/case"model":me.newModel\&\&lS2\&\&(lS2(me.newModel),localStorage.setItem("claude-model",me.newModel));k({type:"assistant"/g' "$CLOUDCLI_BUNDLE" && \ echo "[patch] bundle SSE model event handler applied" || \ echo "[patch] WARNING: bundle case\"model\" pattern not found, skipping patch" # patch v1.2.2-5: bundle add custom model option to select (issue #36) -RUN CLOUDCLI_BUNDLE="/usr/local/lib/node_modules/@siteboon/claude-code-ui/dist/assets/index-X3ImjnMV.js" && \ +RUN CLOUDCLI_BUNDLE="/usr/local/lib/node_modules/@cloudcli-ai/cloudcli/dist/assets/index-X3ImjnMV.js" && \ grep -q 'children:N.OPTIONS.map(({value:C,label:j})=>s.jsx("option",{value:C,children:j},C+j))}' "$CLOUDCLI_BUNDLE" && \ perl -pi -e 's/\Qchildren:N.OPTIONS.map(({value:C,label:j})=>s.jsx("option",{value:C,children:j},C+j))}\E/children:[...N.OPTIONS.map(({value:C,label:j})=>s.jsx("option",{value:C,children:j},C+j)),!N.OPTIONS.some(C=>C.value===k)\&\&k\&\&s.jsx("option",{value:k,children:k},k+"custom")].filter(Boolean)}/g' "$CLOUDCLI_BUNDLE" && \ echo "[patch] bundle custom model select option applied" || \ From 53703568cbbd701ef4bf9be6409d2746a1ce122b Mon Sep 17 00:00:00 2001 From: Lauro Frei Date: Thu, 30 Apr 2026 21:24:36 +0200 Subject: [PATCH 2/3] Fix binary name for @cloudcli-ai/cloudcli package The new package exposes 'cloudcli' binary instead of 'claude-code-ui'. Update s6 service run script accordingly. Co-Authored-By: Claude Opus 4.6 --- s6-overlay/s6-rc.d/cloudcli/run | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/s6-overlay/s6-rc.d/cloudcli/run b/s6-overlay/s6-rc.d/cloudcli/run index 28ef00d..1c32ab0 100644 --- a/s6-overlay/s6-rc.d/cloudcli/run +++ b/s6-overlay/s6-rc.d/cloudcli/run @@ -3,4 +3,4 @@ cd /workspace export HOME=/home/claude export WORKSPACES_ROOT=/workspace export NODE_OPTIONS="${NODE_OPTIONS:+$NODE_OPTIONS }--no-deprecation" -exec s6-setuidgid claude claude-code-ui --port 3001 +exec s6-setuidgid claude cloudcli --port 3001 From 739455813835abe1a80f8a4835296d9f3bb2fb9c Mon Sep 17 00:00:00 2001 From: Lauro Frei Date: Thu, 30 Apr 2026 21:34:20 +0200 Subject: [PATCH 3/3] Update CHANGELOG with npm-based CloudCLI install Co-Authored-By: Claude Opus 4.6 --- docs/CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index f37fdb1..efdd170 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -4,6 +4,11 @@ All notable changes to HolyClaude will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/), and this project adheres to [Semantic Versioning](https://semver.org/). +## [Unreleased] + +### Changed +- CloudCLI is now installed directly from npm (`@cloudcli-ai/cloudcli@latest`) instead of a vendored tarball, so every image rebuild automatically picks up the latest version + ## [1.2.2] - 04/10/2026 ### Fixed