diff --git a/README.md b/README.md index f13c24c..f6e8875 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ stplr info nivora/codex | Приложение | Версия | Архитектуры | Установка | |:--|:--:|:--:|:--| | [Chatbox](https://chatboxai.app/ru) | `1.20.3` | `amd64`, `arm64` | `stplr install nivora/chatbox` | -| [Claude](https://code.claude.com/docs/en/desktop-quickstart) | `1.24012.0` | `amd64`, `arm64` | `stplr install nivora/claude-desktop` | +| [Claude](docs/packages/claude.md) | `1.24012.0` | `amd64`, `arm64` | `stplr install nivora/claude` | | [ClaudeAlt](docs/packages/claude-alt.md) | `1.24012.0` | `amd64`, `arm64` | `stplr install nivora/claude-alt` | | [Codex](docs/packages/codex.md) | `26.721.31836` | `amd64` | `stplr install nivora/codex` | | [GitHub Desktop](docs/packages/github-desktop.md) | `3.6.3` | `amd64`, `arm64` | `stplr install nivora/github-desktop` | diff --git a/claude-alt/Staplerfile b/claude-alt/Staplerfile index bdd74ba..5043be1 100644 --- a/claude-alt/Staplerfile +++ b/claude-alt/Staplerfile @@ -39,15 +39,15 @@ build_deps_altlinux=('binutils' 'python3') sources=( "https://downloads.claude.ai/claude-desktop/apt/stable/pool/main/c/claude-desktop/claude-desktop_${version}_amd64.deb?~archive=false&~name=claude-desktop.deb" "local:///claude-alt" - "https://raw.githubusercontent.com/Cheviiot/Nivora/main/claude-desktop/claude-alt.png?~archive=false&~name=claude-alt.png" - "https://raw.githubusercontent.com/Cheviiot/Nivora/main/claude-desktop/claude-alt-tray-turquoise.png?~archive=false&~name=claude-alt-tray.png" + "https://raw.githubusercontent.com/Cheviiot/Nivora/main/claude/claude-alt.png?~archive=false&~name=claude-alt.png" + "https://raw.githubusercontent.com/Cheviiot/Nivora/main/claude/claude-alt-tray-turquoise.png?~archive=false&~name=claude-alt-tray.png" "local:///patch-asar.py" ) sources_arm64=( "https://downloads.claude.ai/claude-desktop/apt/stable/pool/main/c/claude-desktop/claude-desktop_${version}_arm64.deb?~archive=false&~name=claude-desktop.deb" "local:///claude-alt" - "https://raw.githubusercontent.com/Cheviiot/Nivora/main/claude-desktop/claude-alt.png?~archive=false&~name=claude-alt.png" - "https://raw.githubusercontent.com/Cheviiot/Nivora/main/claude-desktop/claude-alt-tray-turquoise.png?~archive=false&~name=claude-alt-tray.png" + "https://raw.githubusercontent.com/Cheviiot/Nivora/main/claude/claude-alt.png?~archive=false&~name=claude-alt.png" + "https://raw.githubusercontent.com/Cheviiot/Nivora/main/claude/claude-alt-tray-turquoise.png?~archive=false&~name=claude-alt-tray.png" "local:///patch-asar.py" ) checksums=( diff --git a/claude-desktop/.stapler/update-check b/claude/.stapler/update-check similarity index 100% rename from claude-desktop/.stapler/update-check rename to claude/.stapler/update-check diff --git a/claude-desktop/LICENSE b/claude/LICENSE similarity index 100% rename from claude-desktop/LICENSE rename to claude/LICENSE diff --git a/claude-desktop/Staplerfile b/claude/Staplerfile similarity index 99% rename from claude-desktop/Staplerfile rename to claude/Staplerfile index 00af455..7690a70 100644 --- a/claude-desktop/Staplerfile +++ b/claude/Staplerfile @@ -1,6 +1,6 @@ -name='claude-desktop' +name='claude' version=1.24012.0 -release=5 +release=1 summary='Claude desktop application' summary_ru='Десктопное приложение Claude' group='Development/Tools' @@ -17,7 +17,7 @@ nonfree_msg='Claude Desktop является проприетарным прил nonfree_url='https://www.anthropic.com/legal/consumer-terms' provides=() -replaces=('claude-desktop') +replaces=('claude' 'claude-desktop') conflicts=() auto_reqprov_method="dirty" diff --git a/claude-desktop/claude-alt b/claude/claude-alt similarity index 100% rename from claude-desktop/claude-alt rename to claude/claude-alt diff --git a/claude-desktop/claude-alt-tray-turquoise.png b/claude/claude-alt-tray-turquoise.png similarity index 100% rename from claude-desktop/claude-alt-tray-turquoise.png rename to claude/claude-alt-tray-turquoise.png diff --git a/claude-desktop/claude-alt.png b/claude/claude-alt.png similarity index 100% rename from claude-desktop/claude-alt.png rename to claude/claude-alt.png diff --git a/claude-desktop/claude-tray-orange.png b/claude/claude-tray-orange.png similarity index 100% rename from claude-desktop/claude-tray-orange.png rename to claude/claude-tray-orange.png diff --git a/claude-desktop/postinstall.sh b/claude/postinstall.sh similarity index 100% rename from claude-desktop/postinstall.sh rename to claude/postinstall.sh diff --git a/claude-desktop/postremove.sh b/claude/postremove.sh similarity index 100% rename from claude-desktop/postremove.sh rename to claude/postremove.sh diff --git a/claude-desktop/stapler-repo.toml b/claude/stapler-repo.toml similarity index 100% rename from claude-desktop/stapler-repo.toml rename to claude/stapler-repo.toml diff --git a/docs/maintenance.md b/docs/maintenance.md index f169924..fd064ec 100644 --- a/docs/maintenance.md +++ b/docs/maintenance.md @@ -17,7 +17,7 @@ Stapler сам добавляет текущее `name` в generated `Provides` | Package ID | Основание | |:--|:--| | `clash-verge-rev` | Upstream-репозиторий и release title: Clash Verge Rev | -| `claude-desktop` | Upstream DEB: `Package: claude-desktop`; desktop-id `com.anthropic.Claude` сохранён | +| `claude` | Upstream DEB: `Package: claude-desktop`; desktop-id `com.anthropic.Claude` сохранён; старое имя пакета `claude-desktop` заменяется | | `codex` | Отображаемое имя `Codex`; команда и desktop-id `codex-app` сохранены | | `github-desktop` | Официальный upstream `desktop/desktop`; Linux-сборка без стороннего форка | | `nivora-stplr` | Собственный helper Nivora | diff --git a/docs/packages/claude-alt.md b/docs/packages/claude-alt.md index 5e88557..1f9f287 100644 --- a/docs/packages/claude-alt.md +++ b/docs/packages/claude-alt.md @@ -1,12 +1,12 @@ # ClaudeAlt Самостоятельная вторая установка Claude, не входящая в пакет -`claude-desktop`: +`claude`: ```bash sudo stplr install nivora/claude-alt ``` Использует собственные runtime, профиль и desktop-идентичность. Иконки Nivora -переносятся без изменений. `claude-desktop` и `claude-alt` можно устанавливать, +переносятся без изменений. `claude` и `claude-alt` можно устанавливать, обновлять и удалять независимо друг от друга. diff --git a/docs/packages/claude-desktop.md b/docs/packages/claude.md similarity index 78% rename from docs/packages/claude-desktop.md rename to docs/packages/claude.md index d034845..a8736f0 100644 --- a/docs/packages/claude-desktop.md +++ b/docs/packages/claude.md @@ -1,20 +1,20 @@ -# Claude Desktop +# Claude -Пакет `claude-desktop` переупаковывает DEB из APT-источника Anthropic и сохраняет upstream +Пакет `claude` переупаковывает DEB из APT-источника Anthropic и сохраняет upstream desktop-id `com.anthropic.Claude`. ```bash -sudo stplr install nivora/claude-desktop +sudo stplr install nivora/claude ``` -## Два независимых приложения +При установке новый пакет заменяет прежнее имя `nivora/claude-desktop`. +Исполняемая команда `/usr/bin/claude-desktop` сохраняется, чтобы не +конфликтовать с Claude Code CLI, использующим команду `claude`. -- `claude-desktop` запускает основное приложение Claude. -- `claude-alt` и `claude-code-alt` запускают отдельное приложение ClaudeAlt. -- `claude-desktop-account2` — дополнительное имя запуска ClaudeAlt. -- Команда `claude` не создаётся, чтобы не конфликтовать с Claude Code CLI. +## Два независимых пакета -ClaudeAlt имеет отдельные executable/resources tree, Electron `productName`, Wayland `app_id`, +`claude-alt` устанавливается отдельной командой и имеет собственные +executable/resources tree, Electron `productName`, Wayland `app_id`, X11 `WM_CLASS`, desktop-файл, Chromium-профиль, Cowork VM socket, оконную и tray-иконки. В системном лотке используется штатный глиф Claude: оранжевый у основного приложения и бирюзовый у ClaudeAlt. Большие app-иконки окон при этом diff --git a/tests/test_claude_alt.sh b/tests/test_claude_alt.sh index 63d9f55..560959c 100755 --- a/tests/test_claude_alt.sh +++ b/tests/test_claude_alt.sh @@ -3,10 +3,10 @@ set -euo pipefail repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" launcher="${repo_root}/claude-alt/claude-alt" -icon="${repo_root}/claude-desktop/claude-alt.png" -primary_tray_icon="${repo_root}/claude-desktop/claude-tray-orange.png" -alternate_tray_icon="${repo_root}/claude-desktop/claude-alt-tray-turquoise.png" -primary_recipe="${repo_root}/claude-desktop/Staplerfile" +icon="${repo_root}/claude/claude-alt.png" +primary_tray_icon="${repo_root}/claude/claude-tray-orange.png" +alternate_tray_icon="${repo_root}/claude/claude-alt-tray-turquoise.png" +primary_recipe="${repo_root}/claude/Staplerfile" alternate_recipe="${repo_root}/claude-alt/Staplerfile" temp_dir="$(mktemp -d)" diff --git a/tools/package_updates.sh b/tools/package_updates.sh index 0b74f8b..2f37212 100755 --- a/tools/package_updates.sh +++ b/tools/package_updates.sh @@ -8,7 +8,7 @@ readonly -a PACKAGES=( chatbox clash-verge-rev claude-alt - claude-desktop + claude codex fisher github-desktop @@ -219,7 +219,7 @@ latest_version() { balena-etcher) github_latest_release balena-io/etcher ;; chatbox) latest_chatbox ;; clash-verge-rev) github_latest_release clash-verge-rev/clash-verge-rev ;; - claude-alt | claude-desktop) latest_claude_desktop ;; + claude | claude-alt) latest_claude_desktop ;; codex) github_latest_release Boria138/codex-app-linux ;; fisher) github_latest_release jorgebucaran/fisher ;; github-desktop) diff --git a/tools/test_package_lifecycle.sh b/tools/test_package_lifecycle.sh index 1a36453..db5d1dc 100755 --- a/tools/test_package_lifecycle.sh +++ b/tools/test_package_lifecycle.sh @@ -26,7 +26,7 @@ esac # package | command | persistent state marker | desktop/unit | icon readonly -a lifecycle_packages=( 'clash-verge-rev|/usr/bin/clash-verge|/home/nivora-test/.local/share/io.github.clash-verge-rev.clash-verge-rev/nivora-lifecycle-state|/usr/share/applications/Clash Verge.desktop|/usr/share/icons/hicolor/128x128/apps/clash-verge.png' - 'claude-desktop|/usr/bin/claude-desktop|/home/nivora-test/.config/Claude/nivora-lifecycle-state|/usr/share/applications/com.anthropic.Claude.desktop|/usr/share/icons/hicolor/128x128/apps/claude-desktop.png' + 'claude|/usr/bin/claude-desktop|/home/nivora-test/.config/Claude/nivora-lifecycle-state|/usr/share/applications/com.anthropic.Claude.desktop|/usr/share/icons/hicolor/128x128/apps/claude-desktop.png' 'codex|/usr/bin/codex-app|/home/nivora-test/.codex/nivora-lifecycle-state|/usr/share/applications/codex-app.desktop|/usr/share/icons/hicolor/512x512/apps/codex-app.png' 'nivora-stplr|/usr/bin/sl|/home/nivora-test/.config/nivora-stplr/nivora-lifecycle-state|-|-' 'opencode|/usr/bin/opencode-desktop|/home/nivora-test/.config/opencode/nivora-lifecycle-state|/usr/share/applications/opencode-desktop.desktop|/usr/share/icons/hicolor/128x128/apps/ai.opencode.desktop.png' diff --git a/tools/validate_repo.py b/tools/validate_repo.py index 683cafa..e66c280 100755 --- a/tools/validate_repo.py +++ b/tools/validate_repo.py @@ -17,8 +17,8 @@ EXPECTED_PACKAGES = ( "balena-etcher", "chatbox", "clash-verge-rev", + "claude", "claude-alt", - "claude-desktop", "codex", "fisher", "github-desktop", @@ -43,7 +43,7 @@ REQUIRED_ROOT_FILES = { Path("stapler-repo.toml"), Path("docs/maintenance.md"), Path("docs/security-model.md"), - Path("docs/packages/claude-desktop.md"), + Path("docs/packages/claude.md"), Path("docs/packages/claude-alt.md"), Path("docs/packages/codex.md"), Path("docs/packages/github-desktop.md"), @@ -166,8 +166,13 @@ def validate_package(package: str, errors: list[str]) -> dict[str, object]: if provides != [] or conflicts != []: errors.append(f"{package}: provides/conflicts must not contain binary aliases") - if replaces != [package]: - errors.append(f"{package}: replaces must contain only its own base package name") + expected_replaces = [package] + if package == "claude": + expected_replaces.append("claude-desktop") + if replaces != expected_replaces: + errors.append( + f"{package}: replaces must be {expected_replaces}, got {replaces}" + ) if "package()" not in text or "files()" not in text: errors.append(f"{package}: package() or files() is missing") @@ -241,7 +246,7 @@ def validate_readme(metadata: dict[str, dict[str, object]], errors: list[str]) - errors.append("README.md: catalog must contain exactly six categories") for package, values in metadata.items(): - command = f"stplr install nivora/{package}" + command = f"`stplr install nivora/{package}`" catalog_rows = [ line for line in text.splitlines() if line.startswith("|") and command in line ] diff --git a/tools/verify_artifacts.sh b/tools/verify_artifacts.sh index ba73cbe..df1e9ae 100755 --- a/tools/verify_artifacts.sh +++ b/tools/verify_artifacts.sh @@ -93,17 +93,23 @@ for package in "${packages[@]}"; do } fi - if [[ "$package" == 'claude-desktop' ]]; then + if [[ "$package" == 'claude' ]]; then + for forbidden_path in \ + /usr/bin/claude-alt \ + /usr/lib/claude-alt/claude-alt-bin \ + /usr/share/applications/com.anthropic.ClaudeAlt.desktop; do + contains_path "$forbidden_path" && { + echo "${package}: обнаружен компонент отдельного пакета ClaudeAlt: ${forbidden_path}" >&2 + exit 1 + } + done + fi + + if [[ "$package" == 'claude-alt' ]]; then for required_path in \ /usr/bin/claude-alt \ - /usr/bin/claude-desktop-account2 \ - /usr/lib/claude-desktop/resources/TrayIconLinux.png \ - /usr/lib/claude-desktop/resources/TrayIconLinux-Dark.png \ /usr/lib/claude-alt/claude-alt-bin \ /usr/lib/claude-alt/resources/app.asar \ - /usr/lib/claude-alt/resources/icon.png \ - /usr/lib/claude-alt/resources/TrayIconLinux.png \ - /usr/lib/claude-alt/resources/TrayIconLinux-Dark.png \ /usr/share/applications/com.anthropic.ClaudeAlt.desktop \ /usr/share/icons/hicolor/512x512/apps/claude-alt.png; do contains_path "$required_path" || { @@ -111,10 +117,6 @@ for package in "${packages[@]}"; do exit 1 } done - contains_path '/usr/share/applications/claude-desktop-account2.desktop' && { - echo "${package}: обнаружен устаревший desktop-файл второго профиля" >&2 - exit 1 - } fi if [[ "$package" == 'balena-etcher' ]]; then