Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,13 @@ jobs:
mkdir -p "$temporary_directory/release"
printf 'arm64 archive' >"$temporary_directory/release/Gloss-macos-arm64.zip"
printf 'x86_64 archive' >"$temporary_directory/release/Gloss-macos-x86_64.zip"
printf 'arm64 Codex archive' >"$temporary_directory/release/Gloss-macos-arm64-with-codex.zip"
printf 'x86_64 Codex archive' >"$temporary_directory/release/Gloss-macos-x86_64-with-codex.zip"
Scripts/generate_release_metadata.sh \
"$temporary_directory/release/Gloss-macos-arm64.zip" \
"$temporary_directory/release/Gloss-macos-x86_64.zip" \
"$temporary_directory/release/Gloss-macos-arm64-with-codex.zip" \
"$temporary_directory/release/Gloss-macos-x86_64-with-codex.zip" \
0.0.0 \
"$temporary_directory/release" \
v0.0.0 \
Expand All @@ -53,6 +57,9 @@ jobs:
grep -F \
'https://github.com/SunChJ/gloss-releases/releases/download/v0.0.0/' \
"$temporary_directory/release/gloss.rb"
grep -F \
'Gloss-macos-arm64-with-codex.zip' \
"$temporary_directory/release/gloss-with-codex.rb"
(
cd "$temporary_directory/release"
shasum -a 256 --check SHA256SUMS
Expand Down
51 changes: 45 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ jobs:
fi

build:
name: Build macOS ${{ matrix.architecture }}
name: Build macOS ${{ matrix.architecture }} (${{ matrix.variant }})
needs:
- preflight
strategy:
Expand All @@ -62,8 +62,24 @@ jobs:
include:
- architecture: arm64
runner: macos-15
variant: standard
runtime_mode: cli
archive: Gloss-macos-arm64.zip
- architecture: arm64
runner: macos-15
variant: with-codex
runtime_mode: bundled
archive: Gloss-macos-arm64-with-codex.zip
- architecture: x86_64
runner: macos-15-intel
variant: standard
runtime_mode: cli
archive: Gloss-macos-x86_64.zip
- architecture: x86_64
runner: macos-15-intel
variant: with-codex
runtime_mode: bundled
archive: Gloss-macos-x86_64-with-codex.zip
runs-on: ${{ matrix.runner }}
timeout-minutes: 90
env:
Expand Down Expand Up @@ -101,15 +117,27 @@ jobs:
fi
- name: Build Gloss.app
working-directory: gloss
env:
GLOSS_CODEX_RUNTIME_MODE: ${{ matrix.runtime_mode }}
run: Scripts/build_app.sh
- name: Verify app architecture and ad-hoc signature
- name: Verify app architecture, contents, and ad-hoc signature
working-directory: gloss
env:
EXPECTED_ARCHITECTURE: ${{ matrix.architecture }}
RELEASE_VARIANT: ${{ matrix.variant }}
run: |
lipo dist/Gloss.app/Contents/MacOS/Gloss -verify_arch "$EXPECTED_ARCHITECTURE"
test ! -e "dist/Gloss.app/Contents/PlugIns/Gloss Extension.appex"
test ! -e "dist/Gloss.app/Contents/Helpers/gloss-codex-app-server"
if [[ "$RELEASE_VARIANT" == "with-codex" ]]; then
test -x "dist/Gloss.app/Contents/Helpers/gloss-codex-app-server"
test -f "dist/Gloss.app/Contents/Resources/Codex-LICENSE.txt"
test -f "dist/Gloss.app/Contents/Resources/CodexRuntime.lock"
lipo dist/Gloss.app/Contents/Helpers/gloss-codex-app-server \
-verify_arch "$EXPECTED_ARCHITECTURE"
else
test ! -e "dist/Gloss.app/Contents/Helpers/gloss-codex-app-server"
test ! -e "dist/Gloss.app/Contents/Resources/CodexRuntime.lock"
fi
test "$(
/usr/libexec/PlistBuddy \
-c 'Print :GlossSafariExtensionAvailable' \
Expand All @@ -122,12 +150,13 @@ jobs:
working-directory: gloss
env:
GLOSS_RELEASE_ARCHITECTURE: ${{ matrix.architecture }}
GLOSS_RELEASE_VARIANT: ${{ matrix.variant }}
run: Scripts/package_release.sh
- name: Upload architecture artifact
- name: Upload architecture and variant artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: Gloss-${{ matrix.architecture }}
path: gloss/dist/release/Gloss-macos-${{ matrix.architecture }}.zip
name: Gloss-${{ matrix.architecture }}-${{ matrix.variant }}
path: gloss/dist/release/${{ matrix.archive }}
if-no-files-found: error

assemble:
Expand Down Expand Up @@ -157,9 +186,13 @@ jobs:
mkdir -p dist/release
cp ../release-input/Gloss-macos-arm64.zip dist/release/
cp ../release-input/Gloss-macos-x86_64.zip dist/release/
cp ../release-input/Gloss-macos-arm64-with-codex.zip dist/release/
cp ../release-input/Gloss-macos-x86_64-with-codex.zip dist/release/
Scripts/generate_release_metadata.sh \
dist/release/Gloss-macos-arm64.zip \
dist/release/Gloss-macos-x86_64.zip \
dist/release/Gloss-macos-arm64-with-codex.zip \
dist/release/Gloss-macos-x86_64-with-codex.zip \
"$version" \
dist/release \
"$RELEASE_TAG" \
Expand Down Expand Up @@ -206,10 +239,13 @@ jobs:
path: |
gloss/dist/release/Gloss-macos-arm64.zip
gloss/dist/release/Gloss-macos-x86_64.zip
gloss/dist/release/Gloss-macos-arm64-with-codex.zip
gloss/dist/release/Gloss-macos-x86_64-with-codex.zip
gloss/dist/release/SHA256SUMS
gloss/dist/release/gloss-release-manifest.json
gloss/dist/release/gloss-release-manifest.json.sig
gloss/dist/release/gloss.rb
gloss/dist/release/gloss-with-codex.rb
if-no-files-found: error
- name: Publish GitHub release assets
if: github.event_name == 'push' || inputs.publish_release
Expand Down Expand Up @@ -250,10 +286,13 @@ jobs:
--repo "$GLOSS_RELEASE_REPOSITORY" \
dist/release/Gloss-macos-arm64.zip \
dist/release/Gloss-macos-x86_64.zip \
dist/release/Gloss-macos-arm64-with-codex.zip \
dist/release/Gloss-macos-x86_64-with-codex.zip \
dist/release/SHA256SUMS \
dist/release/gloss-release-manifest.json \
dist/release/gloss-release-manifest.json.sig \
dist/release/gloss.rb \
dist/release/gloss-with-codex.rb \
--clobber
gh release edit "$RELEASE_TAG" \
--repo "$GLOSS_RELEASE_REPOSITORY" \
Expand Down
28 changes: 23 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,30 @@ browser bridge on `127.0.0.1` behind a per-device token.

Gloss requires **macOS 14 or newer**.

The default installation does not embed Codex and uses a separately installed Codex CLI for GPT translation:

```bash
brew install --cask sunchj/tap/gloss
```

Alternatively, install the full variant with a bundled Codex app-server runtime.
The two casks conflict and cannot be installed together:

```bash
brew install --cask sunchj/tap/gloss-with-codex
```

GitHub Releases provide both the default `Gloss-macos-<architecture>.zip` and the
bundled `Gloss-macos-<architecture>-with-codex.zip` archives.

Gloss checks the signed release channel after launch, at most once every 24
hours. When an update is available it presents an actionable reminder; official
Homebrew installations can update and restart directly from that prompt. You
can also update manually with:

```bash
brew update
brew upgrade --cask sunchj/tap/gloss
brew upgrade --cask sunchj/tap/gloss # use gloss-with-codex for the bundled variant
```

The Homebrew build is ad-hoc signed rather than Apple-notarized. Its cask
Expand Down Expand Up @@ -142,10 +154,16 @@ open dist/Gloss.app
```

The packaging script expects the companion browser-extension source in a
sibling checkout and deliberately does not bundle Codex. Install Codex first,
or set `GLOSS_CODEX_BIN`; `./Scripts/build_app_without_bundled_codex.sh` is the
explicit equivalent of the default lightweight build. If the extension is not
a sibling checkout, set `GLOSS_BROWSER_EXTENSION_SOURCE` to its directory.
sibling checkout. It does not bundle Codex by default; install Codex first or
set `GLOSS_CODEX_BIN`. To build the bundled variant, run:

```bash
GLOSS_CODEX_RUNTIME_MODE=bundled ./Scripts/build_app.sh
```

`./Scripts/build_app_without_bundled_codex.sh` is the explicit equivalent of
the default lightweight build. If the extension is not a sibling checkout, set
`GLOSS_BROWSER_EXTENSION_SOURCE` to its directory.

## Repository layout

Expand Down
23 changes: 20 additions & 3 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,28 @@ Gloss 使用 Swift 开发,通过 Apple Vision 在本机执行 OCR;浏览器

Gloss 要求 **macOS 14 或更高版本**。

默认安装不内置 Codex,运行 GPT 翻译时使用本机另外安装的 Codex CLI:

```bash
brew install --cask sunchj/tap/gloss
```

也可以选择安装内置 Codex app-server runtime 的完整版本。两种 Cask 会互相冲突,
不能同时安装:

```bash
brew install --cask sunchj/tap/gloss-with-codex
```

GitHub Release 同时提供默认的 `Gloss-macos-<架构>.zip` 和内置 Codex 的
`Gloss-macos-<架构>-with-codex.zip`。

Gloss 会在启动后检查签名发布通道,每 24 小时最多一次。发现新版本时会主动提醒;
官方 Homebrew 安装可以直接在提醒中点击“更新并重新启动”。也可以手动运行:

```bash
brew update
brew upgrade --cask sunchj/tap/gloss
brew upgrade --cask sunchj/tap/gloss # 内置版使用 gloss-with-codex
```

Homebrew 版本使用 ad-hoc 签名,并未经过 Apple 公证。Cask 会在本机重新签名、移除
Expand Down Expand Up @@ -124,8 +136,13 @@ swift run gloss-cli capabilities --json
open dist/Gloss.app
```

打包脚本要求在相邻目录中提供配套的浏览器扩展源码,并且默认不再内置 Codex。
请先安装 Codex CLI,或设置 `GLOSS_CODEX_BIN`;
打包脚本要求在相邻目录中提供配套的浏览器扩展源码。默认不内置 Codex;请先安装
Codex CLI,或设置 `GLOSS_CODEX_BIN`。如需构建内置 Codex runtime 的版本,可以运行:

```bash
GLOSS_CODEX_RUNTIME_MODE=bundled ./Scripts/build_app.sh
```

`./Scripts/build_app_without_bundled_codex.sh` 是默认轻量构建的显式入口。扩展源码不在
相邻目录时,可通过 `GLOSS_BROWSER_EXTENSION_SOURCE` 指定其位置。

Expand Down
4 changes: 2 additions & 2 deletions Resources/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0.2</string>
<string>1.0.3</string>
<key>CFBundleVersion</key>
<string>15</string>
<string>16</string>
<key>GlossSafariExtensionAvailable</key>
<true/>
<key>CFBundleDocumentTypes</key>
Expand Down
34 changes: 31 additions & 3 deletions Scripts/generate_homebrew_cask.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ REPOSITORY="${6:-${GLOSS_RELEASE_REPOSITORY:-SunChJ/gloss-releases}}"
ARM64_ARCHIVE="${7:-Gloss-macos-arm64.zip}"
X86_64_ARCHIVE="${8:-Gloss-macos-x86_64.zip}"
DOWNLOAD_BASE_URL="${GLOSS_CASK_DOWNLOAD_BASE_URL:-}"
CASK_TOKEN="${GLOSS_CASK_TOKEN:-gloss}"
BUNDLES_CODEX="${GLOSS_CASK_BUNDLES_CODEX:-false}"
if [[ -z "$DOWNLOAD_BASE_URL" ]]; then
DOWNLOAD_BASE_URL="https://github.com/$REPOSITORY/releases/download/$RELEASE_TAG"
fi
Expand All @@ -23,6 +25,22 @@ if [[ ! "$VERSION" =~ ^[0-9]+(\.[0-9]+){2}([+-][0-9A-Za-z.-]+)?$ ]]; then
echo "Invalid cask version: $VERSION" >&2
exit 65
fi
case "$CASK_TOKEN:$BUNDLES_CODEX" in
gloss:false)
CONFLICTING_CASK="gloss-with-codex"
CASK_NAME="Gloss"
CASK_DESCRIPTION="Context-aware text and document translation"
;;
gloss-with-codex:true)
CONFLICTING_CASK="gloss"
CASK_NAME="Gloss with Codex"
CASK_DESCRIPTION="Context-aware translation with a bundled Codex runtime"
;;
*)
echo "Unsupported Gloss cask variant: $CASK_TOKEN (bundles Codex: $BUNDLES_CODEX)" >&2
exit 65
;;
esac
for checksum in "$ARM64_SHA256" "$X86_64_SHA256"; do
if [[ ! "$checksum" =~ ^[0-9a-fA-F]{64}$ ]]; then
echo "Invalid cask SHA-256: $checksum" >&2
Expand Down Expand Up @@ -58,7 +76,7 @@ X86_64_SHA256="$(printf '%s' "$X86_64_SHA256" | tr '[:upper:]' '[:lower:]')"
DOWNLOAD_BASE_URL="${DOWNLOAD_BASE_URL%/}"
mkdir -p "$(dirname "$OUTPUT_PATH")"
cat >"$OUTPUT_PATH" <<RUBY
cask "gloss" do
cask "$CASK_TOKEN" do
version "$VERSION"

on_arm do
Expand All @@ -72,10 +90,11 @@ cask "gloss" do
url "$DOWNLOAD_BASE_URL/$X86_64_ARCHIVE"
end

name "Gloss"
desc "Context-aware text and document translation"
name "$CASK_NAME"
desc "$CASK_DESCRIPTION"
homepage "https://github.com/$REPOSITORY"

conflicts_with cask: "$CONFLICTING_CASK"
depends_on macos: :sonoma

app "Gloss.app"
Expand Down Expand Up @@ -150,8 +169,17 @@ cask "gloss" do
caveats <<~EOS
Gloss uses an ad-hoc code signature and is not Apple-notarized. This custom
tap re-signs the installed app and removes its quarantine attribute.
$(if [[ "$BUNDLES_CODEX" == "true" ]]; then
cat <<'EOF'
This variant bundles the Codex app-server runtime. Do not install it together
with the standard gloss cask.
EOF
else
cat <<'EOF'
ChatGPT translation requires a separately installed Codex CLI with
the app-server subcommand; Gloss does not bundle Codex.
EOF
fi)
EOS
end
RUBY
Expand Down
Loading
Loading