Files
software-mansion__argent/scripts/download-simulator-server.sh
filip131311 b835de2326 fix(packaging): ship one shared copy of the Android screen-sharing agent (#983)
## Summary

Fixes the biggest chunk of #980: the published package shipped **four
byte-identical copies** of the Android screen-sharing agent
(`resources/android/`: jar + per-ABI `.so`, ~12.7 MiB each) — one next
to each platform's simulator-server binary, because the binary resolves
the agent relative to its working directory and the spawn set cwd to the
per-platform dir.

This ships **one shared copy** at `bin/resources/android/` and points
the spawn cwd at the bin root instead.

Package size (built from this branch, same artifact set as 0.22.1):

|  | before | after |
|---|---|---|
| unpacked | 115.5 MB | **76.4 MB** |
| packed | 37.6 MB | 25.4 MB |

76.4 MB is under npmmirror's 83886080-byte unpacked-size cap (the limit
#980 trips — note it applies to `dist.unpackedSize`, not the tarball).
Already-published oversized versions are immutable, so the mirror also
needs the `cnpm/unpkg-white-list` entry to sync the backlog; this PR
keeps future versions under the cap.

## Changes

- `scripts/download-simulator-server.sh` extracts the agent tarball
once, to `bin/resources/android/`, instead of next to each binary.
- `bundle-tools.cjs` copies that single shared directory into the
package.
- `@argent/native-devtools-ios` replaces `simulatorServerBinaryDir()`
with `simulatorServerRunDir()`: the bin root when the shared
`resources/android/` exists there, falling back to the per-platform dir
so an `ARGENT_SIMULATOR_SERVER_DIR` override pointing at a pre-dedup
layout keeps working.
- The blueprint spawns simulator-server with `cwd: RUN_DIR` (binary path
stays absolute; the agent lookup is the only cwd-relative path in the
simulator-server crate — audited: every other fs path there is a
tempdir, `dirs::cache_dir()`, or caller-supplied).

No symlinks, no postinstall scripts — plain files plus a different cwd,
so nothing changes for npm/pnpm/yarn/bun or Windows.

## Testing

- Unit: resolver tests updated + new shared-layout case; blueprint test
asserts the spawn cwd.
- Packaging: ran the modified download script + `npm run pack`
end-to-end; tarball contains exactly one `bin/resources/android/` (94
files vs 112).
- Live: branch tool-server with `ARGENT_SIMULATOR_SERVER_DIR` pointed at
the new layout — iOS simulator (screenshot) and Android emulator
(boot-device, screenshot, gesture-tap) green; `lsof` confirms both
spawned simulator-servers run with cwd = bin root, where
`resources/android/<jar>` and each per-ABI `.so` resolve (verified
present at those exact relative paths).
- Physical Android phone (Galaxy S24, the one path that actually pushes
the agent): live-tested — the `android_device` controller resolved the
agent from the shared layout, pushed it, and connected ("All agent
connections established successfully"); screenshot and tap through the
on-phone agent both green, spawn cwd confirmed as the shared bin root.

No docs update needed: internal packaging/layout only — no MCP tool,
CLI, config, or flow-file surface changes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_01UGAsAvYBJ3Jy9DKLaX9aoZ


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved simulator-server resource handling by using one shared
screen-sharing resource location across host platforms.
  * Added a warning when required shared resources are unavailable.
* Ensured simulator-server processes start from the correct runtime
directory.

* **Documentation**
  * Clarified simulator-server runtime and shared resource behavior.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-08-31 14:49:11 +02:00

130 lines
5.0 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
# Downloads simulator-server (argent variant) for every supported host platform
# into platform-keyed subdirectories of packages/native-devtools-ios/bin/ — the
# layout packages/argent/scripts/bundle-tools.cjs and the runtime resolver in
# @argent/native-devtools-ios both expect.
#
# Usage: ./scripts/download-simulator-server.sh [release-tag]
#
# Requires an authenticated gh CLI: the release repo is public, but
# `gh release download` still needs auth.
REPO="software-mansion-labs/simulator-server-releases"
TAG="${1:-radon-main}"
DEST_DIR="packages/native-devtools-ios/bin"
# release-asset-name → host platform key; the keys mirror hostPlatformKey() in
# @argent/native-devtools-ios so the resolver can look up by host.
declare -a TARGETS=(
"simulator-server-argent-macos:darwin"
"simulator-server-argent-linux:linux"
"simulator-server-argent-linux-arm64:linux-arm64"
"simulator-server-argent-windows.exe:win32"
)
mkdir -p "${DEST_DIR}"
for entry in "${TARGETS[@]}"; do
ASSET_NAME="${entry%%:*}"
PLATFORM="${entry##*:}"
PLATFORM_DIR="${DEST_DIR}/${PLATFORM}"
# Must match simulatorServerBinaryName() in the resolver and the dispatcher.
if [[ "${PLATFORM}" == "win32" ]]; then
BIN_BASENAME="simulator-server.exe"
else
BIN_BASENAME="simulator-server"
fi
# Purge first so a previous run's stale binary can't ship when this run's
# download fails and the branch below only warns and continues.
rm -rf "${PLATFORM_DIR}"
mkdir -p "${PLATFORM_DIR}"
echo "Downloading ${ASSET_NAME} → ${PLATFORM_DIR}/${BIN_BASENAME}"
# Tolerate missing assets so macOS-only consumers still work when another
# platform's artifact lags a release. Capture gh's stderr rather than
# discarding it: "not authenticated" vs "asset missing" vs "rate-limited".
GH_STDERR="$(mktemp)"
if ! gh release download "${TAG}" \
--repo "${REPO}" \
--pattern "${ASSET_NAME}" \
--dir "${PLATFORM_DIR}" \
--clobber 2>"${GH_STDERR}"; then
GH_MSG=$(<"${GH_STDERR}")
rm -f "${GH_STDERR}"
echo " ⚠ ${ASSET_NAME} not downloaded — skipping (binary won't be available on ${PLATFORM} hosts)"
[[ -n "${GH_MSG}" ]] && printf ' gh: %s\n' "${GH_MSG//$'\n'/$'\n gh: '}"
# Empty (purged above), so the dir disappears and the inventory stays clean.
rmdir "${PLATFORM_DIR}" 2>/dev/null || true
continue
fi
rm -f "${GH_STDERR}"
mv "${PLATFORM_DIR}/${ASSET_NAME}" "${PLATFORM_DIR}/${BIN_BASENAME}"
chmod +x "${PLATFORM_DIR}/${BIN_BASENAME}"
# A wrong-arch binary is worse than a missing one: the resolver picks it and
# the user gets ENOEXEC at spawn with no hint. Fail hard here, unlike the
# missing-asset case, because a mislabeled asset is an upstream packaging bug.
if command -v file >/dev/null 2>&1; then
DESC="$(file -b "${PLATFORM_DIR}/${BIN_BASENAME}")"
case "${PLATFORM}" in
darwin) EXPECT="Mach-O universal" ;;
linux) EXPECT="ELF 64-bit.*x86-64" ;;
linux-arm64) EXPECT="ELF 64-bit.*aarch64" ;;
win32) EXPECT="PE32\+.*x86-64" ;;
*) EXPECT="" ;;
esac
if [[ -n "${EXPECT}" ]] && ! [[ "${DESC}" =~ ${EXPECT} ]]; then
echo "✗ ${ASSET_NAME} has the wrong architecture for ${PLATFORM}:" >&2
echo " got: ${DESC}" >&2
echo " expected: ${EXPECT}" >&2
exit 1
fi
echo " ✓ arch ok: ${DESC}"
fi
done
echo ""
echo "Downloaded simulator-server binaries:"
find "${DEST_DIR}" \( -name simulator-server -o -name 'simulator-server.exe' \) -type f -exec ls -la {} \;
# The simulator-server `android_device` controller pushes the screen-sharing
# agent (host-independent .jar + per-ABI .so) to the phone over adb, resolving
# it from `resources/android/` relative to its working directory — which the
# blueprint sets to the bin root via simulatorServerRunDir(). The payload runs
# on the phone, so one shared copy serves every host platform.
# A missing asset is tolerated: physical-device support is then unavailable.
AGENT_ASSET="screen-sharing-agent.tar.gz"
AGENT_TMP="$(mktemp -d)"
echo ""
echo "Downloading ${AGENT_ASSET} (Android physical-device screen-sharing agent)"
GH_STDERR="$(mktemp)"
if gh release download "${TAG}" \
--repo "${REPO}" \
--pattern "${AGENT_ASSET}" \
--dir "${AGENT_TMP}" \
--clobber 2>"${GH_STDERR}"; then
rm -f "${GH_STDERR}"
res_dir="${DEST_DIR}/resources/android"
rm -rf "${res_dir}"
mkdir -p "${res_dir}"
tar -xzf "${AGENT_TMP}/${AGENT_ASSET}" -C "${res_dir}"
echo " ✓ screen-sharing agent → ${res_dir}"
else
GH_MSG=$(<"${GH_STDERR}")
rm -f "${GH_STDERR}"
echo " ⚠ ${AGENT_ASSET} not downloaded — physical Android device support will be unavailable"
[[ -n "${GH_MSG}" ]] && printf ' gh: %s\n' "${GH_MSG//$'\n'/$'\n gh: '}"
fi
rm -rf "${AGENT_TMP}"
# Only the macOS binary carries an Apple signature; codesign would noisily fail
# on the others.
if command -v codesign &>/dev/null && [[ -f "${DEST_DIR}/darwin/simulator-server" ]]; then
codesign -dvv "${DEST_DIR}/darwin/simulator-server" 2>&1 \
|| echo "Warning: macOS signature verification failed"
fi