FinalRun 0.1.8
⚠️ Upgrading from a previous npm installIf you previously installed via
npm install -g @finalrun/finalrun-agent, the npm-installed binary is still onPATHand shadows the new one at~/.finalrun/bin/finalrun. Symptom:finalrun --versionkeeps reporting an old version.Remove the npm version once, then the new binary takes over:
npm uninstall -g @finalrun/finalrun-agent hash -r # bust the shell's command cache which finalrun # should now be ~/.finalrun/bin/finalrun finalrun --version # should now be 0.1.8If
whichstill doesn't point at~/.finalrun/bin/finalrun, open a new terminal (so the PATH append in~/.bashrc/~/.zshrctakes effect) or run:export PATH="$PATH:$HOME/.finalrun/bin"This is a one-time cleanup — v0.1.8 is the first release that ships exclusively as a binary; from here on,
finalrun upgradekeeps the binary current.
Install
One command on macOS or Linux. No Node.js, no npm, nothing else required.
curl -fsSL https://raw.githubusercontent.com/final-run/finalrun-agent/main/scripts/install.sh | bashFor CI / non-interactive environments (binary only, no runtime tarball, no prompts):
curl -fsSL https://raw.githubusercontent.com/final-run/finalrun-agent/main/scripts/install.sh | bash -s -- --ciCI environments (CI=1) get this behavior automatically even without the flag.
Artifacts
| Platform | Binary | Runtime tarball |
|---|---|---|
| macOS Apple Silicon | finalrun-darwin-arm64 |
finalrun-runtime-<version>-darwin-arm64.tar.gz |
| macOS Intel | finalrun-darwin-x64 |
finalrun-runtime-<version>-darwin-x64.tar.gz |
| Linux x86_64 | finalrun-linux-x64 |
finalrun-runtime-<version>-linux-x64.tar.gz |
| Linux ARM64 | finalrun-linux-arm64 |
finalrun-runtime-<version>-linux-arm64.tar.gz |
Each artifact ships with a matching .sha256 sidecar.
Upgrading from a previous version
finalrun upgradeThe CLI re-runs the install script with sensible defaults (auto-detects whether you previously installed the runtime tarball, preserves your install directory).
What's changed in this release
Changed — distribution model
The CLI is no longer published to npm. It now ships as a self-contained Bun-compiled binary plus a per-platform runtime tarball, both uploaded to GitHub Releases. End users install via:
# Full local-dev setup (binary + runtime tarball + platform tools + skills)
curl -fsSL https://raw.githubusercontent.com/final-run/finalrun-agent/main/scripts/install.sh | bash
# CI / non-interactive (binary only)
curl -fsSL https://raw.githubusercontent.com/final-run/finalrun-agent/main/scripts/install.sh | bash -s -- --ciNo Node.js required. CI environments (auto-detected via CI=1) skip the interactive setup automatically even without the --ci flag.
Breaking — installer flags
The first cut of v0.1.8 shipped with --cloud-only and --full-setup flags plus TTY-detection that interacted badly with curl | bash (the script could hang mid-install when exec </dev/tty ran while bash was still reading the script body from the curl pipe). The flags have been simplified to a single --ci toggle and the script is now wrapped in a main() function so the redirect can never collide with bash's own script reading.
Migration:
| Old (will hard-error) | New |
|---|---|
bash -s -- --cloud-only |
bash -s -- --ci |
bash -s -- --full-setup |
bash (full is the default; drop the flag) |
Added
@finalrun/cloud-coreworkspace package: pure cloud-submission logic (zip + multipart POST, app upload), shared by the CLI binary@finalrun/local-runtimeworkspace package: builder for the per-platformfinalrun-runtime-<version>-<platform>.tar.gz(driver bundles, gRPC proto, Vite SPA dist) that ships alongside the binary on GitHub Releasesfinalrun upgradesubcommand: re-runs the install script with sensible defaults (auto-detects whether the runtime tarball was previously installed; preservesFINALRUN_DIR)--cloud-only/--full-setupflags oninstall.shfor explicit override of the TTY auto-detection- 30-minute fetch timeout on cloud submissions and app uploads (overridable via
FINALRUN_SUBMIT_TIMEOUT_MSandFINALRUN_UPLOAD_TIMEOUT_MS); stalled connections surface as a clear "connection stalled" message instead of hung spinners FINALRUN_REPORT_APP_DIRandFINALRUN_RUNTIME_ROOTenv vars for pointing the CLI at custom asset locations- GitHub Actions
Releaseworkflow (manualworkflow_dispatchtrigger) that builds all 4 binaries + 4 runtime tarballs, tags the build commit, and creates the GitHub Release with all 16 artifacts RELEASING.mdrunbook documenting the manual release flow, pre-release tags, re-running failed jobs, local dry-run, and rollback
Changed
FINALRUN_CLOUD_URLdefault switched fromcloud-dev.finalrun.apptocloud.finalrun.app. Override the env var to re-target dev infra.- Cloud
cloud testandcloud uploadnow stream the app file to the multipart body viafs.openAsBlobinstead offs.readFileSync— large APKs/IPAs no longer materialize into a single Buffer in memory - Cloud
cloud testships only the env file matching--env, not every YAML under.finalrun/env/(was leaking other environments' bindings) install.shrewritten: downloads the binary first, TTY-detects, runs interactive setup (platform prompt, brew installs, doctor verification, skills install) only when on a real terminal. Prompts have 30-second read timeouts that fall through to the conservative path. Brew install failures now correctly fail the setup step (previously short-circuited via&& ok).- The CLI's
bin/finalrun.tsnow lazy-loads the heavy modules (testRunner,doctorRunner,reportServer,reportServerManager) so cloud commands don't pull them at startup. Local commands fail fast withLocalRuntimeMissingErrorand a recovery URL when the runtime tarball isn't installed. - Test runner is now a portable Node script (
packages/cli/scripts/runTests.mjs) walkingdist/instead ofnode --test "dist/**/*.test.js"(which needs Node 21+ for native glob; we declare>= 20.19)
Removed
npm install -g @finalrun/finalrun-agent— no longer published.packages/cliisprivate: true. Existing npm-installed copies keep working until usersfinalrun upgradeor re-run the install URL.packages/cli/scripts/installAssets.mjs,preparePackage.mjs,cleanupPackage.mjs— npm-publication scripts no longer neededpackages/cli/package.jsonno longer haspostinstall,prepack,postpack,bundleDependencies, orpublishConfig- Client-side APK/IPA inspection in cloud submissions — server validates platform / packageName / simulator-compatibility authoritatively
Fixed
- Bun-compiled binary's
__dirnameis the build-machine source path; resolvingpackage.jsonvia filesystem walk-up failed on every machine other than the one that built the binary. The CLI version is now read viarequire('../package.json')at module load (compiled to a CJS require by tsc and inlined into the bundle by Bun). - Runtime tarball location now honors
$FINALRUN_DIR(default~/.finalrun), matching the install script's convention. Previously the binary's resolver only checked$HOME/.finalrunregardless of where the install script extracted the tarball. - Cloud submit/upload spinners no longer remain spinning after an unparseable JSON body or a server-side rejection — both paths now
spinner.failbefore rethrowing install.shrejects--cloud-onlyand--full-setuptogether; refuses Windows hosts up front (Cygwin / MinGW / MSYS) instead of 404-ing on a non-existentfinalrun-windows-x64.exe; validates the GitHub/releases/latestredirect target shape before parsing the tag- Release workflow gained a
concurrency:block (two simultaneous "Run workflow" clicks now queue rather than race on tag creation), strict semver regex on the version, origin tag-existence check (not just local), and--latestonly when releasing frommainwith a stable (non-pre-release) version