bootstrap-claude-plugins.sh 2.79 KB
# !/usr/bin/env bash
set -euo pipefail

CLAUDE_CONFIG_DIR=${CLAUDE_CONFIG_DIR:-"${HOME}/.claude"}
BOOTSTRAP_MARKER=${BOOTSTRAP_MARKER:-"${CLAUDE_CONFIG_DIR}/.bootstrap-plugins-done"}
CLAUDE_FORCE_PLUGIN_BOOTSTRAP=${CLAUDE_FORCE_PLUGIN_BOOTSTRAP:-0}
CLAUDE_SKIP_SETTINGS_INIT=${CLAUDE_SKIP_SETTINGS_INIT:-0}
CLAUDE_ENABLE_THIRD_PARTY=${CLAUDE_ENABLE_THIRD_PARTY:-0}
DEFAULT_PLUGIN_LIST="superpowers pr-review-toolkit claude-code-setup ralph-loop typescript-lsp rust-analyzer-lsp"
CLAUDE_PLUGIN_LIST=${CLAUDE_PLUGIN_LIST:-"$DEFAULT_PLUGIN_LIST"}

require_claude() {
  if ! command -v claude >/dev/null 2>&1; then
    echo "[error] 未找到 claude 命令,请先安装 Claude Code。" >&2
    exit 1
  fi
}

check_auth() {
  if [ -n "${ANTHROPIC_API_KEY:-}" ] || [ -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ] || [ -f "${CLAUDE_CONFIG_DIR}/.credentials.json" ]; then
    return
  fi

  cat <<'EOF'
[warn] 未检测到认证信息。
[warn] 可稍后配置以下任一方式后重跑脚本:
       export ANTHROPIC_API_KEY=...
       export CLAUDE_CODE_OAUTH_TOKEN=...
EOF
}

prepare_config_dir() {
  mkdir -p "$CLAUDE_CONFIG_DIR"
  chmod 700 "$CLAUDE_CONFIG_DIR"
}

already_bootstrapped() {
  [ "$CLAUDE_FORCE_PLUGIN_BOOTSTRAP" != "1" ] && [ -f "$BOOTSTRAP_MARKER" ]
}

install_plugin() {
  local plugin=$1
  echo "[plugin] 安装 $plugin..."
  if printf '/plugin install %s@claude-plugins-official\n/reload-plugins\n/exit\n' "$plugin" | claude >/tmp/claude-plugin-${plugin}.log 2>&1; then
    echo "[plugin] $plugin 安装完成"
    return 0
  fi

  echo "[plugin] $plugin 安装失败,详见 /tmp/claude-plugin-${plugin}.log" >&2
  return 1
}

init_settings() {
  local settings_file="${CLAUDE_CONFIG_DIR}/settings.json"
  if [ "$CLAUDE_SKIP_SETTINGS_INIT" = "1" ] || [ -f "$settings_file" ]; then
    return
  fi

  cat >"$settings_file" <<'EOF'
{
  "modelType": "anthropic",
  "alwaysThinkingEnabled": false,
  "skipDangerousModePermissionPrompt": true,
  "permissions": {
    "allow": [
      "git status",
      "git diff",
      "git log",
      "ls",
      "pwd"
    ],
    "deny": []
  }
}
EOF
}

install_default_plugins() {
  local failed=0
  local plugin

  echo "[info] 默认插件列表: $CLAUDE_PLUGIN_LIST"
  for plugin in $CLAUDE_PLUGIN_LIST; do
    if ! install_plugin "$plugin"; then
      failed=1
    fi
  done

  if [ "$CLAUDE_ENABLE_THIRD_PARTY" = "1" ]; then
    echo "[info] 已启用第三方扩展位,但当前未配置第三方插件。"
  fi

  return "$failed"
}

write_marker() {
  date -u +"%Y-%m-%dT%H:%M:%SZ" >"$BOOTSTRAP_MARKER"
}

main() {
  require_claude
  prepare_config_dir
  check_auth

  if already_bootstrapped; then
    echo "[info] 检测到已完成 bootstrap,跳过。"
    return
  fi

  install_default_plugins
  init_settings
  write_marker
  echo "[done] Claude Code 插件 bootstrap 完成。"
}

main "$@"