name: CI on: pull_request: branches: - main push: branches: - main jobs: check: name: Lint & Type Check runs-on: ubuntu-latest permissions: contents: read steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v1 with: bun-version: 1.3.0 - name: Install dependencies env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bun install - name: Lint & Type Check run: bun run check build: needs: check name: ${{ matrix.name }} runs-on: ${{ matrix.runner }} strategy: fail-fast: false matrix: include: - name: macOS arm64 (macos-14) runner: macos-14 - name: Linux x64 (ubuntu-24.04) runner: ubuntu-24.04 - name: Linux arm64 (ubuntu-24.04-arm) runner: ubuntu-24.04-arm - name: Windows x64 (windows-latest) runner: windows-latest defaults: run: shell: bash permissions: contents: read steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v1 with: bun-version: 1.3.0 - name: Install dependencies env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bun install - name: Run tests (extended timeout) run: bun test --timeout 15000 - name: Build bundle run: bun run build - name: CLI help smoke test run: ./letta.js --help - name: CLI version smoke test run: ./letta.js --version || true - name: Bundle size check run: | if [ "$RUNNER_OS" = "Windows" ]; then SIZE=$(powershell -command "(Get-Item letta.js).length") else SIZE=$(stat -f%z ./letta.js 2>/dev/null || stat -c%s ./letta.js 2>/dev/null) fi SIZE_MB=$((SIZE / 1024 / 1024)) echo "Bundle size: $SIZE bytes (~${SIZE_MB}MB)" # Warn if bundle is larger than 50MB if [ $SIZE -gt 52428800 ]; then echo "⚠️ Warning: Bundle size is larger than 50MB" else echo "✓ Bundle size is acceptable" fi - name: Headless smoke test (API) # Only run on push to main or PRs from the same repo (not forks, to protect secrets) if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }} env: LETTA_API_KEY: ${{ secrets.LETTA_API_KEY }} run: ./letta.js --prompt "ping" --tools "" --permission-mode plan - name: Publish dry-run if: ${{ github.event_name == 'push' }} env: NPM_CONFIG_TOKEN: ${{ secrets.NPM_TOKEN }} LETTA_API_KEY: dummy run: bun publish --dry-run - name: Pack (no auth available) if: ${{ github.event_name != 'push' }} run: bun pm pack headless: needs: check name: Headless / ${{ matrix.model }} runs-on: ubuntu-latest strategy: fail-fast: false matrix: model: [gpt-5-minimal, gpt-4.1, sonnet-4.5, gemini-pro, glm-4.6, haiku] steps: - name: Checkout uses: actions/checkout@v4 - name: Setup Bun uses: oven-sh/setup-bun@v1 with: bun-version: 1.3.0 - name: Install dependencies env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: bun install - name: Run headless scenario (all outputs) if: ${{ github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) }} env: LETTA_API_KEY: ${{ secrets.LETTA_API_KEY }} run: | bun run src/tests/headless-scenario.ts --model "${{ matrix.model }}" --output text --parallel on bun run src/tests/headless-scenario.ts --model "${{ matrix.model }}" --output json --parallel on bun run src/tests/headless-scenario.ts --model "${{ matrix.model }}" --output stream-json --parallel on