diff --git a/cc-haha/desktop/public/app-icon.png b/cc-haha/desktop/public/app-icon.png index 91fe0b8..26b60c1 100644 Binary files a/cc-haha/desktop/public/app-icon.png and b/cc-haha/desktop/public/app-icon.png differ diff --git a/cc-haha/desktop/scripts/build-macos-arm64.sh b/cc-haha/desktop/scripts/build-macos-arm64.sh index 407d771..4a1f615 100755 --- a/cc-haha/desktop/scripts/build-macos-arm64.sh +++ b/cc-haha/desktop/scripts/build-macos-arm64.sh @@ -9,12 +9,14 @@ REPO_ROOT="$(cd "${DESKTOP_DIR}/.." && pwd)" TARGET_TRIPLE="aarch64-apple-darwin" TAURI_TARGET_DIR="${DESKTOP_DIR}/src-tauri/target" CANONICAL_OUTPUT_DIR="${DESKTOP_DIR}/build-artifacts/macos-arm64" -APP_BUNDLE_NAME="Claude Code Haha.app" -APP_BUNDLE_ID="com.claude-code-haha.desktop" +APP_BUNDLE_NAME="HeiCode.app" +APP_BUNDLE_ID="com.heicode.desktop" +DMG_VOLUME_NAME="Heicode" +DEFAULT_DMG_BASENAME="Heicode_0.1.0_aarch64.dmg" usage() { cat <<'EOF' -Build Claude Code Haha desktop for macOS Apple Silicon and output a DMG. +Build Heicode desktop for macOS Apple Silicon and output a DMG. Usage: ./desktop/scripts/build-macos-arm64.sh [extra tauri build args...] @@ -79,10 +81,10 @@ rm -rf "${DESKTOP_DIR}/src-tauri/target/${TARGET_TRIPLE}/release/bundle" rm -rf "${DESKTOP_DIR}/src-tauri/target/release/bundle" rm -rf "${DESKTOP_DIR}/dist" rm -f "${DESKTOP_DIR}/tsconfig.tsbuildinfo" -rm -rf "${DESKTOP_DIR}/src-tauri/target/${TARGET_TRIPLE}/release/build/claude-code-desktop-"* -rm -rf "${DESKTOP_DIR}/src-tauri/target/${TARGET_TRIPLE}/release/.fingerprint/claude-code-desktop-"* -rm -f "${DESKTOP_DIR}/src-tauri/target/${TARGET_TRIPLE}/release/deps/claude_code_desktop-"* -rm -f "${DESKTOP_DIR}/src-tauri/target/${TARGET_TRIPLE}/release/deps/libclaude_code_desktop-"* +rm -rf "${DESKTOP_DIR}/src-tauri/target/${TARGET_TRIPLE}/release/build/heicode-desktop-"* +rm -rf "${DESKTOP_DIR}/src-tauri/target/${TARGET_TRIPLE}/release/.fingerprint/heicode-desktop-"* +rm -f "${DESKTOP_DIR}/src-tauri/target/${TARGET_TRIPLE}/release/deps/heicode_desktop-"* +rm -f "${DESKTOP_DIR}/src-tauri/target/${TARGET_TRIPLE}/release/deps/libheicode_desktop-"* echo "[build-macos-arm64] Rebuilding frontend (tsc + vite)..." (cd "${DESKTOP_DIR}" && bun run build) @@ -159,15 +161,15 @@ build_canonical_dmg() { local staging_dir local rw_dmg - staging_dir="$(mktemp -d "${TMPDIR:-/tmp}/cc-haha-dmg.XXXXXX")" - rw_dmg="$(mktemp "${TMPDIR:-/tmp}/cc-haha-rw.XXXXXX").dmg" + staging_dir="$(mktemp -d "${TMPDIR:-/tmp}/heicode-dmg.XXXXXX")" + rw_dmg="$(mktemp "${TMPDIR:-/tmp}/heicode-rw.XXXXXX").dmg" cp -R "${app_bundle}" "${staging_dir}/" ln -s /Applications "${staging_dir}/Applications" # Create a read-write DMG first so we can customize the Finder layout hdiutil create \ - -volname "Claude Code Haha" \ + -volname "${DMG_VOLUME_NAME}" \ -srcfolder "${staging_dir}" \ -ov \ -format UDRW \ @@ -188,7 +190,7 @@ build_canonical_dmg() { # 所以这里允许 osascript 非零退出,只 warn,不让 set -e 炸掉整个脚本。 if ! osascript < "${CANONICAL_OUTPUT_DIR}/BUILD_INFO.txt" <=250 RGB as white). + gray = img.convert("L") + mask = gray.point(lambda v: 0 if v >= 250 else 255) + bbox = mask.getbbox() + if bbox: + img = img.crop(bbox) + # Pad to square on white. + w, h = img.size + side = max(w, h) + canvas = Image.new("RGB", (side, side), (255, 255, 255)) + canvas.paste(img, ((side - w) // 2, (side - h) // 2)) + return canvas + +def to_rgba_with_transparent_white(img: Image.Image, threshold: int = 248) -> Image.Image: + rgba = img.convert("RGBA") + pixels = rgba.load() + w, h = rgba.size + for y in range(h): + for x in range(w): + r, g, b, _ = pixels[x, y] + if r >= threshold and g >= threshold and b >= threshold: + pixels[x, y] = (r, g, b, 0) + return rgba + +def main(): + base = load_trimmed_square() + print(f"Trimmed source: {base.size}") + + # PNG outputs (RGB on white → looks correct on any background, matches glass edges). + sizes = { + TAURI_ICONS / "32x32.png": 32, + TAURI_ICONS / "64x64.png": 64, + TAURI_ICONS / "128x128.png": 128, + TAURI_ICONS / "128x128@2x.png": 256, + TAURI_ICONS / "icon.png": 1024, + PUBLIC / "app-icon.png": 1024, + } + for path, size in sizes.items(): + path.parent.mkdir(parents=True, exist_ok=True) + base.resize((size, size), Image.LANCZOS).save(path, "PNG") + print(f"wrote {path} ({size})") + + # Windows Square*Logo / StoreLogo + win_sizes = { + "Square30x30Logo.png": 30, + "Square44x44Logo.png": 44, + "Square71x71Logo.png": 71, + "Square89x89Logo.png": 89, + "Square107x107Logo.png": 107, + "Square142x142Logo.png": 142, + "Square150x150Logo.png": 150, + "Square284x284Logo.png": 284, + "Square310x310Logo.png": 310, + "StoreLogo.png": 50, + } + for name, size in win_sizes.items(): + path = TAURI_ICONS / name + base.resize((size, size), Image.LANCZOS).save(path, "PNG") + print(f"wrote {path} ({size})") + + # ICO with multi-resolution. + ico_path = TAURI_ICONS / "icon.ico" + base.save(ico_path, format="ICO", sizes=[(16,16),(24,24),(32,32),(48,48),(64,64),(128,128),(256,256)]) + print(f"wrote {ico_path}") + + # ICNS (PIL supports it). Required sizes: 16,32,64,128,256,512,1024. + icns_path = TAURI_ICONS / "icon.icns" + base.save(icns_path, format="ICNS", sizes=[(16,16),(32,32),(64,64),(128,128),(256,256),(512,512),(1024,1024)]) + print(f"wrote {icns_path}") + +if __name__ == "__main__": + main()