set up.sh

This commit is contained in:
Jun-te Kim 2026-05-05 17:22:20 +00:00
parent 769689a093
commit af8ea95a5b

View file

@ -1,6 +1,6 @@
#!/usr/bin/env bash
#
# Install Domna's curated skill set into the current repo.
# Install Domna's curated skill set globally (~/.claude).
#
# Run from the root of the target repo:
# curl -fsSL https://raw.githubusercontent.com/Hestia-Homes/agentic-toolkit/main/setup.sh | bash
@ -8,78 +8,93 @@
# bash /path/to/agentic-toolkit/setup.sh
#
# What this does:
# 1. Drops the pinned skills-lock.json from agentic-toolkit into the target repo.
# 2. Runs `skills experimental_install` to restore the exact pinned versions
# of Matt Pocock's skills + Domna's own skills (Hestia-Homes/agentic-toolkit).
# 1. Copies the pinned skills-lock.json from agentic-toolkit to ~/.claude.
# 2. Parses it and runs `skills add --global` per source so all skills land
# in ~/.claude/skills (user-level, available in every repo).
#
# To upgrade skills across all Domna repos:
# - In agentic-toolkit, re-install the skills you want, then commit the
# resulting skills-lock.json (this script reads from that file).
# - Devs re-run setup.sh in their target repos.
# Note: `skills experimental_install` would be the natural fit but it only
# restores at project scope — confirmed empirically that running it against
# a global lock prints "No project skills found" and exits 0, installing
# nothing. So we drive `skills add --global` from the lock instead.
#
# Logs verbose output to $HOME/.claude/agentic-toolkit-setup.log so failures
# under postCreateCommand or `| bash` are inspectable after the fact.
#
set -euo pipefail
# --- logging -------------------------------------------------------------------
CLAUDE_DIR="${CLAUDE_CONFIG_DIR:-$HOME/.claude}"
mkdir -p "$CLAUDE_DIR"
LOG_FILE="$CLAUDE_DIR/agentic-toolkit-setup.log"
# Tee everything (stdout + stderr) to the log so silent failures aren't silent.
exec > >(tee -a "$LOG_FILE") 2>&1
echo "=== agentic-toolkit setup.sh @ $(date -u +%FT%TZ) ==="
# Trap so a failure under set -e prints the failing line into the log.
trap 'rc=$?; echo "ERROR: setup.sh exited $rc at line $LINENO" >&2; exit $rc' ERR
# --- config --------------------------------------------------------------------
LOCK_URL="https://raw.githubusercontent.com/Hestia-Homes/agentic-toolkit/main/skills-lock.json"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" 2>/dev/null && pwd || true)"
LOCAL_LOCK="${SCRIPT_DIR:+$SCRIPT_DIR/skills-lock.json}"
AGENT_TARGET="claude-code"
DEST_LOCK="$CLAUDE_DIR/skills-lock.json"
# --- guards --------------------------------------------------------------------
if ! command -v npx >/dev/null 2>&1; then
echo "error: npx is required (install Node.js >= 20)." >&2
exit 1
fi
if [[ ! -d .git ]]; then
echo "error: run this script from the root of a git repository." >&2
if ! command -v node >/dev/null 2>&1; then
echo "error: node is required to parse skills-lock.json." >&2
exit 1
fi
# --- stage skills-lock.json ----------------------------------------------------
LOCK_FILE="$(mktemp -t skills-lock.XXXXXX.json)"
trap 'rm -f "$LOCK_FILE"' EXIT
# --- stage skills-lock.json into ~/.claude ------------------------------------
if [[ -n "$LOCAL_LOCK" && -f "$LOCAL_LOCK" ]]; then
echo "==> Using local skills-lock.json from $LOCAL_LOCK"
cp "$LOCAL_LOCK" "$LOCK_FILE"
echo "==> Copying local skills-lock.json -> $DEST_LOCK"
cp "$LOCAL_LOCK" "$DEST_LOCK"
else
echo "==> Fetching skills-lock.json from $LOCK_URL"
echo "==> Fetching skills-lock.json -> $DEST_LOCK"
if command -v curl >/dev/null 2>&1; then
curl -fsSL "$LOCK_URL" -o "$LOCK_FILE"
curl -fsSL "$LOCK_URL" -o "$DEST_LOCK"
elif command -v wget >/dev/null 2>&1; then
wget -qO "$LOCK_FILE" "$LOCK_URL"
wget -qO "$DEST_LOCK" "$LOCK_URL"
else
echo "error: need curl or wget to fetch skills-lock.json." >&2
exit 1
fi
fi
AGENT_TARGET="claude-code"
# --- parse lock: write "source<TAB>skill1,skill2,..." to a tempfile -----------
GROUPS_FILE="$(mktemp -t skills-groups.XXXXXX)"
trap 'rm -f "$GROUPS_FILE"' EXIT
# --- install (globally, grouped by source) -------------------------------------
# `skills experimental_install` only restores at project scope. Domna installs
# globally (~/.claude), so we parse the lock and call `skills add` per source
# with the explicit skill list from the lock file.
echo "==> Installing skills globally (~/.claude) from skills-lock.json"
# Group skills by source -> "source<TAB>skill1,skill2,..."
GROUPS="$(node -e '
const lock = JSON.parse(require("fs").readFileSync(process.argv[1], "utf8"));
node --input-type=module -e "
import fs from 'node:fs';
const lock = JSON.parse(fs.readFileSync(process.argv[1], 'utf8'));
const bySource = new Map();
for (const [name, entry] of Object.entries(lock.skills || {})) {
if (!entry.source) continue;
if (!entry || !entry.source) continue;
if (!bySource.has(entry.source)) bySource.set(entry.source, []);
bySource.get(entry.source).push(name);
}
for (const [src, names] of bySource) {
process.stdout.write(src + "\t" + names.join(",") + "\n");
}
' "$LOCK_FILE")"
const out = [...bySource.entries()]
.map(([src, names]) => src + '\t' + names.join(','))
.join('\n');
fs.writeFileSync(process.argv[2], out + (out ? '\n' : ''));
" "$DEST_LOCK" "$GROUPS_FILE"
if [[ -z "$GROUPS" ]]; then
echo "error: no skills found in lock file." >&2
if [[ ! -s "$GROUPS_FILE" ]]; then
echo "error: no skills found in $DEST_LOCK." >&2
exit 1
fi
echo "==> Skill groups parsed from lock:"
cat "$GROUPS_FILE"
# --- install (globally, grouped by source) -------------------------------------
echo "==> Installing skills globally (~/.claude)"
while IFS=$'\t' read -r SOURCE SKILLS; do
[[ -z "$SOURCE" ]] && continue
echo "==> $SOURCE :: $SKILLS"
@ -89,14 +104,12 @@ while IFS=$'\t' read -r SOURCE SKILLS; do
--copy \
--global \
--yes
done <<< "$GROUPS"
done < "$GROUPS_FILE"
# --- post-install reminder -----------------------------------------------------
echo "==> Done. Log: $LOG_FILE"
cat <<'EOF'
==> Done. Next steps:
1. Run /setup-matt-pocock-skills (one-time per repo) to record the issue
tracker, triage labels, and domain-doc layout.
Next step:
Run /setup-matt-pocock-skills once per repo to record the issue tracker,
triage labels, and domain-doc layout.
EOF