diff --git a/scripts/qwen-sbx.sh b/scripts/qwen-sbx.sh new file mode 100755 index 0000000..0330a88 --- /dev/null +++ b/scripts/qwen-sbx.sh @@ -0,0 +1,47 @@ +#!/usr/bin/env bash +# Start a docker-sbx "shell" sandbox for this repo, seed it with (almost) the +# host's whole ~/.qwen config, install the local MCP servers it references, +# and run qwen-code in it. Pass a prompt as args, or nothing for interactive. +set -euo pipefail + +SANDBOX=qwen-sbx +REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +QWEN_VERSION=0.23.1 +CONTAINER_HOME=/home/agent +NETWORK_HOSTS="proxy-ai.haylan.de,astro.dev,*.astro.dev,astro.build,*.astro.build,mcp.docs.astro.build" # model provider + Astro docs/sites/MCP + +if ! sbx ls --format '{{.Name}}' 2>/dev/null | grep -qx "$SANDBOX"; then + sbx create shell "$REPO_DIR" --name "$SANDBOX" + sbx exec "$SANDBOX" -- npm install -g "@qwen-code/qwen-code@$QWEN_VERSION" + + stage="$(mktemp -d)" + trap 'rm -rf "$stage"' EXIT + # Only drop genuinely disposable local history/logs; everything else + # (extensions, mcp-servers, skills, hooks, settings...) comes along. + rsync -a \ + --exclude 'projects' --exclude 'sessions' --exclude 'debug' \ + --exclude 'tmp' --exclude 'usage' --exclude 'usage_record.jsonl' \ + --exclude 'file-history' \ + "$HOME/.qwen/" "$stage/" + # settings.json hardcodes host absolute paths (/home/haylan/...) for local + # MCP servers; rewrite to the container's home so they resolve there too. + sed -i "s#$HOME/#$CONTAINER_HOME/#g" "$stage/settings.json" + + # sbx cp chokes on directories with many small files ("closed pipe"); tar + # to one file locally and extract server-side to dodge that entirely. + tar -C "$stage" -czf "$stage.tar.gz" . + sbx cp "$stage.tar.gz" "$SANDBOX:$CONTAINER_HOME/qwen-config.tar.gz" + sbx exec "$SANDBOX" -- bash -lc "mkdir -p \$HOME/.qwen && tar -C \$HOME/.qwen -xzf \$HOME/qwen-config.tar.gz && rm \$HOME/qwen-config.tar.gz" + + # codebase-memory-mcp (github.com/DeusData/codebase-memory-mcp) is a + # statically-linked binary outside ~/.qwen; same arch as the sandbox, so + # just ship the compiled binary rather than rebuilding it in-container. + sbx exec "$SANDBOX" -- mkdir -p "$CONTAINER_HOME/.local/bin" + sbx cp "$HOME/.local/bin/codebase-memory-mcp" "$SANDBOX:$CONTAINER_HOME/.local/bin/codebase-memory-mcp" + sbx exec "$SANDBOX" -- chmod +x "$CONTAINER_HOME/.local/bin/codebase-memory-mcp" + + sbx policy allow network --sandbox "$SANDBOX" "$NETWORK_HOSTS" +fi + +# -y: headless qwen refuses shell/web tool calls otherwise; the sandbox is the safety boundary. +sbx exec "$SANDBOX" -- qwen -y "$@"