feat(install): Higgsfield step 8.6; login offers test stdin alone
This commit is contained in:
+76
-3
@@ -582,6 +582,8 @@ else
|
||||
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 @@ if command -v ctx7 &>/dev/null; then
|
||||
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=""
|
||||
@@ -990,6 +992,76 @@ for _stray in "$REPO/.agents/skills" "$REPO/.claude/skills"; do
|
||||
done
|
||||
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
|
||||
# ============================================================
|
||||
@@ -1065,13 +1137,13 @@ apply_effort_pins "$REPO" || warn "effort pins: map lines rejected — fix lib/e
|
||||
# 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 <user> (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 " 🔄 agent-skills trio — observability-and-instrumentation, deprec
|
||||
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)"
|
||||
|
||||
@@ -312,5 +312,29 @@ expect profiles \
|
||||
expect pins-map "$(count lib/effort-pins.txt higgsfield)" 0
|
||||
verdict OFF_BY_DEFAULT_WIRING
|
||||
|
||||
# ln_first / ln_last <file> <fixed string> — line number of a match.
|
||||
ln_first() { grep -nF -- "$2" "$ROOT/$1" | head -1 | cut -d: -f1; }
|
||||
ln_last() { grep -nF -- "$2" "$ROOT/$1" | tail -1 | cut -d: -f1; }
|
||||
# shellcheck disable=SC2016 # a literal to grep for, not an expansion
|
||||
PINS='apply_effort_pins "$REPO"'
|
||||
|
||||
# install-plugins.sh: the sync sits in Step 8.6, before the effort pins
|
||||
# (BDR-108); the CLI is proven by a probe, not by its shim; every login
|
||||
# offer tests stdin alone (stdout is the tee pipe).
|
||||
sync_ln="$(ln_last install-plugins.sh 'higgsfield_sync_skills')"
|
||||
expect after-8.5 "$(yn test "$sync_ln" -gt \
|
||||
"$(ln_first install-plugins.sh 'Step 8.5: External skills')")" yes
|
||||
expect before-8.7 "$(yn test "$sync_ln" -lt \
|
||||
"$(ln_first install-plugins.sh 'Step 8.7: 21st.dev')")" yes
|
||||
expect before-pins "$(yn test "$sync_ln" -lt \
|
||||
"$(ln_last install-plugins.sh "$PINS")")" yes
|
||||
expect probe-gates \
|
||||
"$(yn test "$(count install-plugins.sh 'if higgsfield_cli_ok')" -ge 3)" yes
|
||||
expect control "$(echo 'if [ -t 0 ] && [ -t 1 ]; then' | grep -cF -- '-t 1')" 1
|
||||
expect no-stdout-test "$(count install-plugins.sh '-t 1')" 0
|
||||
expect stdin-tests \
|
||||
"$(yn test "$(count install-plugins.sh '[ -t 0 ]')" -ge 3)" yes
|
||||
verdict INSTALL_WIRING
|
||||
|
||||
# ── tally ───────────────────────────────────────────────────
|
||||
printf 'PASS=%s FAIL=%s\n' "$pass" "$fail"; [ "$fail" -eq 0 ]
|
||||
|
||||
Reference in New Issue
Block a user