From cf1f3dd83c76f644ddec6dcadd2733da2e5a4c2e Mon Sep 17 00:00:00 2001 From: nunziati Date: Wed, 8 Apr 2026 14:05:12 +0000 Subject: [PATCH] Refactor install/update scripts to support agentic-platform agnosticity. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit refactor(lib.sh): generalize install_claude_md → install_dispatcher New signature takes the full destination path instead of just the vault dir, allowing callers to install CLAUDE.md, AGENTS.md, or any dispatcher file to an explicit location. Co-Authored-By: Claude Sonnet 4.6 feat(launchme): support --framework flag, build dist/ before install Add --framework and --target arg parsing. Run build.sh before installing to populate dist//. All install_* calls now read from dist// instead of the raw source dirs. MCP is now handled automatically by the adapter (no interactive prompt). Replaced install_claude_md with install_dispatcher. Co-Authored-By: Claude Sonnet 4.6 feat(updateme): support --framework flag, build dist/ before update Add --framework and --target arg parsing. Run build.sh before installing to populate dist//. All install_* calls now read from dist// instead of raw source dirs. Replaced install_claude_md with install_dispatcher. Also fix set -e compatibility in lib.sh: add || true to all conditional [[ ... ]] && info "..." logging lines so they don't abort the script when VERBOSE_COPY=0. Co-Authored-By: Claude Sonnet 4.6 --- scripts/launchme.sh | 91 ++++++++++++++++++++++++--------------------- scripts/lib.sh | 24 ++++++------ scripts/updateme.sh | 42 +++++++++++++++++---- 3 files changed, 94 insertions(+), 63 deletions(-) diff --git a/scripts/launchme.sh b/scripts/launchme.sh index 7d248d6..4d7573b 100755 --- a/scripts/launchme.sh +++ b/scripts/launchme.sh @@ -9,6 +9,10 @@ # # It copies agents, skills, references, hooks, and settings into the vault's # .claude/ directory. +# +# Options: +# --framework Framework to build for (default: claude-code) +# --target Override the vault destination path # ============================================================================= set -eo pipefail @@ -19,6 +23,18 @@ source "$SCRIPT_DIR/lib.sh" resolve_paths "${BASH_SOURCE[0]}" +# ── Parse args ───────────────────────────────────────────────────────────── +FRAMEWORK="claude-code" +TARGET_OVERRIDE="" +while [[ $# -gt 0 ]]; do + case "$1" in + --framework) FRAMEWORK="$2"; shift 2 ;; + --target) TARGET_OVERRIDE="$2"; shift 2 ;; + *) die "Unknown argument: $1 (use --framework or --target )" ;; + esac +done +[[ -n "$TARGET_OVERRIDE" ]] && VAULT_DIR="$TARGET_OVERRIDE" + # ── Banner ──────────────────────────────────────────────────────────────────── print_banner "Setup " echo -e " Repo: ${BOLD}${REPO_DIR}${NC}" @@ -26,21 +42,23 @@ echo -e " Vault: ${BOLD}${VAULT_DIR}${NC}" echo "" # ── Confirm vault location ──────────────────────────────────────────────────── -echo -e "${BOLD}Is this your Obsidian vault folder?${NC}" -echo -e " ${DIM}${VAULT_DIR}${NC}" -echo "" -echo -e " ${BOLD}y)${NC} Yes, install here" -echo -e " ${BOLD}n)${NC} No, let me type the correct path" -if ! read -r -p " > " CONFIRM 2>/dev/null; then CONFIRM=""; fi - -if [[ "$CONFIRM" =~ ^[Nn]$ ]]; then +if [[ -z "$TARGET_OVERRIDE" ]]; then + echo -e "${BOLD}Is this your Obsidian vault folder?${NC}" + echo -e " ${DIM}${VAULT_DIR}${NC}" echo "" - echo -e "${BOLD}Enter the full path to your Obsidian vault:${NC}" - if ! read -r -p " > " VAULT_DIR 2>/dev/null; then - die "Cannot read input — are you running in a non-interactive shell?" + echo -e " ${BOLD}y)${NC} Yes, install here" + echo -e " ${BOLD}n)${NC} No, let me type the correct path" + if ! read -r -p " > " CONFIRM 2>/dev/null; then CONFIRM=""; fi + + if [[ "$CONFIRM" =~ ^[Nn]$ ]]; then + echo "" + echo -e "${BOLD}Enter the full path to your Obsidian vault:${NC}" + if ! read -r -p " > " VAULT_DIR 2>/dev/null; then + die "Cannot read input — are you running in a non-interactive shell?" + fi + VAULT_DIR="${VAULT_DIR/#\~/$HOME}" + [[ -d "$VAULT_DIR" ]] || die "Directory not found: $VAULT_DIR" fi - VAULT_DIR="${VAULT_DIR/#\~/$HOME}" - [[ -d "$VAULT_DIR" ]] || die "Directory not found: $VAULT_DIR" fi # ── Check for existing installation ────────────────────────────────────────── @@ -66,14 +84,20 @@ fi echo "" +# ── Build the framework dist ─────────────────────────────────────────────── +info "Building $FRAMEWORK adapter..." +bash "$SCRIPT_DIR/build.sh" --framework "$FRAMEWORK" +DIST_DIR="$REPO_DIR/dist/$FRAMEWORK" +[[ -d "$DIST_DIR" ]] || die "Build did not produce $DIST_DIR" + # ── Migrate legacy manifests (if any) ──────────────────────────────────────── manifest_migrate # ── Deprecate agents/refs removed from repo (reinstall only) ───────────────── DEP_COUNT=0 if [[ $EXISTING -eq 1 ]]; then - DEP_COUNT=$(deprecate_removed "agents" "$REPO_DIR/agents" "$VAULT_DIR/.claude/agents") - DEP_COUNT=$((DEP_COUNT + $(deprecate_removed "references" "$REPO_DIR/references" "$VAULT_DIR/.claude/references"))) + DEP_COUNT=$(deprecate_removed "agents" "$DIST_DIR/.claude/agents" "$VAULT_DIR/.claude/agents") + DEP_COUNT=$((DEP_COUNT + $(deprecate_removed "references" "$DIST_DIR/.claude/references" "$VAULT_DIR/.claude/references"))) fi # ── Ensure vault support dirs ───────────────────────────────────────────────── @@ -81,19 +105,19 @@ mkdir -p "$VAULT_DIR/Meta/states" # ── Install components ──────────────────────────────────────────────────────── info "Installing agents..." -AGENT_COUNT=$(install_agents "$REPO_DIR/agents" "$VAULT_DIR/.claude/agents") +AGENT_COUNT=$(install_agents "$DIST_DIR/.claude/agents" "$VAULT_DIR/.claude/agents") success "Agents: $AGENT_COUNT installed/updated" info "Installing references..." -REF_COUNT=$(install_refs "$REPO_DIR/references" "$VAULT_DIR/.claude/references") +REF_COUNT=$(install_refs "$DIST_DIR/.claude/references" "$VAULT_DIR/.claude/references") success "References: $REF_COUNT installed/updated" info "Installing skills..." -SKILL_COUNT=$(install_skills "$REPO_DIR/skills" "$VAULT_DIR/.claude/skills") +SKILL_COUNT=$(install_skills "$DIST_DIR/.claude/skills" "$VAULT_DIR/.claude/skills") success "Skills: $SKILL_COUNT installed/updated" info "Installing hooks..." -HOOK_COUNT=$(install_hooks "$REPO_DIR/hooks" "$VAULT_DIR/.claude/hooks") +HOOK_COUNT=$(install_hooks "$DIST_DIR/.claude/hooks" "$VAULT_DIR/.claude/hooks") success "Hooks: $HOOK_COUNT installed/updated" # ── Deprecate stale orchestra scripts on reinstall ────────────────────────── @@ -132,31 +156,12 @@ if [[ -f "$REPO_DIR/CLAUDE.md" ]]; then success "Copied CLAUDE.md" fi +install_settings "$DIST_DIR/.claude/settings.json" "$VAULT_DIR/.claude" +install_dispatcher "$DIST_DIR/CLAUDE.md" "$VAULT_DIR/CLAUDE.md" -install_settings "$REPO_DIR/settings.json" "$VAULT_DIR/.claude" -install_claude_md "$REPO_DIR/DISPATCHER.md" "$VAULT_DIR" - -# ── MCP servers (Gmail + Calendar) ─────────────────────────────────────────── -echo "" -echo -e "${BOLD}Do you use Gmail, Hey.com, or Google Calendar?${NC}" -echo -e " ${DIM}The Postman agent can read your inbox and calendar.${NC}" -echo -e " ${DIM}Gmail uses MCP connectors (read-only). For full access, set up GWS CLI later.${NC}" -echo -e " ${DIM}Hey.com uses the Hey CLI (install from https://github.com/basecamp/hey-cli).${NC}" -echo -e " ${DIM}You can always add this later.${NC}" -echo "" -echo -e " ${BOLD}y)${NC} Yes, set up Gmail + Calendar (MCP connectors)" -echo -e " ${BOLD}n)${NC} No, skip for now" -if ! read -r -p " > " MCP_ANSWER 2>/dev/null; then MCP_ANSWER=""; fi - -if [[ "$MCP_ANSWER" =~ ^[Yy]$ ]]; then - if [[ -f "$VAULT_DIR/.mcp.json" ]]; then - warn ".mcp.json already exists — skipping (won't overwrite)" - else - cp "$REPO_DIR/.mcp.json" "$VAULT_DIR/.mcp.json" - success "Created .mcp.json (Gmail + Google Calendar)" - fi -else - info "Skipped MCP setup" +# ── MCP servers ─────────────────────────────────────────────────────────────── +if [[ -f "$DIST_DIR/.mcp.json" ]]; then + copy_if_changed "$DIST_DIR/.mcp.json" "$VAULT_DIR/.mcp.json" fi # ── Done ────────────────────────────────────────────────────────────────────── diff --git a/scripts/lib.sh b/scripts/lib.sh index c26ff53..844aecf 100755 --- a/scripts/lib.sh +++ b/scripts/lib.sh @@ -305,7 +305,7 @@ install_agents() { manifest+=("$name") copy_if_changed "$src" "$dst_dir/$name" if [[ $_LAST_CHANGED -eq 1 ]]; then - [[ $VERBOSE_COPY -eq 1 ]] && info "Updated agent: $name" + [[ $VERBOSE_COPY -eq 1 ]] && info "Updated agent: $name" || true count=$((count + 1)) fi done @@ -328,7 +328,7 @@ install_refs() { copy_if_changed "$src" "$dst" fi if [[ $_LAST_CHANGED -eq 1 ]]; then - [[ $VERBOSE_COPY -eq 1 ]] && info "Updated reference: $name" + [[ $VERBOSE_COPY -eq 1 ]] && info "Updated reference: $name" || true count=$((count + 1)) fi done @@ -347,7 +347,7 @@ install_skills() { mkdir -p "$dst_dir/$name" copy_if_changed "${skill_src}SKILL.md" "$dst_dir/$name/SKILL.md" if [[ $_LAST_CHANGED -eq 1 ]]; then - [[ $VERBOSE_COPY -eq 1 ]] && info "Updated skill: $name" + [[ $VERBOSE_COPY -eq 1 ]] && info "Updated skill: $name" || true count=$((count + 1)) fi done @@ -368,7 +368,7 @@ install_hooks() { copy_if_changed "$src" "$dst" if [[ $_LAST_CHANGED -eq 1 ]]; then chmod +x "$dst" - [[ $VERBOSE_COPY -eq 1 ]] && info "Updated hook: $name" + [[ $VERBOSE_COPY -eq 1 ]] && info "Updated hook: $name" || true count=$((count + 1)) fi done @@ -393,19 +393,19 @@ install_settings() { cp "$dst" "${dst}.bak" cp "$src" "$dst" _LAST_CHANGED=1 - [[ $VERBOSE_COPY -eq 1 ]] && info "Updated settings.json (previous version saved as settings.json.bak)" - [[ $VERBOSE_COPY -eq 1 ]] && info "For custom hooks, use settings.local.json instead" + [[ $VERBOSE_COPY -eq 1 ]] && info "Updated settings.json (previous version saved as settings.json.bak)" || true + [[ $VERBOSE_COPY -eq 1 ]] && info "For custom hooks, use settings.local.json instead" || true fi } -# install_claude_md -# Copies DISPATCHER.md (src) to vault_dir/CLAUDE.md. +# install_dispatcher +# Copies the source dispatcher file (CLAUDE.md or AGENTS.md) to the destination. # Sets _LAST_CHANGED. -install_claude_md() { - local src="$1" vault_dir="$2" +install_dispatcher() { + local src="$1" dst="$2" [[ -f "$src" ]] || return 0 - copy_if_changed "$src" "$vault_dir/CLAUDE.md" - [[ $_LAST_CHANGED -eq 1 && $VERBOSE_COPY -eq 1 ]] && info "Updated CLAUDE.md" + copy_if_changed "$src" "$dst" + [[ $_LAST_CHANGED -eq 1 && $VERBOSE_COPY -eq 1 ]] && info "Updated $(basename "$dst")" || true } # ── UI helpers ──────────────────────────────────────────────────────────────── diff --git a/scripts/updateme.sh b/scripts/updateme.sh index a75ef93..85e8257 100755 --- a/scripts/updateme.sh +++ b/scripts/updateme.sh @@ -8,6 +8,9 @@ # git pull # bash scripts/updateme.sh # +# Options: +# --framework Framework to build for (default: claude-code) +# --target Override the vault destination path # ============================================================================= set -eo pipefail @@ -18,6 +21,18 @@ source "$SCRIPT_DIR/lib.sh" resolve_paths "${BASH_SOURCE[0]}" +# ── Parse args ───────────────────────────────────────────────────────────── +FRAMEWORK="claude-code" +TARGET_OVERRIDE="" +while [[ $# -gt 0 ]]; do + case "$1" in + --framework) FRAMEWORK="$2"; shift 2 ;; + --target) TARGET_OVERRIDE="$2"; shift 2 ;; + *) die "Unknown argument: $1" ;; + esac +done +[[ -n "$TARGET_OVERRIDE" ]] && VAULT_DIR="$TARGET_OVERRIDE" + # ── Banner ──────────────────────────────────────────────────────────────────── print_banner "Update " @@ -39,12 +54,18 @@ if [[ ! "$ANSWER" =~ ^[Cc]$ ]]; then fi echo "" +# ── Build the framework dist ─────────────────────────────────────────────── +info "Building $FRAMEWORK adapter..." +bash "$SCRIPT_DIR/build.sh" --framework "$FRAMEWORK" +DIST_DIR="$REPO_DIR/dist/$FRAMEWORK" +[[ -d "$DIST_DIR" ]] || die "Build did not produce $DIST_DIR" + # ── Migrate legacy manifests (if any) ──────────────────────────────────────── manifest_migrate # ── Deprecate agents/refs removed from repo ────────────────────────────────── -DEP_COUNT=$(deprecate_removed "agents" "$REPO_DIR/agents" "$VAULT_DIR/.claude/agents") -DEP_COUNT=$((DEP_COUNT + $(deprecate_removed "references" "$REPO_DIR/references" "$VAULT_DIR/.claude/references"))) +DEP_COUNT=$(deprecate_removed "agents" "$DIST_DIR/.claude/agents" "$VAULT_DIR/.claude/agents") +DEP_COUNT=$((DEP_COUNT + $(deprecate_removed "references" "$DIST_DIR/.claude/references" "$VAULT_DIR/.claude/references"))) # ── Ensure vault support dirs ───────────────────────────────────────────────── mkdir -p "$VAULT_DIR/Meta/states" @@ -52,17 +73,22 @@ mkdir -p "$VAULT_DIR/Meta/states" # ── Update components (per-file logging enabled) ───────────────────────────── VERBOSE_COPY=1 -AGENT_COUNT=$(install_agents "$REPO_DIR/agents" "$VAULT_DIR/.claude/agents") -REF_COUNT=$(install_refs "$REPO_DIR/references" "$VAULT_DIR/.claude/references") -SKILL_COUNT=$(install_skills "$REPO_DIR/skills" "$VAULT_DIR/.claude/skills") -HOOK_COUNT=$(install_hooks "$REPO_DIR/hooks" "$VAULT_DIR/.claude/hooks") +AGENT_COUNT=$(install_agents "$DIST_DIR/.claude/agents" "$VAULT_DIR/.claude/agents") +REF_COUNT=$(install_refs "$DIST_DIR/.claude/references" "$VAULT_DIR/.claude/references") +SKILL_COUNT=$(install_skills "$DIST_DIR/.claude/skills" "$VAULT_DIR/.claude/skills") +HOOK_COUNT=$(install_hooks "$DIST_DIR/.claude/hooks" "$VAULT_DIR/.claude/hooks") -install_settings "$REPO_DIR/settings.json" "$VAULT_DIR/.claude" +install_settings "$DIST_DIR/.claude/settings.json" "$VAULT_DIR/.claude" SETTINGS_CHANGED=$_LAST_CHANGED -install_claude_md "$REPO_DIR/DISPATCHER.md" "$VAULT_DIR" +install_dispatcher "$DIST_DIR/CLAUDE.md" "$VAULT_DIR/CLAUDE.md" CLAUDE_MD_CHANGED=$_LAST_CHANGED +# ── MCP servers ─────────────────────────────────────────────────────────────── +if [[ -f "$DIST_DIR/.mcp.json" ]]; then + copy_if_changed "$DIST_DIR/.mcp.json" "$VAULT_DIR/.mcp.json" +fi + # ── Summary ─────────────────────────────────────────────────────────────────── echo "" TOTAL=$((AGENT_COUNT + REF_COUNT + SKILL_COUNT + HOOK_COUNT + SETTINGS_CHANGED + CLAUDE_MD_CHANGED))