squeez 1.7.1

Hook-based token compressor for 5 AI CLI hosts (Claude Code, Copilot CLI, OpenCode, Gemini CLI, Codex CLI). Up to 95% bash compression, signature-mode for code reads, cross-call dedup, MCP server, self-teaching protocol. Zero runtime deps.
Documentation
name: Release
on:
  push:
    tags: ['v*']
  workflow_dispatch:

jobs:
  # ── Build platform binaries ──────────────────────────────────────────────
  build-macos:
    runs-on: macos-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable
      - name: Add targets
        run: rustup target add aarch64-apple-darwin x86_64-apple-darwin
      - name: Build ARM64
        run: cargo build --release --target aarch64-apple-darwin
      - name: Build x86_64
        run: cargo build --release --target x86_64-apple-darwin
      - name: Create universal binary
        run: |
          lipo -create \
            target/aarch64-apple-darwin/release/squeez \
            target/x86_64-apple-darwin/release/squeez \
            -output squeez-macos-universal
      - uses: actions/upload-artifact@v4
        with:
          name: squeez-macos-universal
          path: squeez-macos-universal

  build-linux-x86_64:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable
      - name: Add target
        run: rustup target add x86_64-unknown-linux-musl
      - name: Install musl-tools
        run: sudo apt-get update && sudo apt-get install -y musl-tools
      - name: Build
        run: cargo build --release --target x86_64-unknown-linux-musl
      - run: mv target/x86_64-unknown-linux-musl/release/squeez squeez-linux-x86_64
      - uses: actions/upload-artifact@v4
        with:
          name: squeez-linux-x86_64
          path: squeez-linux-x86_64

  build-linux-aarch64:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable
      - name: Install cross
        run: cargo install cross
      - name: Build
        run: cross build --release --target aarch64-unknown-linux-musl
      - run: mv target/aarch64-unknown-linux-musl/release/squeez squeez-linux-aarch64
      - uses: actions/upload-artifact@v4
        with:
          name: squeez-linux-aarch64
          path: squeez-linux-aarch64

  build-windows-x86_64:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable
      - name: Build
        run: cargo build --release --target x86_64-pc-windows-msvc
      - run: mv target/x86_64-pc-windows-msvc/release/squeez.exe squeez-windows-x86_64.exe
      - uses: actions/upload-artifact@v4
        with:
          name: squeez-windows-x86_64
          path: squeez-windows-x86_64.exe

  # ── GitHub Release (binaries + checksums) ────────────────────────────────
  # Only ONE release is kept at all times — the latest.
  # All previous releases (different tag) are deleted after publishing.
  release:
    needs: [build-macos, build-linux-x86_64, build-linux-aarch64, build-windows-x86_64]
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - uses: actions/download-artifact@v4
      - name: Generate checksums
        run: |
          cd squeez-macos-universal && sha256sum squeez-macos-universal  > ../checksums.sha256 && cd ..
          cd squeez-linux-x86_64   && sha256sum squeez-linux-x86_64     >> ../checksums.sha256 && cd ..
          cd squeez-linux-aarch64  && sha256sum squeez-linux-aarch64    >> ../checksums.sha256 && cd ..
          cd squeez-windows-x86_64 && sha256sum squeez-windows-x86_64.exe >> ../checksums.sha256 && cd ..
      - name: Upload to GitHub release
        uses: softprops/action-gh-release@v1
        with:
          files: |
            squeez-macos-universal/squeez-macos-universal
            squeez-linux-x86_64/squeez-linux-x86_64
            squeez-linux-aarch64/squeez-linux-aarch64
            squeez-windows-x86_64/squeez-windows-x86_64.exe
            checksums.sha256
          make_latest: true
      - name: Delete previous releases (keep only latest)
        env:
          GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          CURRENT_TAG="${{ github.ref_name }}"
          gh release list --limit 100 --json tagName -q '.[].tagName' | while read TAG; do
            if [ "$TAG" != "$CURRENT_TAG" ]; then
              echo "Deleting old release: $TAG"
              gh release delete "$TAG" --yes --cleanup-tag 2>/dev/null || true
            fi
          done

  # ── npm publish ──────────────────────────────────────────────────────────
  publish-npm:
    needs: release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          registry-url: 'https://registry.npmjs.org'
      - name: Sync version from git tag
        run: |
          VERSION="${GITHUB_REF_NAME#v}"
          cd npm
          node -e "
            const fs = require('fs');
            const p = JSON.parse(fs.readFileSync('package.json','utf8'));
            p.version = '$VERSION';
            fs.writeFileSync('package.json', JSON.stringify(p, null, 2) + '\n');
          "
          echo "Publishing squeez@$VERSION to npm"
      - name: Copy README into npm package
        run: cp README.md npm/README.md
      - name: Publish
        run: |
          VERSION="${GITHUB_REF_NAME#v}"
          if npm view "squeez@${VERSION}" version 2>/dev/null | grep -q "${VERSION}"; then
            echo "squeez@${VERSION} already published, skipping."
          else
            cd npm && npm publish --access public
          fi
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

  # ── crates.io publish ────────────────────────────────────────────────────
  publish-crates:
    needs: release
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable
      - name: Publish to crates.io
        run: |
          VERSION="${GITHUB_REF_NAME#v}"
          if cargo search squeez --limit 1 2>/dev/null | grep -q "\"${VERSION}\""; then
            echo "squeez ${VERSION} already published to crates.io, skipping."
          else
            cargo publish --no-verify --allow-dirty --token ${{ secrets.CARGO_REGISTRY_TOKEN }}
          fi

  # ── Auto-update CHANGELOG + README benchmarks ─────────────────────────────
  update-docs:
    needs: [release, publish-npm, publish-crates]
    if: always() && needs.release.result == 'success'
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
        with:
          ref: main
          # RELEASE_PAT (admin fine-grained) so the docs commit can be
          # pushed straight to main without going through a PR round-trip.
          # Loop-safe: auto-release.yml classifies `docs:` commits as
          # TYPE=none and short-circuits before bumping a new version.
          token: ${{ secrets.RELEASE_PAT }}
          fetch-depth: 0

      - uses: dtolnay/rust-toolchain@stable
        with:
          toolchain: stable

      - name: Add musl target
        run: rustup target add x86_64-unknown-linux-musl

      - name: Install musl-tools
        run: sudo apt-get update && sudo apt-get install -y musl-tools

      - name: Build release binary
        run: cargo build --release --target x86_64-unknown-linux-musl

      - name: Generate changelog
        run: bash .github/scripts/generate-changelog.sh
        env:
          NEW_TAG: ${{ github.ref_name }}

      - name: Update README benchmarks
        run: bash .github/scripts/update-readme-benchmarks.sh ./target/x86_64-unknown-linux-musl/release/squeez

      - name: Copy CHANGELOG to npm directory
        run: cp CHANGELOG.md npm/CHANGELOG.md

      - name: Commit + push directly to main
        run: |
          if git diff --quiet -- CHANGELOG.md npm/CHANGELOG.md README.md; then
            echo "No doc changes for ${{ github.ref_name }} — skipping commit."
            exit 0
          fi
          git config user.name  "github-actions[bot]"
          git config user.email "github-actions[bot]@users.noreply.github.com"
          git add CHANGELOG.md npm/CHANGELOG.md README.md
          git commit -m "docs: update changelog and benchmarks for ${{ github.ref_name }}"
          # Direct push to main. Admin-owned RELEASE_PAT bypasses required-
          # review on main; auto-release.yml sees a `docs:` commit and skips.
          git push origin main