mirror of
https://github.com/lobehub/lobehub.git
synced 2026-03-26 13:19:34 +07:00
🐛 fix(desktop): macos26 small icon (#9421)
* 🐛 fix(desktop): macos26 icon small
* Revert "🐛 fix(desktop): macos26 icon small"
This reverts commit 4a4b7b230c.
* ✨ feat(desktop): support Liquid Glass icons for macOS 26
- Add pre-generated Assets.car files for all build variants
- Configure afterPack hook to copy Assets.car during build
- Maintain backward compatibility with .icns fallback for older macOS
Reference: https://github.com/electron-userland/electron-builder/issues/9254
* docs: optimize comments
* fix: update deprecated macos-13 to macos-15-intel
* docs: optimize ai rules
This commit is contained in:
@@ -6,18 +6,16 @@ alwaysApply: true
|
|||||||
|
|
||||||
You are developing an open-source, modern-design AI chat framework: lobehub(previous lobe-chat).
|
You are developing an open-source, modern-design AI chat framework: lobehub(previous lobe-chat).
|
||||||
|
|
||||||
support platforms:
|
Supported platforms:
|
||||||
|
|
||||||
- web desktop/mobile
|
- web desktop/mobile
|
||||||
- desktop(electron)
|
- desktop(electron)
|
||||||
- mobile app(react native). coming soon
|
- mobile app(react native), coming soon
|
||||||
|
|
||||||
logo emoji: 🤯
|
logo emoji: 🤯
|
||||||
|
|
||||||
## Project Technologies Stack
|
## Project Technologies Stack
|
||||||
|
|
||||||
read [package.json](mdc:package.json) to know all npm packages you can use.
|
|
||||||
|
|
||||||
- Next.js 15
|
- Next.js 15
|
||||||
- react 19
|
- react 19
|
||||||
- TypeScript
|
- TypeScript
|
||||||
@@ -33,6 +31,6 @@ read [package.json](mdc:package.json) to know all npm packages you can use.
|
|||||||
- dayjs for time library
|
- dayjs for time library
|
||||||
- lodash-es for utility library
|
- lodash-es for utility library
|
||||||
- TRPC for type safe backend
|
- TRPC for type safe backend
|
||||||
- PGLite for client DB and PostgreSQL for backend DB
|
- PGLite for client DB and Neon PostgreSQL for backend DB
|
||||||
- Drizzle ORM
|
- Drizzle ORM
|
||||||
- Vitest for testing
|
- Vitest for testing
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ alwaysApply: false
|
|||||||
|
|
||||||
# LobeChat Project Structure
|
# LobeChat Project Structure
|
||||||
|
|
||||||
note: some not very important files are not shown for simplicity.
|
|
||||||
|
|
||||||
## Complete Project Structure
|
## Complete Project Structure
|
||||||
|
|
||||||
this project use common monorepo structure. The workspace packages name use `@lobechat/` namespace.
|
This project uses common monorepo structure. The workspace packages name use `@lobechat/` namespace.
|
||||||
|
|
||||||
|
**note**: some not very important files are not shown for simplicity.
|
||||||
|
|
||||||
```plaintext
|
```plaintext
|
||||||
lobe-chat/
|
lobe-chat/
|
||||||
@@ -28,10 +28,12 @@ lobe-chat/
|
|||||||
│ │ │ ├── schemas/
|
│ │ │ ├── schemas/
|
||||||
│ │ │ └── repositories/
|
│ │ │ └── repositories/
|
||||||
│ ├── model-bank/
|
│ ├── model-bank/
|
||||||
|
│ │ └── src/
|
||||||
|
│ │ └── aiModels/
|
||||||
│ ├── model-runtime/
|
│ ├── model-runtime/
|
||||||
│ │ └── src/
|
│ │ └── src/
|
||||||
│ │ ├── openai/
|
│ │ ├── core/
|
||||||
│ │ └── anthropic/
|
│ │ └── providers/
|
||||||
│ ├── types/
|
│ ├── types/
|
||||||
│ │ └── src/
|
│ │ └── src/
|
||||||
│ │ ├── message/
|
│ │ ├── message/
|
||||||
@@ -96,14 +98,14 @@ lobe-chat/
|
|||||||
- UI Components: `src/components`, `src/features`
|
- UI Components: `src/components`, `src/features`
|
||||||
- Global providers: `src/layout`
|
- Global providers: `src/layout`
|
||||||
- Zustand stores: `src/store`
|
- Zustand stores: `src/store`
|
||||||
- Client Services: `src/services/`
|
- Client Services: `src/services/` cross-platform services
|
||||||
- clientDB: `src/services/<domain>/client.ts`
|
- clientDB: `src/services/<domain>/client.ts`
|
||||||
- serverDB: `src/services/<domain>/server.ts`
|
- serverDB: `src/services/<domain>/server.ts`
|
||||||
- API Routers:
|
- API Routers:
|
||||||
- `src/app/(backend)/webapi` (REST)
|
- `src/app/(backend)/webapi` (REST)
|
||||||
- `src/server/routers/{edge|lambda|async|desktop|tools}` (tRPC)
|
- `src/server/routers/{edge|lambda|async|desktop|tools}` (tRPC)
|
||||||
- Server:
|
- Server:
|
||||||
- Services(can access serverDB): `src/server/services`
|
- Services(can access serverDB): `src/server/services` server-used-only services
|
||||||
- Modules(can't access db): `src/server/modules` (Server only Third-party Service Module)
|
- Modules(can't access db): `src/server/modules` (Server only Third-party Service Module)
|
||||||
- Database:
|
- Database:
|
||||||
- Schema (Drizzle): `packages/database/src/schemas`
|
- Schema (Drizzle): `packages/database/src/schemas`
|
||||||
@@ -113,8 +115,8 @@ lobe-chat/
|
|||||||
|
|
||||||
## Data Flow Architecture
|
## Data Flow Architecture
|
||||||
|
|
||||||
- **Browser/PWA**: React UI → Client Service → Direct Model Access → PGLite (Web WASM)
|
- **Web with ClientDB**: React UI → Client Service → Direct Model Access → PGLite (Web WASM)
|
||||||
- **Server**: React UI → Client Service → tRPC Lambda → Server Services → PostgreSQL (Remote)
|
- **Web with ServerDB**: React UI → Client Service → tRPC Lambda → Server Services → PostgreSQL (Remote)
|
||||||
- **Desktop**:
|
- **Desktop**:
|
||||||
- Cloud sync disabled: Electron UI → Client Service → tRPC Lambda → Local Server Services → PGLite (Node WASM)
|
- Cloud sync disabled: Electron UI → Client Service → tRPC Lambda → Local Server Services → PGLite (Node WASM)
|
||||||
- Cloud sync enabled: Electron UI → Client Service → tRPC Lambda → Cloud Server Services → PostgreSQL (Remote)
|
- Cloud sync enabled: Electron UI → Client Service → tRPC Lambda → Cloud Server Services → PostgreSQL (Remote)
|
||||||
|
|||||||
@@ -29,16 +29,11 @@ alwaysApply: false
|
|||||||
|
|
||||||
## Code Structure and Readability
|
## Code Structure and Readability
|
||||||
|
|
||||||
- Refactor repeated logic into reusable functions.
|
|
||||||
- Prefer object destructuring when accessing and using properties.
|
- Prefer object destructuring when accessing and using properties.
|
||||||
- Use consistent, descriptive naming; avoid obscure abbreviations.
|
- Use consistent, descriptive naming; avoid obscure abbreviations.
|
||||||
- Use semantically meaningful variable, function, and class names.
|
- Use semantically meaningful variable, function, and class names.
|
||||||
- Replace magic numbers or strings with well-named constants.
|
- Replace magic numbers or strings with well-named constants.
|
||||||
- Keep meaningful code comments; do not remove them when applying edits. Update comments when behavior changes.
|
|
||||||
- Ensure JSDoc comments accurately reflect the implementation.
|
|
||||||
- Look for opportunities to simplify or modernize code with the latest JavaScript/TypeScript features where it improves clarity.
|
|
||||||
- Defer formatting to tooling; ignore purely formatting-only issues and autofixable lint problems.
|
- Defer formatting to tooling; ignore purely formatting-only issues and autofixable lint problems.
|
||||||
- Respect project Prettier settings.
|
|
||||||
|
|
||||||
## UI and Theming
|
## UI and Theming
|
||||||
|
|
||||||
@@ -50,15 +45,14 @@ alwaysApply: false
|
|||||||
## Performance
|
## Performance
|
||||||
|
|
||||||
- Prefer `for…of` loops to index-based `for` loops when feasible.
|
- Prefer `for…of` loops to index-based `for` loops when feasible.
|
||||||
- Decide whether callbacks should be debounced or throttled based on UX and performance needs.
|
- Reuse existing utils inside `packages/utils` or installed npm packages rather than reinventing the wheel.
|
||||||
- Reuse existing npm packages rather than reinventing the wheel (e.g., `lodash-es/omit`).
|
|
||||||
- Query only the required columns from a database rather than selecting entire rows.
|
- Query only the required columns from a database rather than selecting entire rows.
|
||||||
|
|
||||||
## Time and Consistency
|
## Time and Consistency
|
||||||
|
|
||||||
- Instead of calling `Date.now()` multiple times, assign it to a constant once and reuse it to ensure consistency and improve readability.
|
- Instead of calling `Date.now()` multiple times, assign it to a constant once and reuse it to ensure consistency and improve readability.
|
||||||
|
|
||||||
## Some logging rules
|
## Logging
|
||||||
|
|
||||||
- Never log user private information like api key, etc
|
- Never log user private information like api key, etc
|
||||||
- Don't use `import { log } from 'debug'` to log messages, because it will directly log the message to the console.
|
- Don't use `import { log } from 'debug'` to log messages, because it will directly log the message to the console.
|
||||||
|
|||||||
20
.github/workflows/desktop-pr-build.yml
vendored
20
.github/workflows/desktop-pr-build.yml
vendored
@@ -95,7 +95,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, macos-13, windows-2025, ubuntu-latest]
|
os: [macos-latest, macos-15-intel, windows-2025, ubuntu-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
@@ -129,11 +129,11 @@ jobs:
|
|||||||
run: npm run desktop:build
|
run: npm run desktop:build
|
||||||
env:
|
env:
|
||||||
# 设置更新通道,PR构建为nightly,否则为stable
|
# 设置更新通道,PR构建为nightly,否则为stable
|
||||||
UPDATE_CHANNEL: 'nightly'
|
UPDATE_CHANNEL: "nightly"
|
||||||
APP_URL: http://localhost:3015
|
APP_URL: http://localhost:3015
|
||||||
DATABASE_URL: 'postgresql://postgres@localhost:5432/postgres'
|
DATABASE_URL: "postgresql://postgres@localhost:5432/postgres"
|
||||||
# 默认添加一个加密 SECRET
|
# 默认添加一个加密 SECRET
|
||||||
KEY_VAULTS_SECRET: 'oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE='
|
KEY_VAULTS_SECRET: "oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE="
|
||||||
# macOS 签名和公证配置
|
# macOS 签名和公证配置
|
||||||
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
|
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
|
||||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||||
@@ -152,10 +152,10 @@ jobs:
|
|||||||
run: npm run desktop:build
|
run: npm run desktop:build
|
||||||
env:
|
env:
|
||||||
# 设置更新通道,PR构建为nightly,否则为stable
|
# 设置更新通道,PR构建为nightly,否则为stable
|
||||||
UPDATE_CHANNEL: 'nightly'
|
UPDATE_CHANNEL: "nightly"
|
||||||
APP_URL: http://localhost:3015
|
APP_URL: http://localhost:3015
|
||||||
DATABASE_URL: 'postgresql://postgres@localhost:5432/postgres'
|
DATABASE_URL: "postgresql://postgres@localhost:5432/postgres"
|
||||||
KEY_VAULTS_SECRET: 'oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE='
|
KEY_VAULTS_SECRET: "oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE="
|
||||||
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_PROJECT_ID }}
|
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_PROJECT_ID }}
|
||||||
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_BASE_URL }}
|
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_BASE_URL }}
|
||||||
# 将 TEMP 和 TMP 目录设置到 C 盘
|
# 将 TEMP 和 TMP 目录设置到 C 盘
|
||||||
@@ -168,10 +168,10 @@ jobs:
|
|||||||
run: npm run desktop:build
|
run: npm run desktop:build
|
||||||
env:
|
env:
|
||||||
# 设置更新通道,PR构建为nightly,否则为stable
|
# 设置更新通道,PR构建为nightly,否则为stable
|
||||||
UPDATE_CHANNEL: 'nightly'
|
UPDATE_CHANNEL: "nightly"
|
||||||
APP_URL: http://localhost:3015
|
APP_URL: http://localhost:3015
|
||||||
DATABASE_URL: 'postgresql://postgres@localhost:5432/postgres'
|
DATABASE_URL: "postgresql://postgres@localhost:5432/postgres"
|
||||||
KEY_VAULTS_SECRET: 'oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE='
|
KEY_VAULTS_SECRET: "oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE="
|
||||||
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_PROJECT_ID }}
|
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_PROJECT_ID }}
|
||||||
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_BASE_URL }}
|
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_NIGHTLY_DESKTOP_BASE_URL }}
|
||||||
|
|
||||||
|
|||||||
14
.github/workflows/release-desktop-beta.yml
vendored
14
.github/workflows/release-desktop-beta.yml
vendored
@@ -82,7 +82,7 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [macos-latest, macos-13, windows-2025, ubuntu-latest]
|
os: [macos-latest, macos-15-intel, windows-2025, ubuntu-latest]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v5
|
||||||
with:
|
with:
|
||||||
@@ -116,9 +116,9 @@ jobs:
|
|||||||
run: npm run desktop:build
|
run: npm run desktop:build
|
||||||
env:
|
env:
|
||||||
APP_URL: http://localhost:3015
|
APP_URL: http://localhost:3015
|
||||||
DATABASE_URL: 'postgresql://postgres@localhost:5432/postgres'
|
DATABASE_URL: "postgresql://postgres@localhost:5432/postgres"
|
||||||
# 默认添加一个加密 SECRET
|
# 默认添加一个加密 SECRET
|
||||||
KEY_VAULTS_SECRET: 'oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE='
|
KEY_VAULTS_SECRET: "oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE="
|
||||||
# macOS 签名和公证配置
|
# macOS 签名和公证配置
|
||||||
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
|
CSC_LINK: ${{ secrets.APPLE_CERTIFICATE_BASE64 }}
|
||||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
|
||||||
@@ -137,8 +137,8 @@ jobs:
|
|||||||
run: npm run desktop:build
|
run: npm run desktop:build
|
||||||
env:
|
env:
|
||||||
APP_URL: http://localhost:3015
|
APP_URL: http://localhost:3015
|
||||||
DATABASE_URL: 'postgresql://postgres@localhost:5432/postgres'
|
DATABASE_URL: "postgresql://postgres@localhost:5432/postgres"
|
||||||
KEY_VAULTS_SECRET: 'oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE='
|
KEY_VAULTS_SECRET: "oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE="
|
||||||
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_BETA_DESKTOP_PROJECT_ID }}
|
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_BETA_DESKTOP_PROJECT_ID }}
|
||||||
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_BETA_DESKTOP_BASE_URL }}
|
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_BETA_DESKTOP_BASE_URL }}
|
||||||
|
|
||||||
@@ -152,8 +152,8 @@ jobs:
|
|||||||
run: npm run desktop:build
|
run: npm run desktop:build
|
||||||
env:
|
env:
|
||||||
APP_URL: http://localhost:3015
|
APP_URL: http://localhost:3015
|
||||||
DATABASE_URL: 'postgresql://postgres@localhost:5432/postgres'
|
DATABASE_URL: "postgresql://postgres@localhost:5432/postgres"
|
||||||
KEY_VAULTS_SECRET: 'oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE='
|
KEY_VAULTS_SECRET: "oLXWIiR/AKF+rWaqy9lHkrYgzpATbW3CtJp3UfkVgpE="
|
||||||
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_BETA_DESKTOP_PROJECT_ID }}
|
NEXT_PUBLIC_DESKTOP_PROJECT_ID: ${{ secrets.UMAMI_BETA_DESKTOP_PROJECT_ID }}
|
||||||
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_BETA_DESKTOP_BASE_URL }}
|
NEXT_PUBLIC_DESKTOP_UMAMI_BASE_URL: ${{ secrets.UMAMI_BETA_DESKTOP_BASE_URL }}
|
||||||
|
|
||||||
|
|||||||
24
CLAUDE.md
24
CLAUDE.md
@@ -31,28 +31,18 @@ This repository adopts a monorepo structure.
|
|||||||
|
|
||||||
see @.cursor/rules/typescript.mdc
|
see @.cursor/rules/typescript.mdc
|
||||||
|
|
||||||
### Modify Code Rules
|
|
||||||
|
|
||||||
- **Code Language**:
|
|
||||||
- For files with existing Chinese comments: Continue using Chinese to maintain consistency
|
|
||||||
- For new files or files without Chinese comments: MUST use American English.
|
|
||||||
- eg: new react tsx file and new test file
|
|
||||||
- Conservative for existing code, modern approaches for new features
|
|
||||||
|
|
||||||
### Testing
|
### Testing
|
||||||
|
|
||||||
Testing work follows the Rule-Aware Task Execution system above.
|
- **Required Rule**: read `@.cursor/rules/testing-guide/testing-guide.mdc` before writing tests
|
||||||
|
|
||||||
- **Required Rule**: `testing-guide/testing-guide.mdc`
|
|
||||||
- **Command**:
|
- **Command**:
|
||||||
- web: `bunx vitest run --silent='passed-only' '[file-path-pattern]'`
|
- web: `bunx vitest run --silent='passed-only' '[file-path-pattern]'`
|
||||||
- packages(eg: database): `cd packages/database && bunx vitest run --silent='passed-only' '[file-path-pattern]'`
|
- packages(eg: database): `cd packages/database && bunx vitest run --silent='passed-only' '[file-path-pattern]'`
|
||||||
|
|
||||||
**Important**:
|
**Important**:
|
||||||
|
|
||||||
- wrapped the file path in single quotes to avoid shell expansion
|
- wrap the file path in single quotes to avoid shell expansion
|
||||||
- Never run `bun run test` etc to run tests, this will run all tests and cost about 10mins
|
- Never run `bun run test` etc to run tests, this will run all tests and cost about 10mins
|
||||||
- If try to fix the same test twice, but still failed, stop and ask for help.
|
- If trying to fix the same test twice, but still failed, stop and ask for help.
|
||||||
|
|
||||||
### Typecheck
|
### Typecheck
|
||||||
|
|
||||||
@@ -61,15 +51,9 @@ Testing work follows the Rule-Aware Task Execution system above.
|
|||||||
### i18n
|
### i18n
|
||||||
|
|
||||||
- **Keys**: Add to `src/locales/default/namespace.ts`
|
- **Keys**: Add to `src/locales/default/namespace.ts`
|
||||||
- **Dev**: Translate `locales/zh-CN/namespace.json` locale file only for preview
|
- **Dev**: Translate `locales/zh-CN/namespace.json` and `locales/en-US/namespace.json` locales file only for dev preview
|
||||||
- DON'T run `pnpm i18n`, let CI auto handle it
|
- DON'T run `pnpm i18n`, let CI auto handle it
|
||||||
|
|
||||||
## Rules Index
|
## Rules Index
|
||||||
|
|
||||||
Some useful rules of this project. Read them when needed.
|
|
||||||
|
|
||||||
**IMPORTANT**: All rule files referenced in this document are located in the `.cursor/rules/` directory. Throughout this document, rule files are referenced by their filename only for brevity.
|
|
||||||
|
|
||||||
### 📋 Complete Rule Files
|
|
||||||
|
|
||||||
Some useful project rules are listed in @.cursor/rules/rules-index.mdc
|
Some useful project rules are listed in @.cursor/rules/rules-index.mdc
|
||||||
|
|||||||
BIN
apps/desktop/build/Icon-beta.Assets.car
Normal file
BIN
apps/desktop/build/Icon-beta.Assets.car
Normal file
Binary file not shown.
BIN
apps/desktop/build/Icon-dev.Assets.car
Normal file
BIN
apps/desktop/build/Icon-dev.Assets.car
Normal file
Binary file not shown.
BIN
apps/desktop/build/Icon-nightly.Assets.car
Normal file
BIN
apps/desktop/build/Icon-nightly.Assets.car
Normal file
Binary file not shown.
BIN
apps/desktop/build/Icon.Assets.car
Normal file
BIN
apps/desktop/build/Icon.Assets.car
Normal file
Binary file not shown.
@@ -1,5 +1,7 @@
|
|||||||
const dotenv = require('dotenv');
|
const dotenv = require('dotenv');
|
||||||
|
const fs = require('node:fs/promises');
|
||||||
const os = require('node:os');
|
const os = require('node:os');
|
||||||
|
const path = require('node:path');
|
||||||
|
|
||||||
dotenv.config();
|
dotenv.config();
|
||||||
|
|
||||||
@@ -32,11 +34,50 @@ const getProtocolScheme = () => {
|
|||||||
|
|
||||||
const protocolScheme = getProtocolScheme();
|
const protocolScheme = getProtocolScheme();
|
||||||
|
|
||||||
|
// Determine icon file based on version type
|
||||||
|
const getIconFileName = () => {
|
||||||
|
if (isNightly) return 'Icon-nightly';
|
||||||
|
if (isBeta) return 'Icon-beta';
|
||||||
|
return 'Icon';
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {import('electron-builder').Configuration}
|
* @type {import('electron-builder').Configuration}
|
||||||
* @see https://www.electron.build/configuration
|
* @see https://www.electron.build/configuration
|
||||||
*/
|
*/
|
||||||
const config = {
|
const config = {
|
||||||
|
/**
|
||||||
|
* AfterPack hook to copy pre-generated Liquid Glass Assets.car for macOS 26+
|
||||||
|
* @see https://github.com/electron-userland/electron-builder/issues/9254
|
||||||
|
* @see https://github.com/MultiboxLabs/flow-browser/pull/159
|
||||||
|
* @see https://github.com/electron/packager/pull/1806
|
||||||
|
*/
|
||||||
|
afterPack: async (context) => {
|
||||||
|
// Only process macOS builds
|
||||||
|
if (context.electronPlatformName !== 'darwin') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const iconFileName = getIconFileName();
|
||||||
|
const assetsCarSource = path.join(__dirname, 'build', `${iconFileName}.Assets.car`);
|
||||||
|
const resourcesPath = path.join(
|
||||||
|
context.appOutDir,
|
||||||
|
`${context.packager.appInfo.productFilename}.app`,
|
||||||
|
'Contents',
|
||||||
|
'Resources',
|
||||||
|
);
|
||||||
|
const assetsCarDest = path.join(resourcesPath, 'Assets.car');
|
||||||
|
|
||||||
|
try {
|
||||||
|
await fs.access(assetsCarSource);
|
||||||
|
await fs.copyFile(assetsCarSource, assetsCarDest);
|
||||||
|
console.log(`✅ Copied Liquid Glass icon: ${iconFileName}.Assets.car`);
|
||||||
|
} catch {
|
||||||
|
// Non-critical: Assets.car not found or copy failed
|
||||||
|
// App will use fallback .icns icon on all macOS versions
|
||||||
|
console.log(`⏭️ Skipping Assets.car (not found or copy failed)`);
|
||||||
|
}
|
||||||
|
},
|
||||||
appId: isNightly
|
appId: isNightly
|
||||||
? 'com.lobehub.lobehub-desktop-nightly'
|
? 'com.lobehub.lobehub-desktop-nightly'
|
||||||
: isBeta
|
: isBeta
|
||||||
@@ -81,6 +122,7 @@ const config = {
|
|||||||
compression: 'maximum',
|
compression: 'maximum',
|
||||||
entitlementsInherit: 'build/entitlements.mac.plist',
|
entitlementsInherit: 'build/entitlements.mac.plist',
|
||||||
extendInfo: {
|
extendInfo: {
|
||||||
|
CFBundleIconName: 'AppIcon',
|
||||||
CFBundleURLTypes: [
|
CFBundleURLTypes: [
|
||||||
{
|
{
|
||||||
CFBundleURLName: 'LobeHub Protocol',
|
CFBundleURLName: 'LobeHub Protocol',
|
||||||
|
|||||||
Reference in New Issue
Block a user