diff --git a/.github/workflows/desktop_cd.yaml b/.github/workflows/desktop_cd.yaml index 44aa3f603b..cd8595d8e3 100644 --- a/.github/workflows/desktop_cd.yaml +++ b/.github/workflows/desktop_cd.yaml @@ -66,6 +66,18 @@ jobs: permissions: contents: write runs-on: macos-14 + strategy: + fail-fast: false + matrix: + include: + - target: aarch64-apple-darwin + arch: aarch64 + artifact_name: silicon + include_am: true + - target: x86_64-apple-darwin + arch: x86_64 + artifact_name: intel + include_am: false defaults: run: shell: bash @@ -83,19 +95,22 @@ jobs: with: platform: macos - uses: ./.github/actions/pnpm_install - - uses: ./.github/actions/argmax_sdk_setup + - if: ${{ matrix.include_am }} + uses: ./.github/actions/argmax_sdk_setup with: api-token: ${{ secrets.AM_SECRET_TOKEN }} - run: pnpm -F ui build - - run: | - aws s3 cp s3://argmax/stt apps/desktop/src-tauri/binaries/stt-aarch64-apple-darwin \ + - if: ${{ matrix.include_am }} + run: | + aws s3 cp s3://argmax/stt apps/desktop/src-tauri/binaries/stt-${{ matrix.target }} \ --endpoint-url ${{ secrets.CLOUDFLARE_R2_ENDPOINT_URL }} \ --region auto env: AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} - - run: | - chmod +x ./apps/desktop/src-tauri/binaries/stt-aarch64-apple-darwin + - if: ${{ matrix.include_am }} + run: | + chmod +x ./apps/desktop/src-tauri/binaries/stt-${{ matrix.target }} ./scripts/sidecar.sh "./apps/desktop/${{ env.TAURI_CONF_PATH }}" "binaries/stt" - run: ./scripts/resource.sh "./apps/desktop/${{ env.TAURI_CONF_PATH }}" "resources/libonnxruntime.dylib" - uses: ./.github/actions/apple_cert @@ -109,12 +124,11 @@ jobs: if [[ "${{ inputs.channel }}" == "staging" ]]; then FEATURES_FLAG="--features devtools" fi - pnpm -F desktop tauri build --target aarch64-apple-darwin --config ${{ env.TAURI_CONF_PATH }} --verbose $FEATURES_FLAG + pnpm -F desktop tauri build --target ${{ matrix.target }} --config ${{ env.TAURI_CONF_PATH }} --verbose $FEATURES_FLAG env: - # https://github.com/tauri-apps/tauri-action/issues/740 CI: false GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - AM_API_KEY: ${{ secrets.AM_API_KEY }} + AM_API_KEY: ${{ matrix.include_am && secrets.AM_API_KEY || '' }} POSTHOG_API_KEY: ${{ secrets.POSTHOG_API_KEY }} SENTRY_DSN: ${{ secrets.SENTRY_DSN }} APPLE_ID: ${{ secrets.APPLE_ID }} @@ -133,7 +147,7 @@ jobs: VITE_PRO_PRODUCT_ID: ${{ secrets.VITE_PRO_PRODUCT_ID }} - run: | mkdir -p target/release/ - find target/aarch64-apple-darwin/release -type f -not -path "*/\.*" -exec cp {} target/release/ \; + find target/${{ matrix.target }}/release -type f -not -path "*/\.*" -exec cp {} target/release/ \; shell: bash working-directory: ./apps/desktop/src-tauri - if: ${{ inputs.channel != 'staging' }} @@ -147,10 +161,10 @@ jobs: working-directory: ./apps/desktop - if: ${{ inputs.channel != 'staging' }} run: | - DMG_FILE=$(find "apps/desktop/src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/" -name "*.dmg" -type f) - cp "$DMG_FILE" "hyprnote-macos-aarch64.dmg" - aws s3 cp "hyprnote-macos-aarch64.dmg" \ - "s3://hyprnote-build/desktop/${{ needs.compute-version.outputs.version }}/hyprnote-macos-aarch64.dmg" \ + DMG_FILE=$(find "apps/desktop/src-tauri/target/${{ matrix.target }}/release/bundle/dmg/" -name "*.dmg" -type f) + cp "$DMG_FILE" "hyprnote-macos-${{ matrix.arch }}.dmg" + aws s3 cp "hyprnote-macos-${{ matrix.arch }}.dmg" \ + "s3://hyprnote-build/desktop/${{ needs.compute-version.outputs.version }}/hyprnote-macos-${{ matrix.arch }}.dmg" \ --endpoint-url ${{ secrets.CLOUDFLARE_R2_ENDPOINT_URL }} \ --region auto env: @@ -159,8 +173,8 @@ jobs: - if: ${{ inputs.channel == 'staging' }} uses: actions/upload-artifact@v4 with: - name: hyprnote-staging-macos - path: apps/desktop/src-tauri/target/aarch64-apple-darwin/release/bundle/dmg/*.dmg + name: hyprnote-staging-macos-${{ matrix.artifact_name }} + path: apps/desktop/src-tauri/target/${{ matrix.target }}/release/bundle/dmg/*.dmg retention-days: 3 build-linux: @@ -261,18 +275,22 @@ jobs: channel: ${{ env.RELEASE_CHANNEL }} framework: tauri working-directory: ./apps/desktop - - name: Download macOS DMG from S3 + - if: ${{ needs.build-macos.result == 'success' }} run: | aws s3 cp \ "s3://hyprnote-build/desktop/${{ needs.compute-version.outputs.version }}/hyprnote-macos-aarch64.dmg" \ "hyprnote-macos-aarch64.dmg" \ --endpoint-url ${{ secrets.CLOUDFLARE_R2_ENDPOINT_URL }} \ --region auto + aws s3 cp \ + "s3://hyprnote-build/desktop/${{ needs.compute-version.outputs.version }}/hyprnote-macos-x86_64.dmg" \ + "hyprnote-macos-x86_64.dmg" \ + --endpoint-url ${{ secrets.CLOUDFLARE_R2_ENDPOINT_URL }} \ + --region auto env: AWS_ACCESS_KEY_ID: ${{ secrets.CLOUDFLARE_R2_ACCESS_KEY_ID }} AWS_SECRET_ACCESS_KEY: ${{ secrets.CLOUDFLARE_R2_SECRET_ACCESS_KEY }} - - name: Download Linux AppImage from S3 (if available) - if: ${{ needs.build-linux.result == 'success' }} + - if: ${{ needs.build-linux.result == 'success' }} run: | aws s3 cp \ "s3://hyprnote-build/desktop/${{ needs.compute-version.outputs.version }}/hyprnote-linux-x86_64.AppImage" \ @@ -287,22 +305,30 @@ jobs: github_token: ${{ secrets.GITHUB_TOKEN }} custom_tag: desktop_v${{ needs.compute-version.outputs.version }} tag_prefix: "" - - name: Create GitHub release with macOS only - if: ${{ needs.build-linux.result != 'success' }} - uses: ncipollo/release-action@v1 - with: - tag: desktop_v${{ needs.compute-version.outputs.version }} - name: desktop_v${{ needs.compute-version.outputs.version }} - body: "https://hyprnote.com/changelog/${{ needs.compute-version.outputs.version }}" - artifacts: "hyprnote-macos-aarch64.dmg" - - name: Create GitHub release with macOS + Linux - if: ${{ needs.build-linux.result == 'success' }} - uses: ncipollo/release-action@v1 + - id: artifacts + run: | + ARTIFACTS="" + if [[ "${{ needs.build-macos.result }}" == "success" ]]; then + ARTIFACTS="hyprnote-macos-aarch64.dmg,hyprnote-macos-x86_64.dmg" + fi + if [[ "${{ needs.build-linux.result }}" == "success" ]]; then + if [[ -n "$ARTIFACTS" ]]; then + ARTIFACTS="$ARTIFACTS,hyprnote-linux-x86_64.AppImage" + else + ARTIFACTS="hyprnote-linux-x86_64.AppImage" + fi + fi + if [[ -z "$ARTIFACTS" ]]; then + echo "No artifacts to release" >&2 + exit 1 + fi + echo "list=$ARTIFACTS" >> $GITHUB_OUTPUT + - uses: ncipollo/release-action@v1 with: tag: desktop_v${{ needs.compute-version.outputs.version }} name: desktop_v${{ needs.compute-version.outputs.version }} body: "https://hyprnote.com/changelog/${{ needs.compute-version.outputs.version }}" - artifacts: "hyprnote-macos-aarch64.dmg,hyprnote-linux-x86_64.AppImage" + artifacts: ${{ steps.artifacts.outputs.list }} - run: | set -e curl -f -X POST \ diff --git a/apps/desktop/package.json b/apps/desktop/package.json index a029497bb0..2a74e28ff2 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -67,6 +67,7 @@ "@tauri-apps/plugin-fs": "^2.4.4", "@tauri-apps/plugin-http": "^2.5.4", "@tauri-apps/plugin-opener": "^2.5.2", + "@tauri-apps/plugin-os": "^2.3.2", "@tauri-apps/plugin-process": "^2.3.1", "@tauri-apps/plugin-shell": "^2.3.3", "@tauri-apps/plugin-store": "^2.4.1", diff --git a/apps/desktop/src/components/main/sidebar/search/index.tsx b/apps/desktop/src/components/main/sidebar/search/index.tsx index d236316e06..39f9da674f 100644 --- a/apps/desktop/src/components/main/sidebar/search/index.tsx +++ b/apps/desktop/src/components/main/sidebar/search/index.tsx @@ -1,7 +1,5 @@ import { SearchXIcon } from "lucide-react"; -import { cn } from "@hypr/utils"; - import { type GroupedSearchResults, useSearch, diff --git a/apps/desktop/src/components/settings/ai/stt/select.tsx b/apps/desktop/src/components/settings/ai/stt/select.tsx index acc96889c0..79fa1f0c06 100644 --- a/apps/desktop/src/components/settings/ai/stt/select.tsx +++ b/apps/desktop/src/components/settings/ai/stt/select.tsx @@ -1,5 +1,6 @@ import { useForm } from "@tanstack/react-form"; -import { useQueries } from "@tanstack/react-query"; +import { useQueries, useQuery } from "@tanstack/react-query"; +import { arch } from "@tauri-apps/plugin-os"; import { Input } from "@hypr/ui/components/ui/input"; import { @@ -219,6 +220,14 @@ function useConfiguredMapping(): Record< main.STORE_ID, ); + const targetArch = useQuery({ + queryKey: ["target-arch"], + queryFn: () => arch(), + staleTime: Infinity, + }); + + const isAppleSilicon = targetArch.data === "aarch64"; + const [p2, p3, tinyEn, smallEn] = useQueries({ queries: [ sttModelQueries.isDownloaded("am-parakeet-v2"), @@ -235,17 +244,24 @@ function useConfiguredMapping(): Record< } if (provider.id === "hyprnote") { + const models = [ + { id: "cloud", isDownloaded: billing.isPro }, + { id: "QuantizedTinyEn", isDownloaded: tinyEn.data ?? false }, + { id: "QuantizedSmallEn", isDownloaded: smallEn.data ?? false }, + ]; + + if (isAppleSilicon) { + models.push( + { id: "am-parakeet-v2", isDownloaded: p2.data ?? false }, + { id: "am-parakeet-v3", isDownloaded: p3.data ?? false }, + ); + } + return [ provider.id, { configured: true, - models: [ - { id: "cloud", isDownloaded: billing.isPro }, - { id: "am-parakeet-v2", isDownloaded: p2.data ?? false }, - { id: "am-parakeet-v3", isDownloaded: p3.data ?? false }, - { id: "QuantizedTinyEn", isDownloaded: tinyEn.data ?? false }, - { id: "QuantizedSmallEn", isDownloaded: smallEn.data ?? false }, - ], + models, }, ]; } diff --git a/apps/web/src/routes/_view/changelog/$slug.tsx b/apps/web/src/routes/_view/changelog/$slug.tsx index 50c081d1cf..9247beb11a 100644 --- a/apps/web/src/routes/_view/changelog/$slug.tsx +++ b/apps/web/src/routes/_view/changelog/$slug.tsx @@ -118,11 +118,42 @@ function HeroSection({ changelog }: { changelog: ChangelogWithMeta }) {

Version {changelog.version}

+ ); } +function DownloadButtons({ version }: { version: string }) { + const baseUrl = `https://github.com/fastrepl/hyprnote/releases/download/desktop_v${version}`; + + return ( +
+ + + Apple Silicon + + + + Intel Mac + + + + Linux + +
+ ); +} + function ChangelogContentSection({ changelog, allChangelogs, diff --git a/apps/web/src/routes/_view/download/apple-intel.tsx b/apps/web/src/routes/_view/download/apple-intel.tsx new file mode 100644 index 0000000000..d67c2f7faf --- /dev/null +++ b/apps/web/src/routes/_view/download/apple-intel.tsx @@ -0,0 +1,9 @@ +import { createFileRoute, redirect } from "@tanstack/react-router"; + +export const Route = createFileRoute("/_view/download/apple-intel")({ + beforeLoad: async () => { + throw redirect({ + href: "https://desktop2.hyprnote.com/download/latest/dmg-x86_64?channel=nightly", + }); + }, +}); diff --git a/apps/web/src/routes/_view/download/index.tsx b/apps/web/src/routes/_view/download/index.tsx index 0983b30225..c1b84f1707 100644 --- a/apps/web/src/routes/_view/download/index.tsx +++ b/apps/web/src/routes/_view/download/index.tsx @@ -27,8 +27,9 @@ function Component() { ])} > - Mac (Apple Silicon) features on-device speech-to-text. Other - platforms coming soon without on-device processing. + Mac (Apple Silicon) features on-device speech-to-text. Intel Mac + available with cloud-based transcription. Other platforms coming + soon. @@ -57,8 +58,8 @@ function Component() {