diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index b0f0e1c..d850164 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -34,7 +34,7 @@ { "name": "use-family", "description": "The whole *-use family in one install: every *-use plugin below as a dependency, a routing skill that tells the agent which one to use and how they combine, and a session-start check for missing CLIs, and CLIs kept at their plugin's version.", - "version": "0.9.0", + "version": "0.9.1", "category": "productivity", "source": "./plugins/use-family", "homepage": "https://github.com/leeguooooo/plugins/tree/main/plugins/use-family" diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 36785a2..222c7ba 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -11,6 +11,7 @@ jobs: steps: - uses: actions/checkout@v4 - run: sh tests/install-use-family.test.sh + - run: sh tests/doctor.test.sh - run: sh tests/readme-codex-list.test.sh - name: install-use-family.ps1 parses shell: pwsh diff --git a/install-use-family.sh b/install-use-family.sh index 840446c..3ebd5fc 100644 --- a/install-use-family.sh +++ b/install-use-family.sh @@ -23,7 +23,9 @@ CLIS="chrome-use cookie-use mail-use discord-use bitwarden-use chatgpt-use memor repo_of() { # repo_of : the GitHub repo a use lives in case "$1" in ocs) echo open-cross-session ;; *) echo "$1" ;; esac } -[ "$(uname -s)" = Darwin ] && CLIS="$CLIS wechat-use message-use paste-use" +[ "$(uname -s)" = Darwin ] && CLIS="$CLIS message-use paste-use" +# wechat-use's macOS installer stops with "Apple Silicon only" on Intel, so don't suggest it there. +[ "$(uname -s)-$(uname -m)" = Darwin-arm64 ] && CLIS="$CLIS wechat-use" fetch() { # fetch if [ -d "$2/.git" ]; then @@ -68,6 +70,12 @@ if [ -n "$missing" ]; then case "$name" in # image-use has no install.sh: the CLI is the single file at the root of the checkout above. image-use) echo " sudo install \"$BASE/image-use/image-use\" /usr/local/bin/image-use" ;; + # No prebuilt binary for Intel Macs; the installer only says to build from source. + discord-use) if [ "$(uname -s)-$(uname -m)" = Darwin-x86_64 ]; then + echo " cargo install --git https://github.com/leeguooooo/discord-use --root ~/.local # Intel Mac: builds from source, needs Rust (rustup.rs)" + else + echo " curl -fsSL https://raw.githubusercontent.com/leeguooooo/discord-use/main/install.sh | sh" + fi ;; *) echo " curl -fsSL https://raw.githubusercontent.com/leeguooooo/$(repo_of "$name")/main/install.sh | sh" ;; esac done diff --git a/plugins/use-family/.claude-plugin/plugin.json b/plugins/use-family/.claude-plugin/plugin.json index dfdcd53..9272fc7 100644 --- a/plugins/use-family/.claude-plugin/plugin.json +++ b/plugins/use-family/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "use-family", - "version": "0.9.0", + "version": "0.9.1", "description": "The whole *-use family in one install: browser, email, texts (iMessage/SMS), chat, phone, identity, passwords, sessions, notes, clipboard history, promo and explainer videos, and the other agents on your machines. Adds a routing skill that tells the agent which use to reach for and how they combine, plus a session-start check for missing CLIs and one that upgrades a CLI older than its plugin.", "author": { "name": "leeguooooo" diff --git a/plugins/use-family/scripts/doctor.sh b/plugins/use-family/scripts/doctor.sh index c670814..bd41ecb 100755 --- a/plugins/use-family/scripts/doctor.sh +++ b/plugins/use-family/scripts/doctor.sh @@ -6,9 +6,12 @@ PATH="$PATH:$HOME/.local/bin:/opt/homebrew/bin:/usr/local/bin" # iphone-use runs as a daemon and profile-use ships its script inside the skill, # so neither has a CLI on PATH to look for. -names="chrome-use cookie-use mail-use discord-use bitwarden-use chatgpt-use memory-use ocs" -case "$(uname -s)" in MINGW*|MSYS*|CYGWIN*) ;; *) names="$names motion-use" ;; esac # motion-use: macOS and Linux only -[ "$(uname -s)" = Darwin ] && names="$names wechat-use message-use paste-use" +os=$(uname -s); arch=$(uname -m) +names="chrome-use cookie-use mail-use discord-use bitwarden-use chatgpt-use memory-use ocs image-use" +case "$os" in MINGW*|MSYS*|CYGWIN*) ;; *) names="$names motion-use" ;; esac # motion-use: macOS and Linux only +[ "$os" = Darwin ] && names="$names message-use paste-use" +# wechat-use's macOS installer stops with "Apple Silicon only" on Intel, so don't suggest it there. +[ "$os-$arch" = Darwin-arm64 ] && names="$names wechat-use" missing="" for name in $names; do @@ -25,5 +28,11 @@ echo "use-family: these CLIs are not installed:$missing" echo "Install one when a task needs it, after asking the user:" for name in $missing; do repo=$name; [ "$name" = ocs ] && repo=open-cross-session - echo " curl -fsSL https://raw.githubusercontent.com/leeguooooo/$repo/main/install.sh | sh" + case "$name-$os-$arch" in + # image-use has no install.sh: the CLI is the single file at the root of its repo. + image-use-*) echo " git clone -q --depth 1 https://github.com/leeguooooo/image-use ~/.agents/use-family/image-use && ln -sf ~/.agents/use-family/image-use/image-use ~/.local/bin/image-use" ;; + # No prebuilt binary for Intel Macs; the installer only says to build from source. + discord-use-Darwin-x86_64) echo " cargo install --git https://github.com/leeguooooo/discord-use --root ~/.local # Intel Mac: builds from source, needs Rust (rustup.rs)" ;; + *) echo " curl -fsSL https://raw.githubusercontent.com/leeguooooo/$repo/main/install.sh | sh" ;; + esac done diff --git a/tests/doctor.test.sh b/tests/doctor.test.sh new file mode 100644 index 0000000..766862e --- /dev/null +++ b/tests/doctor.test.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# Runs use-family's doctor.sh with no *-use CLI installed, as an Intel and an Apple Silicon Mac +# (fake uname), and checks which CLIs it names and with what install hint. +# sh tests/doctor.test.sh +set -eu +ROOT=$(cd "$(dirname "$0")/.." && pwd) +TMP=$(mktemp -d); trap 'rm -rf "$TMP"' EXIT +mkdir -p "$TMP/bin" "$TMP/home" +cat > "$TMP/bin/uname" <<'UNAME' +#!/bin/sh +case "$1" in -m) echo "$FAKE_ARCH" ;; *) echo Darwin ;; esac +UNAME +chmod +x "$TMP/bin/uname" +# Only the shell itself: no *-use CLI and no system tool that doctor.sh might find. +ln -s "$(command -v sh)" "$TMP/bin/sh" + +run() { # run : doctor.sh's stdout on a Mac with that arch + FAKE_ARCH=$1 HOME="$TMP/home" PATH="$TMP/bin" sh "$ROOT/plugins/use-family/scripts/doctor.sh" +} +fail() { echo "FAIL: $1"; echo "$out"; exit 1; } + +out=$(run x86_64) +echo "$out" | grep -q 'not installed:.* wechat-use' && fail "Intel: suggests wechat-use, whose installer is Apple Silicon only" +echo "$out" | grep -qF 'cargo install --git https://github.com/leeguooooo/discord-use' || fail "Intel: no build-from-source hint for discord-use" +echo "$out" | grep -q 'discord-use/main/install.sh' && fail "Intel: points at discord-use's install.sh, which has no Intel binary" +echo "$out" | grep -q 'not installed:.* image-use' || fail "image-use not checked" +echo "$out" | grep -q 'image-use/main/install.sh' && fail "points at an install.sh image-use does not have" +echo "$out" | grep -qF 'ln -sf ~/.agents/use-family/image-use/image-use ~/.local/bin/image-use' || fail "no single-file install hint for image-use" + +out=$(run arm64) +echo "$out" | grep -q 'not installed:.* wechat-use' || fail "Apple Silicon: wechat-use not checked" +echo "$out" | grep -qF 'leeguooooo/discord-use/main/install.sh | sh' || fail "Apple Silicon: lost discord-use's install.sh hint" + +echo "ok doctor.sh" diff --git a/tests/install-use-family.test.sh b/tests/install-use-family.test.sh index 703f013..aae6586 100644 --- a/tests/install-use-family.test.sh +++ b/tests/install-use-family.test.sh @@ -18,7 +18,13 @@ case "$*" in esac GIT chmod +x "$TMP/bin/git" -for tool in sh mkdir ln readlink uname touch chmod rm cat dirname basename; do +# Fake uname: a Mac whose arch is $FAKE_ARCH (arm64 unless a check sets it). +cat > "$TMP/bin/uname" <<'UNAME' +#!/bin/sh +case "$1" in -m) echo "${FAKE_ARCH:-arm64}" ;; *) echo Darwin ;; esac +UNAME +chmod +x "$TMP/bin/uname" +for tool in sh mkdir ln readlink touch chmod rm cat dirname basename; do ln -s "$(command -v "$tool")" "$TMP/bin/$tool" done @@ -34,6 +40,13 @@ echo "$out" | grep -qF "sudo install \"$TMP/home/.agents/use-family/image-use/im echo "$out" | grep -q 'leeguooooo/image-use/main/install.sh' && fail "points at an install.sh image-use does not have" echo "$out" | grep -qF 'leeguooooo/mail-use/main/install.sh | sh' || fail "generic install.sh hint lost" +echo "$out" | grep -q '^CLIs not installed yet:.* wechat-use' || fail "Apple Silicon: wechat-use missing from the not-installed list" +echo "$out" | grep -qF 'leeguooooo/discord-use/main/install.sh | sh' || fail "Apple Silicon: lost discord-use's install.sh hint" + +out=$(FAKE_ARCH=x86_64 run) +echo "$out" | grep -q '^CLIs not installed yet:.* wechat-use' && fail "Intel: suggests wechat-use, whose installer is Apple Silicon only" +echo "$out" | grep -qF 'cargo install --git https://github.com/leeguooooo/discord-use' || fail "Intel: no build-from-source hint for discord-use" + printf '#!/bin/sh\n' > "$TMP/bin/image-use"; chmod +x "$TMP/bin/image-use" out=$(run) echo "$out" | grep -q 'image-use/image-use\|not installed yet:.* image-use' && fail "image-use reported although it is on PATH"