diff --git a/AGENTS.md b/AGENTS.md index 56416c0..6b21276 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## Scope -This repository contains the offline macOS Community App, its loopback-only +This repository contains the offline macOS App, its loopback-only theme engine, three original starter themes, and tests. Do not add production backend, deployment, Firebase, analytics, remote-device, account, or update infrastructure. diff --git a/CHANGELOG.md b/CHANGELOG.md index bb1c4e9..4be5920 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 0.1.0 — 2026-08-11 -- Added a native, offline macOS Community App for applying and restoring Codex +- Added a native, offline macOS App for applying and restoring Codex themes. - Included three original starter themes and an open local theme format. - Added loopback-only injection, signature validation, transactional theme diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cf5ece8..3d4333d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,9 @@ # Contributing -Thank you for helping improve AI ThemeStore Community. +Thank you for helping improve AI ThemeStore. 1. Fork the repository and create a focused branch. -2. Keep changes within the offline Community scope. +2. Keep changes within the offline, local-only project scope. 3. Run `./tests/run-tests.sh` on macOS. 4. Describe the user impact and actual checks in the pull request. 5. Include screenshots for visual changes. diff --git a/NOTICE.md b/NOTICE.md index 527a979..9f282be 100644 --- a/NOTICE.md +++ b/NOTICE.md @@ -1,6 +1,6 @@ # Notices -AI ThemeStore Community is an unofficial customization project. It is not +AI ThemeStore is an unofficial customization project. It is not affiliated with, endorsed by, or sponsored by OpenAI. The MIT License applies to the source code and the three original starter @@ -14,7 +14,7 @@ UI, text, or watermarks. Screenshots under `docs/images/` are sanitized, high-fidelity previews rendered with project-owned themes. Some showcase themes come from the wider ThemeStore -catalog and are not bundled with this Community app. The previews contain a +catalog and are not bundled with this app. The previews contain a simulated Codex interface for demonstration only and no real account, project, or conversation data. No third-party character fan artwork is included. OpenAI and Codex names and interface elements remain the property of their respective diff --git a/Package.swift b/Package.swift index eb76198..f60c852 100644 --- a/Package.swift +++ b/Package.swift @@ -3,18 +3,18 @@ import PackageDescription let package = Package( - name: "AIThemeStoreCommunity", + name: "AIThemeStore", platforms: [.macOS(.v13)], products: [ .executable( - name: "ai-themestore-community", - targets: ["AIThemeStoreCommunity"] + name: "ai-themestore", + targets: ["AIThemeStore"] ), ], targets: [ .executableTarget( - name: "AIThemeStoreCommunity", - path: "Sources/AIThemeStoreCommunity" + name: "AIThemeStore", + path: "Sources/AIThemeStore" ), ] ) diff --git a/README.md b/README.md index b3e2bf1..c98010a 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,19 @@ English · 简体中文

-# AI ThemeStore Community +# AI ThemeStore An open-source, offline theme app for **Codex Desktop on macOS**. It gives the Codex workspace a visual identity while keeping the official app intact and making every change reversible. -[![macOS 13+](https://img.shields.io/badge/macOS-13%2B-111827?logo=apple)](https://github.com/hackergene/AI-ThemeStore-Community/releases/latest) +[![macOS 13+](https://img.shields.io/badge/macOS-13%2B-111827?logo=apple)](https://github.com/hackergene/AI-ThemeStore/releases/latest) [![SwiftUI App](https://img.shields.io/badge/app-SwiftUI-F05138?logo=swift&logoColor=white)](#technology-stack) [![JavaScript Engine](https://img.shields.io/badge/engine-JavaScript-F7DF1E?logo=javascript&logoColor=111827)](#technology-stack) [![MIT License](https://img.shields.io/badge/license-MIT-25D9FF.svg)](./LICENSE) [![Offline](https://img.shields.io/badge/runtime-offline-8A6CFF.svg)](#privacy-and-safety) -> AI ThemeStore Community is an independent, unofficial project. It is not +> AI ThemeStore is an independent, unofficial project. It is not > affiliated with, endorsed by, or sponsored by OpenAI. ## Codex, themed @@ -41,7 +41,7 @@ No third-party character fan art is included in this repository. ## Technology stack -AI ThemeStore Community is a hybrid native macOS app: **Swift and SwiftUI** +AI ThemeStore is a hybrid native macOS app: **Swift and SwiftUI** provide the application interface, while a local **JavaScript and CSS theme engine** handles Codex theming, verification, and recovery. @@ -58,7 +58,7 @@ JavaScript even though the user-facing application is native SwiftUI. ## What we learned from theming Codex Codex is a living product, so a durable theme cannot be just a wallpaper or a -collection of fragile selectors. The Community engine is built around a few +collection of fragile selectors. The theme engine is built around a few practical lessons: 1. **Theme the complete workflow.** New Chat and active tasks must share the @@ -80,7 +80,7 @@ customization boundary understandable and recoverable. ### Download -Download the latest build from [GitHub Releases](https://github.com/hackergene/AI-ThemeStore-Community/releases/latest). +Download the latest build from [GitHub Releases](https://github.com/hackergene/AI-ThemeStore/releases/latest). ### Build from source @@ -88,18 +88,18 @@ Requirements: macOS 13 or newer, the official Codex Desktop app, and Xcode Command Line Tools. ```bash -git clone https://github.com/hackergene/AI-ThemeStore-Community.git -cd AI-ThemeStore-Community +git clone https://github.com/hackergene/AI-ThemeStore.git +cd AI-ThemeStore ./scripts/build-app.sh -open "dist/AI ThemeStore Community.app" +open "dist/AI ThemeStore.app" ``` -The build script creates the Community app locally. It does not modify or +The build script creates the app locally. It does not modify or re-sign the official Codex app. ### Use the app -1. Open AI ThemeStore Community. +1. Open AI ThemeStore. 2. Select a local theme and choose **Apply Theme**. 3. The app restarts Codex and verifies the themed New Chat and task surfaces. 4. Choose **Restore Codex Appearance** whenever you want the native look back. @@ -122,12 +122,12 @@ a minimal example. ## Privacy and safety -The Community edition works offline and contains no telemetry or account code. +AI ThemeStore works offline and contains no telemetry or account code. Its debugging connection is bound to `127.0.0.1` only. Because a local debugging port is sensitive while a theme is active, avoid running untrusted local software at the same time. Read the full boundary in [SECURITY.md](./SECURITY.md). -## Community and full edition +## Project scope This repository is intentionally focused on a small, auditable, offline Codex theme experience. The broader theme catalog and hosted browsing experience are diff --git a/README.zh-CN.md b/README.zh-CN.md index ccba5ea..e098f67 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -2,18 +2,18 @@ English · 简体中文

-# AI ThemeStore Community +# AI ThemeStore 一套面向 **macOS Codex Desktop** 的开源离线主题 App。它可以为 Codex 工作区加入完整的视觉主题,同时保持官方 App 完整,所有改动均可恢复。 -[![macOS 13+](https://img.shields.io/badge/macOS-13%2B-111827?logo=apple)](https://github.com/hackergene/AI-ThemeStore-Community/releases/latest) +[![macOS 13+](https://img.shields.io/badge/macOS-13%2B-111827?logo=apple)](https://github.com/hackergene/AI-ThemeStore/releases/latest) [![SwiftUI App](https://img.shields.io/badge/app-SwiftUI-F05138?logo=swift&logoColor=white)](#技术栈) [![JavaScript Engine](https://img.shields.io/badge/engine-JavaScript-F7DF1E?logo=javascript&logoColor=111827)](#技术栈) [![MIT License](https://img.shields.io/badge/license-MIT-25D9FF.svg)](./LICENSE) [![Offline](https://img.shields.io/badge/runtime-offline-8A6CFF.svg)](#隐私与安全) -> AI ThemeStore Community 是独立的非官方项目,与 OpenAI 无隶属、背书或赞助关系。 +> AI ThemeStore 是独立的非官方项目,与 OpenAI 无隶属、背书或赞助关系。 ## Codex 主题效果 @@ -37,7 +37,7 @@ ## 技术栈 -AI ThemeStore Community 是一套混合架构的原生 macOS App:**Swift 与 +AI ThemeStore 是一套混合架构的原生 macOS App:**Swift 与 SwiftUI** 提供应用界面,本地 **JavaScript 与 CSS 主题引擎**负责 Codex 主题应用、验证和恢复。 @@ -54,7 +54,7 @@ GitHub 的语言标签依据源码字节数计算,因此即使用户看到的 ## 适配 Codex 的实践经验 Codex 是持续演进的产品,因此稳定主题不能只是一张壁纸,也不能依赖一组脆弱的 -选择器。Community 引擎基于以下实践构建: +选择器。主题引擎基于以下实践构建: 1. **覆盖完整工作流。** New Chat 与运行中任务应使用统一视觉语言,包括任务卡、 输入区、侧边栏和分层面板。 @@ -74,7 +74,7 @@ Codex 是持续演进的产品,因此稳定主题不能只是一张壁纸, ### 下载 -从 [GitHub Releases](https://github.com/hackergene/AI-ThemeStore-Community/releases/latest) +从 [GitHub Releases](https://github.com/hackergene/AI-ThemeStore/releases/latest) 下载最新版本。 ### 从源码构建 @@ -82,17 +82,17 @@ Codex 是持续演进的产品,因此稳定主题不能只是一张壁纸, 需要 macOS 13 或更高版本、官方 Codex Desktop App,以及 Xcode Command Line Tools。 ```bash -git clone https://github.com/hackergene/AI-ThemeStore-Community.git -cd AI-ThemeStore-Community +git clone https://github.com/hackergene/AI-ThemeStore.git +cd AI-ThemeStore ./scripts/build-app.sh -open "dist/AI ThemeStore Community.app" +open "dist/AI ThemeStore.app" ``` -构建脚本只生成本地 Community App,不会修改或重新签名官方 Codex App。 +构建脚本只生成本地 App,不会修改或重新签名官方 Codex App。 ### 使用 App -1. 打开 AI ThemeStore Community。 +1. 打开 AI ThemeStore。 2. 选择本地主题并点击“应用主题”。 3. App 会重启 Codex,并验证 New Chat 与任务页的主题状态。 4. 随时点击“恢复 Codex 外观”即可回到原生界面。 @@ -114,11 +114,11 @@ open "dist/AI ThemeStore Community.app" ## 隐私与安全 -Community 版离线运行,不包含遥测或账号代码。调试连接仅绑定 `127.0.0.1`。 +AI ThemeStore 离线运行,不包含遥测或账号代码。调试连接仅绑定 `127.0.0.1`。 主题启用期间,本地调试端口属于敏感能力,请勿同时运行不可信的本机软件。完整边界 见 [SECURITY.md](./SECURITY.md)。 -## Community 与完整版 +## 项目边界 本仓库有意保持为一套小型、可审计、离线的 Codex 主题体验。更多主题及在线浏览 体验请访问 [themestore.ai](https://themestore.ai)。 diff --git a/Resources/Info.plist b/Resources/Info.plist index 60cde90..2e3e143 100644 --- a/Resources/Info.plist +++ b/Resources/Info.plist @@ -5,17 +5,17 @@ CFBundleDevelopmentRegion zh_CN CFBundleDisplayName - AI ThemeStore Community + AI ThemeStore CFBundleExecutable - ai-themestore-community + ai-themestore CFBundleIconFile AppIcon CFBundleIdentifier - ai.themestore.community + ai.themestore.opensource CFBundleInfoDictionaryVersion 6.0 CFBundleName - AI ThemeStore Community + AI ThemeStore CFBundlePackageType APPL CFBundleShortVersionString diff --git a/SECURITY.md b/SECURITY.md index 29b398e..90e03da 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,11 +2,11 @@ ## Supported version -Security fixes are provided for the latest Community release. +Security fixes are provided for the latest release. ## Runtime boundary -AI ThemeStore Community does not modify the official Codex application. It +AI ThemeStore does not modify the official Codex application. It launches Codex with a Chromium DevTools endpoint bound to `127.0.0.1`, validates the official app and bundled Node.js signatures, and injects only into verified Codex renderer targets. diff --git a/Sources/AIThemeStoreCommunity/AIThemeStoreCommunityApp.swift b/Sources/AIThemeStore/AIThemeStoreApp.swift similarity index 86% rename from Sources/AIThemeStoreCommunity/AIThemeStoreCommunityApp.swift rename to Sources/AIThemeStore/AIThemeStoreApp.swift index edb61a0..7a2ad28 100644 --- a/Sources/AIThemeStoreCommunity/AIThemeStoreCommunityApp.swift +++ b/Sources/AIThemeStore/AIThemeStoreApp.swift @@ -1,7 +1,7 @@ import SwiftUI @main -struct AIThemeStoreCommunityApp: App { +struct AIThemeStoreApp: App { @StateObject private var model = AppModel() var body: some Scene { diff --git a/Sources/AIThemeStoreCommunity/AppModel.swift b/Sources/AIThemeStore/AppModel.swift similarity index 95% rename from Sources/AIThemeStoreCommunity/AppModel.swift rename to Sources/AIThemeStore/AppModel.swift index 1b6c0f3..e619929 100644 --- a/Sources/AIThemeStoreCommunity/AppModel.swift +++ b/Sources/AIThemeStore/AppModel.swift @@ -3,7 +3,7 @@ import Foundation @MainActor final class AppModel: ObservableObject { - @Published private(set) var themes: [CommunityTheme] = [] + @Published private(set) var themes: [ThemeModel] = [] @Published private(set) var runtime = RuntimeStatus.unavailable @Published private(set) var busy = false @Published private(set) var activity = "正在读取本地主题…" @@ -54,7 +54,7 @@ final class AppModel: ObservableObject { } } - func apply(_ theme: CommunityTheme) async { + func apply(_ theme: ThemeModel) async { guard !busy else { return } busy = true activity = "正在应用 \(theme.name)…" diff --git a/Sources/AIThemeStoreCommunity/BridgeClient.swift b/Sources/AIThemeStore/BridgeClient.swift similarity index 90% rename from Sources/AIThemeStoreCommunity/BridgeClient.swift rename to Sources/AIThemeStore/BridgeClient.swift index 01e0b07..d824e42 100644 --- a/Sources/AIThemeStoreCommunity/BridgeClient.swift +++ b/Sources/AIThemeStore/BridgeClient.swift @@ -7,7 +7,7 @@ struct BridgeClient: Sendable { func apply(themeID: String) async throws -> RuntimeStatus { guard ThemeLibrary.isSafeThemeID(themeID) else { - throw CommunityError.invalidTheme("主题 ID 不安全。") + throw ThemeStoreError.invalidTheme("主题 ID 不安全。") } return try await run(action: "apply", themeID: themeID) } @@ -30,7 +30,7 @@ struct BridgeClient: Sendable { return bundled } } - if let root = ProcessInfo.processInfo.environment["THEMESTORE_COMMUNITY_ROOT"] { + if let root = ProcessInfo.processInfo.environment["THEMESTORE_PROJECT_ROOT"] { let development = URL(fileURLWithPath: root, isDirectory: true) .appendingPathComponent("engine/scripts/app-bridge-macos.sh", isDirectory: false) if FileManager.default.isExecutableFile(atPath: development.path) { @@ -41,7 +41,7 @@ struct BridgeClient: Sendable { } private func run(action: String, themeID: String? = nil) async throws -> RuntimeStatus { - guard let executable = executableURL() else { throw CommunityError.bridgeUnavailable } + guard let executable = executableURL() else { throw ThemeStoreError.bridgeUnavailable } let arguments = [action, themeID ?? "", "codex"] let home = FileManager.default.homeDirectoryForCurrentUser.path @@ -66,12 +66,12 @@ struct BridgeClient: Sendable { guard process.terminationStatus == 0 else { let message = String(data: errorData, encoding: .utf8)? .trimmingCharacters(in: .whitespacesAndNewlines) - throw CommunityError.bridgeFailed( + throw ThemeStoreError.bridgeFailed( message?.isEmpty == false ? message! : "本地主题操作失败。" ) } guard let status = try? JSONDecoder().decode(RuntimeStatus.self, from: outputData) else { - throw CommunityError.invalidBridgeResponse + throw ThemeStoreError.invalidBridgeResponse } return status }.value diff --git a/Sources/AIThemeStoreCommunity/ContentView.swift b/Sources/AIThemeStore/ContentView.swift similarity index 97% rename from Sources/AIThemeStoreCommunity/ContentView.swift rename to Sources/AIThemeStore/ContentView.swift index 554de60..f49dcfc 100644 --- a/Sources/AIThemeStoreCommunity/ContentView.swift +++ b/Sources/AIThemeStore/ContentView.swift @@ -32,7 +32,7 @@ struct ContentView: View { .frame(minWidth: 940, minHeight: 680) .task { await model.bootstrap() } .alert( - "AI ThemeStore Community", + "AI ThemeStore", isPresented: Binding( get: { !model.alertMessage.isEmpty }, set: { if !$0 { model.alertMessage = "" } } @@ -49,7 +49,7 @@ struct ContentView: View { VStack(alignment: .leading, spacing: 8) { Text("AI ThemeStore") .font(.system(size: 34, weight: .bold, design: .rounded)) - Text("COMMUNITY · OFFLINE MAC APP") + Text("OPEN SOURCE · OFFLINE MAC APP") .font(.system(size: 12, weight: .semibold, design: .monospaced)) .foregroundStyle(.secondary) Text("选择一套本地主题,为 Codex 换一张会呼吸的脸。") @@ -134,7 +134,7 @@ struct ContentView: View { } private struct ThemeCard: View { - let theme: CommunityTheme + let theme: ThemeModel let active: Bool let disabled: Bool let apply: () -> Void diff --git a/Sources/AIThemeStoreCommunity/Models.swift b/Sources/AIThemeStore/Models.swift similarity index 93% rename from Sources/AIThemeStoreCommunity/Models.swift rename to Sources/AIThemeStore/Models.swift index b7f65f6..df2bcfb 100644 --- a/Sources/AIThemeStoreCommunity/Models.swift +++ b/Sources/AIThemeStore/Models.swift @@ -13,7 +13,7 @@ struct ThemeMetadata: Decodable, Sendable { let assets: Assets } -struct CommunityTheme: Identifiable, Sendable { +struct ThemeModel: Identifiable, Sendable { let id: String let metadata: ThemeMetadata let directoryURL: URL @@ -39,7 +39,7 @@ struct RuntimeStatus: Decodable, Sendable { ) } -enum CommunityError: LocalizedError { +enum ThemeStoreError: LocalizedError { case invalidTheme(String) case bridgeUnavailable case bridgeFailed(String) diff --git a/Sources/AIThemeStoreCommunity/ThemeLibrary.swift b/Sources/AIThemeStore/ThemeLibrary.swift similarity index 82% rename from Sources/AIThemeStoreCommunity/ThemeLibrary.swift rename to Sources/AIThemeStore/ThemeLibrary.swift index af35465..3b12156 100644 --- a/Sources/AIThemeStoreCommunity/ThemeLibrary.swift +++ b/Sources/AIThemeStore/ThemeLibrary.swift @@ -21,7 +21,7 @@ enum ThemeLibrary { static func installBundledThemes() throws { let manager = FileManager.default guard let resourceRoot = Bundle.main.resourceURL else { - throw CommunityError.invalidTheme("App 资源目录不可用。") + throw ThemeStoreError.invalidTheme("App 资源目录不可用。") } let bundledRoot = resourceRoot.appendingPathComponent("themes", isDirectory: true) let destinationRoot = try themesRoot() @@ -40,7 +40,7 @@ enum ThemeLibrary { } } - static func scan() throws -> [CommunityTheme] { + static func scan() throws -> [ThemeModel] { let manager = FileManager.default let root = try themesRoot() let directories = try manager.contentsOfDirectory( @@ -52,10 +52,10 @@ enum ThemeLibrary { .sorted { $0.name.localizedStandardCompare($1.name) == .orderedAscending } } - static func readTheme(at directory: URL) throws -> CommunityTheme { + static func readTheme(at directory: URL) throws -> ThemeModel { let values = try directory.resourceValues(forKeys: [.isDirectoryKey, .isSymbolicLinkKey]) guard values.isDirectory == true, values.isSymbolicLink != true else { - throw CommunityError.invalidTheme("主题目录必须是本地普通目录。") + throw ThemeStoreError.invalidTheme("主题目录必须是本地普通目录。") } let metadataURL = directory.appendingPathComponent("theme.json", isDirectory: false) @@ -67,27 +67,27 @@ enum ThemeLibrary { let size = metadataValues.fileSize, size > 0, size <= 64 * 1024 else { - throw CommunityError.invalidTheme("theme.json 缺失或大小不安全。") + throw ThemeStoreError.invalidTheme("theme.json 缺失或大小不安全。") } let metadata = try JSONDecoder().decode(ThemeMetadata.self, from: Data(contentsOf: metadataURL)) guard isSafeThemeID(metadata.id), metadata.id == directory.lastPathComponent else { - throw CommunityError.invalidTheme("主题 ID 与目录名不一致。") + throw ThemeStoreError.invalidTheme("主题 ID 与目录名不一致。") } guard metadata.name.count <= 80, metadata.version.count <= 32 else { - throw CommunityError.invalidTheme("主题名称或版本号过长。") + throw ThemeStoreError.invalidTheme("主题名称或版本号过长。") } guard metadata.assets.hero == URL(fileURLWithPath: metadata.assets.hero).lastPathComponent, !metadata.assets.hero.contains("/") else { - throw CommunityError.invalidTheme("主题背景必须位于主题目录内。") + throw ThemeStoreError.invalidTheme("主题背景必须位于主题目录内。") } let previewURL = directory.appendingPathComponent(metadata.assets.hero, isDirectory: false) let previewValues = try previewURL.resourceValues(forKeys: [.isRegularFileKey, .isSymbolicLinkKey]) guard previewValues.isRegularFile == true, previewValues.isSymbolicLink != true else { - throw CommunityError.invalidTheme("主题背景不存在或不是普通文件。") + throw ThemeStoreError.invalidTheme("主题背景不存在或不是普通文件。") } - return CommunityTheme( + return ThemeModel( id: metadata.id, metadata: metadata, directoryURL: directory, diff --git a/docs/images/README.md b/docs/images/README.md index e05fd45..e0de0d6 100644 --- a/docs/images/README.md +++ b/docs/images/README.md @@ -7,7 +7,7 @@ project-owned source themes from the wider ThemeStore catalog: - `fortune-code-workshop/hero.png` — original Chinese fortune-workbench collection - `azure-lotus-dharma/hero.png` — original blue Buddha and Zen collection - `ember-ninja-legacy/hero.png` — original, non-franchise ninja world -- `silver-nocturne-rose/hero.png` — ThemeStore Community theme +- `silver-nocturne-rose/hero.png` — original AI ThemeStore theme The original ninja asset is used deliberately instead of the personal-use `hero-ip.png` fan asset. No third-party character fan artwork is included. diff --git a/docs/images/codex-theme-showcase.png b/docs/images/codex-theme-showcase.png index bfa90ab..9c36d2e 100644 Binary files a/docs/images/codex-theme-showcase.png and b/docs/images/codex-theme-showcase.png differ diff --git a/docs/images/x-launch-fortune-code-workshop.png b/docs/images/x-launch-fortune-code-workshop.png index 7123de2..d76285e 100644 Binary files a/docs/images/x-launch-fortune-code-workshop.png and b/docs/images/x-launch-fortune-code-workshop.png differ diff --git a/scripts/build-app.sh b/scripts/build-app.sh index d4378b8..2e5c4d0 100755 --- a/scripts/build-app.sh +++ b/scripts/build-app.sh @@ -4,7 +4,7 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)" ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)" -OUTPUT="${1:-$ROOT/dist/AI ThemeStore Community.app}" +OUTPUT="${1:-$ROOT/dist/AI ThemeStore.app}" case "$OUTPUT" in *.app) ;; @@ -18,21 +18,21 @@ esac /usr/bin/swift build --package-path "$ROOT" --configuration release BIN_DIR="$(/usr/bin/swift build --package-path "$ROOT" --configuration release --show-bin-path)" -TEMP="$(/usr/bin/mktemp -d /tmp/ai-themestore-community.XXXXXX)" +TEMP="$(/usr/bin/mktemp -d /tmp/ai-themestore.XXXXXX)" trap '/bin/rm -rf "$TEMP"' EXIT -APP="$TEMP/AI ThemeStore Community.app" +APP="$TEMP/AI ThemeStore.app" /bin/mkdir -p "$APP/Contents/MacOS" "$APP/Contents/Resources" /bin/cp "$ROOT/Resources/Info.plist" "$APP/Contents/Info.plist" /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $VERSION" "$APP/Contents/Info.plist" /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $(/bin/date -u +%Y%m%d%H%M%S)" "$APP/Contents/Info.plist" -/bin/cp "$BIN_DIR/ai-themestore-community" "$APP/Contents/MacOS/ai-themestore-community" +/bin/cp "$BIN_DIR/ai-themestore" "$APP/Contents/MacOS/ai-themestore" /bin/cp "$ROOT/Resources/Brand/AppIcon.icns" "$APP/Contents/Resources/AppIcon.icns" /bin/cp "$ROOT/Resources/Brand/AppIcon.png" "$APP/Contents/Resources/AppIcon.png" /usr/bin/ditto "$ROOT/engine" "$APP/Contents/Resources/engine" /usr/bin/ditto "$ROOT/themes" "$APP/Contents/Resources/themes" /bin/cp "$ROOT/VERSION" "$APP/Contents/Resources/engine/VERSION" -/bin/chmod 755 "$APP/Contents/MacOS/ai-themestore-community" "$APP/Contents/Resources/engine/scripts/"*.sh +/bin/chmod 755 "$APP/Contents/MacOS/ai-themestore" "$APP/Contents/Resources/engine/scripts/"*.sh /usr/bin/codesign --force --deep --options runtime --sign - "$APP" /usr/bin/codesign --verify --deep --strict "$APP" @@ -44,4 +44,4 @@ if [ -e "$OUTPUT" ]; then esac fi /usr/bin/ditto "$APP" "$OUTPUT" -printf 'Built AI ThemeStore Community %s: %s\n' "$VERSION" "$OUTPUT" +printf 'Built AI ThemeStore %s: %s\n' "$VERSION" "$OUTPUT" diff --git a/scripts/build-release.sh b/scripts/build-release.sh index e15e6d5..4bf495c 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -5,8 +5,8 @@ set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd -P)" ROOT="$(cd "$SCRIPT_DIR/.." && pwd -P)" VERSION="$(/usr/bin/tr -d '[:space:]' < "$ROOT/VERSION")" -APP="$ROOT/dist/AI ThemeStore Community.app" -ZIP="$ROOT/dist/AI-ThemeStore-Community-$VERSION-macos.zip" +APP="$ROOT/dist/AI ThemeStore.app" +ZIP="$ROOT/dist/AI-ThemeStore-$VERSION-macos.zip" "$SCRIPT_DIR/build-app.sh" "$APP" /bin/rm -f "$ZIP" "$ZIP.sha256" diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 620890a..40b60ea 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -46,10 +46,21 @@ done if /usr/bin/grep -R -E -n \ '(Firebase|GoogleService-Info|fast-ai|/home/hackergene|/api/device/|device-identity-v1|production\.env|staging\.env)' \ "$ROOT/Sources" "$ROOT/engine" "$ROOT/scripts" "$ROOT/themes"; then - printf 'Production-only marker found in Community source.\n' >&2 + printf 'Production-only marker found in open-source project.\n' >&2 + exit 1 +fi + +if /usr/bin/grep -R -i -n \ + --exclude='*.png' --exclude='*.avif' --exclude='*.icns' \ + 'comm''unity' \ + "$ROOT/AGENTS.md" "$ROOT/CHANGELOG.md" "$ROOT/CONTRIBUTING.md" \ + "$ROOT/NOTICE.md" "$ROOT/README.md" "$ROOT/README.zh-CN.md" \ + "$ROOT/Resources" "$ROOT/SECURITY.md" "$ROOT/Sources" "$ROOT/docs" \ + "$ROOT/scripts" "$ROOT/themes"; then + printf 'Legacy edition branding found in AI ThemeStore.\n' >&2 exit 1 fi "$ROOT/scripts/build-app.sh" -/usr/bin/codesign --verify --deep --strict "$ROOT/dist/AI ThemeStore Community.app" -printf 'AI ThemeStore Community tests passed.\n' +/usr/bin/codesign --verify --deep --strict "$ROOT/dist/AI ThemeStore.app" +printf 'AI ThemeStore tests passed.\n' diff --git a/themes/cyber-neon/theme.json b/themes/cyber-neon/theme.json index b7787d8..65a013c 100644 --- a/themes/cyber-neon/theme.json +++ b/themes/cyber-neon/theme.json @@ -3,9 +3,9 @@ "id": "cyber-neon", "name": "赛博霓虹", "version": "1.0.2", - "author": "AI ThemeStore Community", + "author": "AI ThemeStore", "description": "午夜蓝、电子青与克制紫光构成的沉浸式工作台。", - "brandSubtitle": "COMMUNITY NIGHT LAB", + "brandSubtitle": "ORIGINAL NIGHT LAB", "tagline": "进入专注、清晰、安静的深夜工作流。", "projectPrefix": "载入项目 · ", "projectLabel": "⌁ 选择霓虹节点", diff --git a/themes/minimal-glass/theme.json b/themes/minimal-glass/theme.json index 3737287..5b3fd60 100644 --- a/themes/minimal-glass/theme.json +++ b/themes/minimal-glass/theme.json @@ -3,9 +3,9 @@ "id": "minimal-glass", "name": "极简玻璃", "version": "1.0.2", - "author": "AI ThemeStore Community", + "author": "AI ThemeStore", "description": "象牙白、薄雾青与低干扰玻璃建筑组成的安静主题。", - "brandSubtitle": "COMMUNITY QUIET SERIES", + "brandSubtitle": "ORIGINAL QUIET SERIES", "tagline": "留出空间,让重要的事情自然浮现。", "projectPrefix": "打开 · ", "projectLabel": "▱ 选择纯净画布", diff --git a/themes/pink-future-city/theme.json b/themes/pink-future-city/theme.json index 4b44f8b..1f10cf0 100644 --- a/themes/pink-future-city/theme.json +++ b/themes/pink-future-city/theme.json @@ -3,9 +3,9 @@ "id": "pink-future-city", "name": "粉色未来城市", "version": "1.0.2", - "author": "AI ThemeStore Community", + "author": "AI ThemeStore", "description": "柔和玫瑰晨光、未来城市与轻盈玻璃面板。", - "brandSubtitle": "COMMUNITY ORIGINAL", + "brandSubtitle": "ORIGINAL THEME SERIES", "tagline": "在柔和晨光里开始新的创造。", "projectPrefix": "进入项目 · ", "projectLabel": "♡ 选择未来街区",