--- a/install-plugins.sh +++ b/install-plugins.sh @@ -582,6 +582,8 @@ fi # ctx7 auth — detect, then offer login ONLY in an interactive TTY. A non-interactive # run (CI / headless / re-run) must never open a browser or block on OAuth. +# The test reads stdin alone: stdout is the tee pipe set up at the top of +# this script, never a terminal. if command -v ctx7 &>/dev/null; then # Deterministic offline oracle: ctx7's OAuth token lives here (XDG-aware). # Present => authenticated; absent => anonymous. No subprocess, no network, no browser. @@ -590,7 +592,7 @@ ok "ctx7 authenticated (full rate limits)" else info "ctx7 works anonymously — docs + library already usable, no auth required." - if [ -t 0 ] && [ -t 1 ]; then + if [ -t 0 ]; then # Interactive terminal: offer to log in now (opens a browser). printf '%b' "${BLUE}→${NC} Authenticate ctx7 now for higher rate limits? [y/N] " read -r ctx7_ans || ctx7_ans="" @@ -991,6 +993,76 @@ echo "" # ============================================================ +# STEP 8.6 — HIGGSFIELD CLI + SKILL PACK +# ============================================================ +# `@higgsfield/cli` (bins `higgsfield`, `higgs`): image, video, audio and +# brand media generation from the terminal, one browser login, metered +# credits. Its skills come from github.com/higgsfield-ai/skills, cloned by +# lib/higgsfield-skills.sh into skills-external/higgsfield-* (gitignored). +# +# Nothing is linked here. The pack is OFF by default and belongs to no +# profile: `lib/toggle-external.sh enable higgsfield` turns the media skills +# on, `enable higgsfield-websites` the landing-page aid. Keeping it out of +# link.sh and of every profile is what stops a re-run from re-enabling it +# (BDR-093). This step runs before Step 8.7 so the effort pins are still +# re-applied after the last vendoring step (BDR-108). +echo "── Step 8.6: Higgsfield CLI + skill pack ───────────────────" +echo "" +# shellcheck source=lib/higgsfield-skills.sh disable=SC1091 +source "$REPO/lib/higgsfield-skills.sh" +HF_PKG="@higgsfield/cli" +# The package vendors its binary in a postinstall script that npm may hold +# back; this form lets that one script run. +HF_REMEDY="npm install -g --allow-scripts=${HF_PKG} ${HF_PKG}" + +# higgsfield_cli_ok, not `command -v`: the npm shim can sit on PATH with no +# binary behind it, and only a probe tells the two apart. +if higgsfield_cli_ok; then + ok "Higgsfield CLI already installed" +else + HF_VER=$(pinned_version "higgsfield") + [ "$HF_VER" = "latest" ] || HF_PKG="${HF_PKG}@${HF_VER}" + info "Installing ${HF_PKG} (version from plugins.lock.json: ${HF_VER})..." + npm install -g "$HF_PKG" || true + if higgsfield_cli_ok; then + ok "Higgsfield CLI installed" + else + err "Higgsfield CLI install failed — run manually: $HF_REMEDY" + fi +fi + +if higgsfield_cli_ok; then + # Skill pack — cloned to a stage, then moved under skills-external/. + if HF_N=$(higgsfield_sync_skills "$REPO"); then + ok "Higgsfield skill pack synced to skills-external/ ($HF_N skills)" + else + warn "Higgsfield skill pack sync failed — existing copies kept (check: git clone $HIGGSFIELD_SKILLS_URL)" + fi + + # Auth — offer the login only when stdin is a terminal: a non-interactive + # run (CI / headless) must never open a browser or block on OAuth. + if higgsfield_signed_in; then + ok "Higgsfield: signed in" + elif [ -t 0 ]; then + printf '%b' "${BLUE}→${NC} Sign in to Higgsfield now? (opens a browser) [y/N] " + read -r hf_ans || hf_ans="" + if [[ "$hf_ans" =~ ^[Yy]([Ee][Ss])?$ ]]; then + if higgsfield auth login; then + ok "Higgsfield authenticated" + else + warn "Higgsfield login did not finish — re-run 'higgsfield auth login' anytime" + fi + else + info "Skipped — sign in later with: higgsfield auth login" + fi + else + info "Not signed in. Generation needs: higgsfield auth login" + fi + info "Pack is off by default — enable: bash lib/toggle-external.sh enable higgsfield" +fi +echo "" + +# ============================================================ # STEP 8.7 — 21ST.DEV CLI + SKILL PACK # ============================================================ # `@21st-dev/cli` (bin `21st`): one browser login (`21st login`, token in @@ -1065,13 +1137,13 @@ # Auth — detect, then offer login ONLY in an interactive TTY. A non-interactive # run (CI / headless / re-run) must never open a browser or block on OAuth. # Search and logo lookup are free; retrieving component code and 21st AI need -# the session. Mirrors the ctx7 auth block (Step 6). +# the session. Mirrors the ctx7 auth block (Step 6), stdin-only test included. if command -v 21st &>/dev/null; then # `whoami` is a local token read (no network): "Logged in as (saved …)." TFD_WHO="$(21st whoami 2>/dev/null | head -1)" if [[ "$TFD_WHO" == "Logged in as "* ]]; then ok "21st: ${TFD_WHO%.}" - elif [ -t 0 ] && [ -t 1 ]; then + elif [ -t 0 ]; then printf '%b' "${BLUE}→${NC} Sign in to 21st now? (opens a browser) [y/N] " read -r tfd_ans || tfd_ans="" if [[ "$tfd_ans" =~ ^[Yy]([Ee][Ss])?$ ]]; then @@ -1236,6 +1308,7 @@ echo " 🔄 mengto scroll skills — scroll-world-storytelling, build-threejs-scroll-worlds, scroll-scrubbed-visual-sequence, scroll-scrubbed-word-reveal, scroll-progress-timeline (curl → symlink, pinned commit)" echo " 🔄 darwin-skill — autonomous skill optimizer (npx skills, ~/.agents/skills/)" echo " 🔄 21st skill pack — 21st.dev CLI skills; design ones follow the profile (full by default), publishing ones on demand (toggle: lib/toggle-external.sh enable 21st)" +echo " 🔄 higgsfield pack — Higgsfield CLI media skills (image, video, audio, brand), OFF by default (toggle: lib/toggle-external.sh enable higgsfield; landing-page aid: enable higgsfield-websites)" echo "" echo " All plugins installed at: user scope (~/.claude/plugins/)" echo " GStack skills symlinked individually into ~/.claude/skills/ (→ submodule)"