Skill: wjneng/flutter-cn-setup (version 0.0.1)

--- name: flutter-cn-setup description: 为中国区开发者在新电脑上搭建完整 Flutter 开发环境，覆盖 Android/iOS toolchain、镜像配置、诊断和验收。用户提到安装 Flutter、中国区镜像、修复 flutter doctor、或新 macOS 初始化 Flutter 环境时使用。 --- # Flutter CN 环境安装 ## 快速开始 大多数场景直接执行： ```bash cd .cursor/skills/flutter-cn-setup bash scripts/bootstrap-flutter-cn.sh bash scripts/validate-flutter-cn.sh ``` 仅 Android 快速路径： ```bash cd .cursor/skills/flutter-cn-setup NEED_IOS=no bash scripts/bootstrap-flutter-cn.sh NEED_IOS=no bash scripts/validate-flutter-cn.sh ``` ## 适用范围 本 Skill 用于在中国区网络下，为 **全新 macOS 设备**搭建完整 Flutter 环境。 目标结果： - Flutter SDK 已安装并加入 `PATH` - Flutter 与 Dart 包下载镜像已配置 - Android toolchain 可用（Android Studio + SDK + licenses） - iOS toolchain 可用（Xcode + CocoaPods，按需） - `flutter doctor` 达到可日常开发状态 ## 快速诊断 1. 确认系统与芯片架构： - `uname -m`（期望 `arm64` 或 `x86_64`） - `sw_vers` 2. 检查 Homebrew 是否存在： - `brew --version` 3. 检查当前 Flutter 状态： - `which flutter` - `flutter --version` - `flutter doctor -v` 4. 若已安装 Flutter，优先 **修复/升级**，除非用户明确要求全量重装。 ## 中国区镜像配置 下载依赖前先配置： ```bash export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn ``` 持久化到 shell 配置（zsh 默认 `~/.zshrc`）： ```bash cat <<'EOF' >> ~/.zshrc # Flutter 中国区镜像 export PUB_HOSTED_URL=https://pub.flutter-io.cn export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn EOF source ~/.zshrc ``` 如果镜像不稳定，先和用户确认替代方案再切换 URL。 ## 安装流程（macOS） 可复制以下清单跟踪进度： ```text Flutter CN 安装进度 - [ ] 1) 安装基础工具（git、curl、unzip、xz） - [ ] 2) 安装 Flutter SDK - [ ] 3) 配置 PATH 与镜像 - [ ] 4) 执行 flutter precache 与 doctor - [ ] 5) 安装 Android Studio + Android SDK + licenses - [ ] 6) 安装 Xcode + CocoaPods（如需 iOS） - [ ] 7) 验证 Android emulator / iOS simulator - [ ] 8) 创建并运行示例应用 ``` ### 1) 基础工具 优先使用 Homebrew： ```bash brew install git curl unzip xz ``` 如果缺少 Homebrew，先安装后重试。 ### 2) 安装 Flutter SDK 推荐目录： - Apple Silicon：`~/development/flutter` - Intel：`~/development/flutter` 建议使用 git 安装（便于后续升级）： ```bash mkdir -p ~/development git clone https://github.com/flutter/flutter.git -b stable ~/development/flutter ``` ### 3) 配置 PATH 与镜像 添加 Flutter 可执行路径： ```bash cat <<'EOF' >> ~/.zshrc # Flutter SDK 路径 export PATH="$PATH:$HOME/development/flutter/bin" EOF source ~/.zshrc ``` 确认 `~/.zshrc` 中也已写入镜像变量（见上文镜像配置）。 ### 4) 执行 precache 与 doctor ```bash flutter --version flutter precache flutter doctor -v ``` 若提示命令不存在，重新打开终端或再次 `source` shell profile 后重试。 ### 5) Android toolchain 1. 安装 Android Studio（图形界面安装即可）。 2. 打开 Android Studio 一次，完成首次 SDK 初始化。 3. 确认已安装以下 SDK 组件： - Android SDK Platform (latest stable API) - Android SDK Platform-Tools - Android SDK Command-line Tools - Android Emulator 4. 接受 licenses： ```bash flutter doctor --android-licenses ``` 若提示缺少 `sdkmanager`，在 SDK Manager 补装 command-line tools 后重试。 ### 6) iOS toolchain（按需） 1. 从 App Store 安装 Xcode。 2. 执行： ```bash sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer sudo xcodebuild -runFirstLaunch ``` 3. 安装 CocoaPods： ```bash brew install cocoapods pod --version ``` 若 CocoaPods 因网络或权限失败，优先使用 Homebrew 路径，不要先切 Ruby gem 方案。 ### 7) 设备与模拟器就绪检查 ```bash flutter devices ``` 期望结果： - Android 开发至少有一个 emulator 或真机 - iOS 开发可识别 simulator（`open -a Simulator`） ### 8) 端到端验证 ```bash flutter create hello_flutter_cn cd hello_flutter_cn flutter pub get flutter run ``` 若 pub 下载慢或失败，重新检查**当前 shell 会话**与 shell profile 中的镜像变量。 ## 常见问题处理 ### `flutter doctor` 提示 Android toolchain 缺失 - 确保 Android Studio 至少打开并初始化过一次。 - 检查 Flutter 的 Android SDK 配置： - `flutter config --android-sdk <sdk-path>` - 重新执行： - `flutter doctor -v` - `flutter doctor --android-licenses` ### `Unable to find git in your PATH` - 安装 git（`brew install git`） - 重启终端 - 验证 `git --version` ### CocoaPods repo/spec timeout - 先确认基础网络与镜像配置。 - 重试 `pod --version` 与 iOS 构建。 - 仍失败时，先记录完整报错，再与用户确定 mirror/proxy 策略。 ### Xcode license 或首次启动未完成 - 执行： - `sudo xcodebuild -license accept` - `sudo xcodebuild -runFirstLaunch` ## 工具脚本 使用内置脚本执行可重复安装： ```bash bash scripts/bootstrap-flutter-cn.sh ``` 可选环境变量： ```bash NEED_IOS=no \ FLUTTER_DIR="$HOME/development/flutter" \ SHELL_PROFILE="$HOME/.zshrc" \ bash scripts/bootstrap-flutter-cn.sh ``` 脚本行为： - 通过 Homebrew 安装基础工具 - 通过 git 安装或更新 Flutter `stable` - 以幂等方式写入镜像和 PATH - 执行 `flutter precache` 与 `flutter doctor -v` - 输出 Android/iOS 后续人工步骤 - 创建冒烟工程 `~/hello_flutter_cn` 执行验收： ```bash bash scripts/validate-flutter-cn.sh ``` 验收参数： ```bash # 仅 Android NEED_IOS=no bash scripts/validate-flutter-cn.sh # 仅 iOS NEED_ANDROID=no bash scripts/validate-flutter-cn.sh ``` 验收输出： - 每项检查输出 PASS/WARN/FAIL - 最终结果：`READY for development` 或 `NOT READY` - 退出码：ready 为 `0`，not ready 为 `1` ## 验收闭环 排障时建议按以下循环执行： 1. 运行 bootstrap 脚本： - `bash scripts/bootstrap-flutter-cn.sh` 2. 运行 validator： - `bash scripts/validate-flutter-cn.sh` 3. 如果 validator 失败： - 先修复优先级最高的 FAIL 项 - 再次运行 validator 4. 仅当结果为 `READY for development` 时结束 ## 技能输出格式 执行本 Skill 后给用户的回复应包含： 1. **当前状态**：已安装与缺失项 2. **已执行命令**：按阶段归类 3. **阻塞问题**：精确报错与可能原因 4. **下一步动作**：最小可执行解阻命令 5. **最终验收**：对 `flutter doctor -v` 的简明结论 ## 约束 - 不要默认要求 iOS；先确认用户是否仅需 Android。 - 默认使用 stable channel，除非用户明确要求 beta/master。 - 不要粗暴覆盖 shell profile；优先幂等追加。 - 不要默认卸载现有 SDK，除非用户明确要求清理。 ## 附加资料 - 错误到修复速查：`[troubleshooting.md](troubleshooting.md)` - 分场景回复模板：`[examples.md](examples.md)` - Skill 回归检查清单：`[self-test.md](self-test.md)`

path: examples.md
content: # Flutter CN 示例模板

在执行本 Skill 时，可直接复用以下输出模板。

## 示例 1：全新 macOS（Android + iOS）

### 用户诉求
在中国区网络下，从 0 安装完整 Flutter 开发环境。

### 建议执行
```bash
cd .cursor/skills/flutter-cn-setup
bash scripts/bootstrap-flutter-cn.sh
bash scripts/validate-flutter-cn.sh
```

### 建议回复格式
```markdown
当前状态
- 已安装：Homebrew、Git、Flutter stable
- 已配置：中国区镜像、Flutter PATH
- 待完成：Android Studio 首次初始化、Xcode 首次启动

已执行命令
- bootstrap-flutter-cn.sh
- validate-flutter-cn.sh

阻塞问题
- Android licenses 尚未接受
- Xcode 首次启动未完成

下一步
- flutter doctor --android-licenses
- sudo xcodebuild -runFirstLaunch

最终验收
- 环境接近可用，完成上述两步后重新执行 validator。
```

## 示例 2：仅 Android 环境

### 用户诉求
只做 Android 开发，不需要 iOS。

### 建议执行
```bash
cd .cursor/skills/flutter-cn-setup
NEED_IOS=no bash scripts/bootstrap-flutter-cn.sh
NEED_IOS=no bash scripts/validate-flutter-cn.sh
```

### 建议回复格式
```markdown
当前状态
- Android toolchain 与 Flutter 已就绪
- iOS 检查按需跳过

已执行命令
- NEED_IOS=no bootstrap 脚本
- NEED_IOS=no validator 脚本

阻塞问题
- 无

下一步
- 启动模拟器并运行示例工程

最终验收
- Android 开发环境已就绪（READY）。
```

## 示例 3：已安装 Flutter，但 `doctor` 报错

### 用户诉求
在不全量重装的前提下修复现有环境。

### 建议执行
```bash
cd .cursor/skills/flutter-cn-setup
bash scripts/validate-flutter-cn.sh || true
# 先修复报告中优先级最高的 FAIL 项
bash scripts/bootstrap-flutter-cn.sh
bash scripts/validate-flutter-cn.sh
```

### 建议回复格式
```markdown
当前状态
- 检测到已有 Flutter，并已更新到 stable
- 当前 shell 配置中的镜像已修正

已执行命令
- 验收 -> 安装修复 -> 验收

阻塞问题
- iOS 依赖阶段 CocoaPods 超时

下一步
- cd ios && pod install --verbose
- 若仍超时，记录失败 host/path 后再做针对性网络策略

最终验收
- Android 已可用；iOS 仍受 CocoaPods 网络问题影响。
```

## 使用要求

对用户反馈结果时，至少包含：
- 已完成内容
- 当前阻塞项
- 最小可执行的下一条命令


path: troubleshooting.md
content: # Flutter CN 故障速查

本手册用于中国区 Flutter 环境常见问题的快速定位与修复。

## 1) `flutter pub get` 很慢或超时

### 现象
- `Resolving dependencies...` 长时间卡住
- 访问 `pub.dev` 出现连接超时

### 检查
```bash
echo "$PUB_HOSTED_URL"
echo "$FLUTTER_STORAGE_BASE_URL"
```

期望值：
- `https://pub.flutter-io.cn`
- `https://storage.flutter-io.cn`

### 处理
```bash
export PUB_HOSTED_URL=https://pub.flutter-io.cn
export FLUTTER_STORAGE_BASE_URL=https://storage.flutter-io.cn
flutter pub get -v
```

如果生效，请写入 `~/.zshrc` 并重开终端。

## 2) Gradle 依赖下载慢或失败

### 现象
- Android 构建卡在 `Download https://services.gradle.org/...`
- Gradle 依赖频繁出现 `Read timed out`

### 建议策略
- 优先使用稳定网络链路（办公网络、可用代理/VPN）。
- 团队仓库中不要默认改项目级 Gradle 镜像，除非用户明确要求。

### 可选：仅本机优化
编辑 `~/.gradle/gradle.properties`：

```properties
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.jvmargs=-Xmx4g -Dfile.encoding=UTF-8
org.gradle.internal.http.connectionTimeout=120000
org.gradle.internal.http.socketTimeout=120000
```

然后执行：
```bash
cd android
./gradlew --refresh-dependencies
```

## 3) CocoaPods 安装或更新超时

### 现象
- `pod install` hangs or fails on spec repo update
- CDN 拉取超时

### 检查
```bash
pod --version
which pod
```

### 处理顺序
1. 优先确认 CocoaPods 来自 Homebrew：
   ```bash
   brew install cocoapods
   ```
2. 在 iOS 目录重试并打开详细日志：
   ```bash
   cd ios
   pod install --verbose
   ```
3. 若仍失败，先记录失败的 host/path，再决定是否更改源配置。

## 4) `flutter doctor` 缺少 `Android toolchain`

### 现象
- `Android toolchain - develop for Android devices` 显示 `✗`
- 提示缺少 `cmdline-tools` 或 licenses

### 处理
1. 打开一次 Android Studio 并完成初始化向导。
2. 在 SDK Manager 安装：
   - Android SDK Platform
   - Android SDK Platform-Tools
   - Android SDK Command-line Tools
3. 执行：
   ```bash
   flutter doctor --android-licenses
   flutter doctor -v
   ```

如果 SDK 路径是自定义：
```bash
flutter config --android-sdk "$HOME/Library/Android/sdk"
```

## 5) Xcode 未配置完成

### 现象
- `Xcode - develop for iOS and macOS` 显示 `✗`
- license 或首次启动未完成

### 处理
```bash
sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
sudo xcodebuild -license accept
sudo xcodebuild -runFirstLaunch
flutter doctor -v
```

## 6) `git` 找不到 / `flutter` 命令找不到

### 现象
- `Unable to find git in your PATH`
- `zsh: command not found: flutter`

### 处理
```bash
brew install git
echo 'export PATH="$PATH:$HOME/development/flutter/bin"' >> ~/.zshrc
source ~/.zshrc
git --version
flutter --version
```

## 7) 检测不到模拟器/设备

### 现象
- `flutter devices` 返回无设备

### 处理
- Android：在 Android Studio Device Manager 启动 emulator。
- iOS:
  ```bash
  open -a Simulator
  flutter devices
  ```

如果使用真机，确认 USB 调试/信任流程已完成。

## 最小化排障信息采集

需要升级排障时，先收集：

```bash
flutter doctor -v
flutter devices
flutter --version
echo "$PUB_HOSTED_URL"
echo "$FLUTTER_STORAGE_BASE_URL"
```

请提供：执行命令、完整报错、开始出现问题的时间点。


path: self-test.md
content: # Flutter CN Skill 自测清单

用这个清单验证 Skill 是否可发现、可执行、输出一致。

## 1) 发现能力测试（触发覆盖）

可使用以下提示词测试：
- "帮我在新 Mac 上装 Flutter，中国区网络"
- "配置 Flutter 镜像，`flutter doctor` 还有报错"
- "只需要 Android 的 Flutter 开发环境"
- "新电脑装完整 Flutter + Android Studio + Xcode"

通过标准：
- Skill 能被自动命中。
- 回复遵循本 Skill 流程，而非泛化建议。

## 2) 脚本路径测试

在项目根目录执行：

```bash
ls .cursor/skills/flutter-cn-setup/scripts/bootstrap-flutter-cn.sh
ls .cursor/skills/flutter-cn-setup/scripts/validate-flutter-cn.sh
```

通过标准：
- 两个脚本路径均存在且可执行。

## 3) 安装脚本基础可运行测试

先用保守模式：

```bash
cd .cursor/skills/flutter-cn-setup
NEED_IOS=no bash scripts/bootstrap-flutter-cn.sh
```

通过标准：
- 脚本无语法报错并正常退出。
- shell profile 追加是幂等的（重复执行不会大量重复写入）。

## 4) 验收输出契约测试

```bash
cd .cursor/skills/flutter-cn-setup
NEED_IOS=no bash scripts/validate-flutter-cn.sh; echo $?
```

通过标准：
- 输出包含 PASS/WARN/FAIL 计数。
- 输出包含最终结论（`READY for development` 或 `NOT READY`）。
- 退出码与结论一致（就绪为 `0`，未就绪为 `1`）。

## 5) 文档链接测试

打开 `SKILL.md` 检查以下链接：
- `troubleshooting.md`
- `examples.md`
- `self-test.md`

通过标准：
- 链接都为一层引用且可访问。

## 6) 回复质量契约

调用 Skill 时，检查输出至少包含：
1. 当前状态
2. 已执行命令（或下一步命令）
3. 阻塞问题
4. 最小下一步动作
5. 最终验收结论

通过标准：
- 五个部分齐全，表达简洁。

## 7) 回归场景

至少覆盖以下两条路径：
- 仅 Android：`NEED_IOS=no`
- 已有 Flutter 修复：validate -> bootstrap -> validate

通过标准：
- 不出现相互矛盾的操作指令。
- 阻塞项解法有明确优先级。

## 8) 安全操作检查

通过标准：
- 默认不包含破坏性卸载操作。
- 不强制覆盖 shell profile。
- iOS 为可选，不是必选。
- 默认保持 stable channel。

## 发布门禁

仅在以下条件全部通过时标记为 ready：
- 发现能力测试通过
- 脚本与文档检查通过
- 回复质量契约通过


path: scripts/bootstrap-flutter-cn.sh
content: #!/usr/bin/env bash

set -euo pipefail

FLUTTER_DIR="${FLUTTER_DIR:-$HOME/development/flutter}"
SHELL_PROFILE="${SHELL_PROFILE:-$HOME/.zshrc}"
NEED_IOS="${NEED_IOS:-yes}" # yes|no
MIRROR_PUB_URL="${MIRROR_PUB_URL:-https://pub.flutter-io.cn}"
MIRROR_STORAGE_URL="${MIRROR_STORAGE_URL:-https://storage.flutter-io.cn}"

log() {
  printf "\n[%s] %s\n" "$(date '+%H:%M:%S')" "$*"
}

has_cmd() {
  command -v "$1" >/dev/null 2>&1
}

append_if_missing() {
  local line="$1"
  local file="$2"
  if [[ ! -f "$file" ]]; then
    touch "$file"
  fi
  if ! grep -Fqx "$line" "$file"; then
    printf "%s\n" "$line" >> "$file"
  fi
}

check_macos() {
  if [[ "$(uname -s)" != "Darwin" ]]; then
    echo "This script is for macOS only."
    exit 1
  fi
}

install_base_tools() {
  if ! has_cmd brew; then
    cat <<'EOF'
Homebrew is not installed.
Install it first:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Then re-run this script.
EOF
    exit 1
  fi

  log "Installing base tools with Homebrew"
  brew install git curl unzip xz
}

install_or_update_flutter() {
  mkdir -p "$(dirname "$FLUTTER_DIR")"
  if [[ -d "$FLUTTER_DIR/.git" ]]; then
    log "Flutter exists, updating stable branch"
    git -C "$FLUTTER_DIR" fetch --tags
    git -C "$FLUTTER_DIR" checkout stable
    git -C "$FLUTTER_DIR" pull --ff-only
  else
    log "Cloning Flutter stable to $FLUTTER_DIR"
    git clone https://github.com/flutter/flutter.git -b stable "$FLUTTER_DIR"
  fi
}

configure_shell_profile() {
  log "Configuring mirrors and PATH in $SHELL_PROFILE"
  append_if_missing "# Flutter CN mirrors" "$SHELL_PROFILE"
  append_if_missing "export PUB_HOSTED_URL=$MIRROR_PUB_URL" "$SHELL_PROFILE"
  append_if_missing "export FLUTTER_STORAGE_BASE_URL=$MIRROR_STORAGE_URL" "$SHELL_PROFILE"
  append_if_missing "# Flutter SDK PATH" "$SHELL_PROFILE"
  append_if_missing "export PATH=\"\$PATH:$FLUTTER_DIR/bin\"" "$SHELL_PROFILE"

  # Also export in current shell for immediate usage.
  export PUB_HOSTED_URL="$MIRROR_PUB_URL"
  export FLUTTER_STORAGE_BASE_URL="$MIRROR_STORAGE_URL"
  export PATH="$PATH:$FLUTTER_DIR/bin"
}

run_flutter_checks() {
  log "Running flutter precache and doctor"
  flutter --version
  flutter precache
  flutter doctor -v
}

handle_android_reminder() {
  log "Android next steps"
  cat <<'EOF'
1) Install Android Studio and open it once.
2) In SDK Manager, install:
   - Android SDK Platform
   - Android SDK Platform-Tools
   - Android SDK Command-line Tools
   - Android Emulator
3) Then run:
   flutter doctor --android-licenses
   flutter doctor -v
EOF
}

handle_ios_reminder() {
  if [[ "$NEED_IOS" != "yes" ]]; then
    log "Skipping iOS setup reminder (NEED_IOS=$NEED_IOS)"
    return 0
  fi

  log "iOS next steps"
  cat <<'EOF'
1) Install Xcode from App Store.
2) Run:
   sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer
   sudo xcodebuild -runFirstLaunch
3) Install CocoaPods:
   brew install cocoapods
4) Verify:
   pod --version
   flutter doctor -v
EOF
}

create_smoke_project() {
  local project_dir="$HOME/hello_flutter_cn"
  if [[ -d "$project_dir" ]]; then
    log "Smoke project already exists: $project_dir"
    return 0
  fi

  log "Creating smoke test Flutter app at $project_dir"
  flutter create "$project_dir"
  (
    cd "$project_dir"
    flutter pub get
  )
}

main() {
  check_macos
  log "Starting Flutter CN bootstrap"
  log "Config: FLUTTER_DIR=$FLUTTER_DIR, SHELL_PROFILE=$SHELL_PROFILE, NEED_IOS=$NEED_IOS"

  install_base_tools
  install_or_update_flutter
  configure_shell_profile
  run_flutter_checks
  handle_android_reminder
  handle_ios_reminder
  create_smoke_project

  log "Done. Open a new terminal or run: source \"$SHELL_PROFILE\""
}

main "$@"


path: scripts/validate-flutter-cn.sh
content: #!/usr/bin/env bash

set -euo pipefail

NEED_IOS="${NEED_IOS:-yes}"         # yes|no
NEED_ANDROID="${NEED_ANDROID:-yes}" # yes|no

RED="$(printf '\033[31m')"
GREEN="$(printf '\033[32m')"
YELLOW="$(printf '\033[33m')"
RESET="$(printf '\033[0m')"

PASS_COUNT=0
FAIL_COUNT=0
WARN_COUNT=0

pass() {
  PASS_COUNT=$((PASS_COUNT + 1))
  printf "${GREEN}PASS${RESET} - %s\n" "$1"
}

fail() {
  FAIL_COUNT=$((FAIL_COUNT + 1))
  printf "${RED}FAIL${RESET} - %s\n" "$1"
}

warn() {
  WARN_COUNT=$((WARN_COUNT + 1))
  printf "${YELLOW}WARN${RESET} - %s\n" "$1"
}

has_cmd() {
  command -v "$1" >/dev/null 2>&1
}

check_cmd() {
  local cmd="$1"
  local label="$2"
  if has_cmd "$cmd"; then
    pass "$label"
  else
    fail "$label (missing command: $cmd)"
  fi
}

check_env() {
  local key="$1"
  local expected="$2"
  local actual="${!key:-}"
  if [[ "$actual" == "$expected" ]]; then
    pass "$key is set to $expected"
  elif [[ -z "$actual" ]]; then
    fail "$key is not set"
  else
    warn "$key is '$actual' (expected '$expected')"
  fi
}

check_flutter_doctor() {
  if ! has_cmd flutter; then
    fail "flutter doctor check skipped (flutter not found)"
    return
  fi

  local doctor_output
  doctor_output="$(flutter doctor -v 2>&1 || true)"

  if printf '%s' "$doctor_output" | grep -q "No issues found!"; then
    pass "flutter doctor reports no issues"
    return
  fi

  # Android checks
  if [[ "$NEED_ANDROID" == "yes" ]]; then
    if printf '%s' "$doctor_output" | grep -Eq "Android toolchain .* [•✓]" \
      && ! printf '%s' "$doctor_output" | grep -Eq "Android toolchain .* ✗"; then
      pass "Android toolchain is available"
    else
      fail "Android toolchain has issues"
    fi
  fi

  # iOS checks
  if [[ "$NEED_IOS" == "yes" ]]; then
    if printf '%s' "$doctor_output" | grep -Eq "Xcode .* [•✓]" \
      && ! printf '%s' "$doctor_output" | grep -Eq "Xcode .* ✗"; then
      pass "Xcode toolchain is available"
    else
      fail "Xcode toolchain has issues"
    fi

    if printf '%s' "$doctor_output" | grep -Eq "CocoaPods .* [•✓]" \
      && ! printf '%s' "$doctor_output" | grep -Eq "CocoaPods .* ✗"; then
      pass "CocoaPods is available"
    else
      fail "CocoaPods has issues"
    fi
  fi
}

check_devices() {
  if ! has_cmd flutter; then
    fail "flutter devices check skipped (flutter not found)"
    return
  fi

  local devices_output
  devices_output="$(flutter devices 2>&1 || true)"

  if printf '%s' "$devices_output" | grep -q "No devices detected"; then
    warn "No runtime devices detected (emulator/simulator/physical)"
    return
  fi

  pass "At least one Flutter runtime device is detected"
}

print_summary() {
  printf "\n====================\n"
  printf "Validation Summary\n"
  printf "PASS: %s\n" "$PASS_COUNT"
  printf "WARN: %s\n" "$WARN_COUNT"
  printf "FAIL: %s\n" "$FAIL_COUNT"
  printf "====================\n"

  if [[ "$FAIL_COUNT" -eq 0 ]]; then
    printf "${GREEN}Result: READY for development${RESET}\n"
    exit 0
  else
    printf "${RED}Result: NOT READY${RESET}\n"
    printf "Fix FAIL items, then rerun this validator.\n"
    exit 1
  fi
}

main() {
  echo "Flutter CN environment validation"
  echo "NEED_ANDROID=$NEED_ANDROID NEED_IOS=$NEED_IOS"
  echo

  check_cmd flutter "Flutter CLI installed"
  check_cmd git "Git installed"
  check_cmd brew "Homebrew installed"

  check_env PUB_HOSTED_URL "https://pub.flutter-io.cn"
  check_env FLUTTER_STORAGE_BASE_URL "https://storage.flutter-io.cn"

  check_flutter_doctor
  check_devices
  print_summary
}

main "$@"


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (HIGH)