spawn/fly/opencode.sh
A 2ef621cc69
refactor: convert fly/ cloud provider from bash to TypeScript (#1601) (#1602)
Replace fly/lib/common.sh (741 lines of bash) with a TypeScript
implementation using Bun runtime. The fly/ provider was the most
complex bash code in the project — recent fixes (#1597, #1599, #1600)
highlight the pain of debugging HTTP calls, JSON parsing, and multi-step
auth flows in shell.

New TypeScript modules:
- fly/lib/ui.ts — logging, prompts, validation (zero deps)
- fly/lib/fly.ts — API client (fetch), auth chain, org listing, provisioning
- fly/lib/oauth.ts — OpenRouter OAuth via Bun.serve(), key management
- fly/lib/agents.ts — typed agent configs for all 6 agents
- fly/main.ts — orchestrator entry point

Agent .sh files become thin shims (~30 lines) that install bun if needed,
download TS sources for curl|bash execution, and delegate to main.ts.

Test coverage:
- 44 TypeScript unit tests (bun test) for pure logic
- 4 fly failure-mode tests (mock.sh) for error scenarios
- All existing test suites pass (110 run.sh, 76 mock.sh)

Co-authored-by: lab <6723574+louisgv@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-02-21 10:41:34 -08:00

31 lines
1.1 KiB
Bash

#!/bin/bash
set -eo pipefail
# Thin shim: ensures bun is available, downloads TS sources if needed, runs main.ts
_ensure_bun() {
if command -v bun &>/dev/null; then return 0; fi
printf '\033[0;36mInstalling bun...\033[0m\n' >&2
curl -fsSL https://bun.sh/install | bash >/dev/null 2>&1 || { printf '\033[0;31mFailed to install bun\033[0m\n' >&2; exit 1; }
export PATH="$HOME/.bun/bin:$PATH"
command -v bun &>/dev/null || { printf '\033[0;31mbun not found after install\033[0m\n' >&2; exit 1; }
}
_ensure_bun
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd)"
if [[ -n "$SCRIPT_DIR" && -f "$SCRIPT_DIR/main.ts" ]]; then
exec bun run "$SCRIPT_DIR/main.ts" opencode "$@"
fi
REMOTE_BASE="https://raw.githubusercontent.com/OpenRouterTeam/spawn/main/fly"
TMPDIR_TS=$(mktemp -d)
trap 'rm -rf "$TMPDIR_TS"' EXIT
mkdir -p "$TMPDIR_TS/lib"
for f in main.ts lib/fly.ts lib/oauth.ts lib/agents.ts lib/ui.ts; do
curl -fsSL "$REMOTE_BASE/$f" -o "$TMPDIR_TS/$f" || { printf '\033[0;31mFailed to download %s\033[0m\n' "$f" >&2; exit 1; }
done
exec bun run "$TMPDIR_TS/main.ts" opencode "$@"