Community编程与开发github.com

Expo 技能评估

端到端评估本仓库中的 Expo 技能——包括触发准确性、生成代码质量以及在 iOS 模拟器和 Android 模拟器上通过 Expo Go 运行时的截图(Web 可选)。在用户想要评估 Expo 技能、测试技能是否生成可用代码、使用设备截图对技能进行基准测试,或验证技能输出是否正确渲染时使用。

Expo 技能评估 是什么?

Expo 技能评估是一个全面的评估工具,用于端到端测试 `plugins/expo/skills/` 目录下的 Expo AI 技能。它支持评估触发准确性、生成代码质量以及运行时渲染效果,并能够在 iOS 模拟器和 Android 模拟器上通过 Expo Go 或开发构建(development build)生成截图。该工具支持运行自定义提示词、内置提示词以及基于上传截图的视觉测试,允许用户灵活配置评估维度。用户可以选择 Expo SDK 版本和运行平台(iOS/Android/Web),并控制是否将结果发布为可共享的 Artifact。该工具通过复杂的提示词配置和建议流程,确保用户明确评估范围,并通过多种评分维度(运行时截图、触发准确性、代码检查)提供全面的技能评估。

兼容平台✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/expo/skills/tree/main/.claude/skills/expo-skill-eval

Installed? Explore more 编程与开发 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

Expo 技能评估 是做什么的?

评估 plugins/expo/skills/ 中的技能在触发准确性、生成代码质量以及 Expo Go 中运行时渲染方面的表现。

要求:macOS 及 Xcode(iOS 模拟器)、安装了至少一个 AVD 的 Android SDK,以及 bun。不假设使用其他设备工具。

工作区根目录:/private/tmp/expo-skill-eval-<skill-name>/iteration-N/(例如 /private/tmp/expo-skill-eval-expo-ui/iteration-4/)。

开始前——明确范围

在开始任何管道工作之前,请先确认以下所有内容——不要跳过任何一项(如果请求中已明确说明某项选择,则跳过)。将它们分批放入 AskUserQuestion 调用中,每次不超过 4 个问题,按以下顺序:

  1. 要评估哪个技能(如果请求中未明确)。
  2. 提示词——驱动评估的提示词。内置提示词(来自技能的评估案例)默认全部选中;可以去掉一些,添加自定义文本提示词,或从上传的截图构建(技能必须重现的目标 UI)。详见提示词部分。
  3. 要验证的内容——三项多选:运行时 + 截图 / 触发准确性 / 代码检查(无设备)。详见要验证的内容部分。
  4. Expo SDK——最新版(默认,自动检测)或固定版本。
  5. 运行器——Expo Go(默认)或开发构建。
  6. 平台——iOS / Android / Web(始终提供所有三个选项)。
  7. claude -p 的权限标志——跳过权限(默认)或接受编辑。
  8. 查看器交付——仅本地(默认)或发布可共享的 Artifact。
  9. 如果选择了触发准确性——确认已发布的 expo 插件已禁用(或未安装)。

每个选项的详细信息如下。第 4-6 项(SDK、运行器、平台)可以自然地放在一个 AskUserQuestion 调用中。

如果请求中未明确要评估的技能,列出 plugins/expo/skills/ 中的可用技能,并询问要评估哪个。

被测试技能的加载方式——每个阶段两种机制(不要全局选择一种):执行器运行通过文件路径(SKILL_PATH = plugins/expo/skills/<skill>/SKILL.md,显式读取)引用该技能,而触发评估则将其作为插件加载(--plugin-dir plugins/expo,因此模型可以根据其描述自动选择)。两者都指向本地、仓库内的版本——这就是你正在评估的内容。你不需要任何特殊标志来启动测试框架会话本身(测试框架通过仓库路径找到技能);这些机制适用于它生成的 claude -p 子进程。请参阅步骤 1 和 3 以了解为什么每个阶段不同。一个必需的预运行检查(当触发评估在范围内时): 如果已发布的 expo 插件已安装/启用,请在启动测试框架之前禁用(通过 /plugin),并在之后重新启用。一次禁用是一个全局配置更改,此会话和生成的 claude -p 子进程都会继承。为什么触发评估需要它:该阶段通过 --plugin-dir 加载本地技能,并且第二个已安装的 expo 会与之冲突——模型可能会触发已发布的 expo:expo-ui,由于检测只看到工具调用名称,你会默默地给已发布的描述打分,而不是你本地编辑的描述(冲突也可能导致错误)。执行器/运行时/静态阶段不会受到影响——它们通过本地 SKILL_PATH 读取被测试的技能,且不带 --plugin-dir——因此运行时不包含触发评估可以跳过禁用。禁用 expo 不会禁用 expo-skill-eval(一个独立的项目技能,不属于 expo 插件的一部分),因此测试框架仍然可用。

将这一点以明确的预先确认形式展示给用户——就像确认要评估哪个技能一样。当触发评估在范围内时,请在开始步骤 1 之前*让用户确认已发布的 expo 插件已禁用(或未安装);如果它仍然启用,暂停并让他们通过 /plugin 禁用它。在用户确认之前不要运行触发评估——测试框架无法自行可靠地检测已安装的插件(读取全局插件配置或 claude plugin list 会提示),因此这是手动确认,而不是自动检查。

选择提示词——内置、自定义或目标截图。 提示词是驱动执行器的输入(带技能和不带技能);它们与你验证的内容是分开的。使用 AskUserQuestion 确认它们(如果请求中已指定提示词,则跳过):

  • 内置提示词——通过阅读被测试的技能(其 SKILL.md + references/)和 references/runtime-matrix.md 生成的代表性提示词,涵盖技能的标准用例。(如果技能已经在其 evals/evals.json 中附带了评估案例,也将其 prompt 字段纳入——但大多数技能没有,因此你通常自己推导。)默认全部选中,因此默认运行会锻炼技能的标准案例;让用户取消选择任何预选。
  • 自定义文本提示词——用户输入的一次性提示词。不要为此专门分配一个选项槽:AskUserQuestion 会自动添加一个 "输入内容" / 其他条目,并且在那里输入的任何内容都会成为自定义文本案例。
  • 从上传的截图构建——用户提供目标截图的路径(要重现的 UI)。执行器被告知打开它——claude -p 使用其 Read 工具读取 PNG——并构建匹配的应用程序;案例将路径记录为 reference_image,评分将生成的应用程序与目标进行比较(步骤 6)。这是 UI 技能最强的视觉测试:"构建这个。"

遵守 AskUserQuestion 的每个问题 4 个选项上限,并遵循以下优先级(需要避免的错误:上传选项在四个槽位填满时被静默丢弃):

  1. 始终为 "从上传的截图构建" 预留一个槽位。 这是视觉评估的全部意义,绝不能成为被丢弃的选项。
  2. 不要添加显式的 "自定义文本提示词" 选项——自动的 "输入内容" / 其他条目已经覆盖了它。
  3. 将剩余的 ≤3 个槽位填入内置/代表性提示词,默认选中。如果超过 3 个,将它们合并为一个默认选中的 "所有内置提示词(默认)" 选项,并在简短后续询问中提供子集选择,以便上传选项仍然适合。

将其呈现为多选。当选择了 "从上传的截图构建" 时,在后续询问中提供目标图像路径。每个选中的提示词(内置、输入或图像)成为一个评估案例(带技能和不带技能运行)。

始终确认要验证的内容,除非请求中明确说明。提供以下选项,让用户选择一个或多个(基于技能的 references/runtime-matrix.md 条目建议的默认值为粗体):

选项作用何时建议为默认值
运行时 + 截图完整管道:fixture → 执行器 → 静态检查 → 在 iOS/Android 上运行应用程序并截图。运行器(Expo Go 或开发构建)是独立问题——不要在这里提及。默认用于任何渲染应用程序屏幕的技能(references/runtime-matrix.md 中的 expo-go/dev-build 行)。需要已启动的模拟器/模拟器。
触发准确性通过 claude -p 运行逼真的提示词,检查技能是否被读取。衡量召回率(仅限应触发的查询)。始终作为独立检查有用。
代码检查(无设备)tsc --noEmit + 差异感知 lint + expo export,以及评分者根据你提供的任何自定义期望检查生成的代码。无需设备。默认用于 static-only 和 n/a 技能,以及每次你想验证代码模式(正确的导入路径、Host 包装器等)而不运行应用程序时。

将这些呈现为一个多选问题——"你想验证什么?" 这些是评分维度(如何判断构建的内容)——与提示词阶段(构建什么)不同。用户可以选择任意组合。当提示词是上传的截图(参见提示词)时,包括 "运行时 + 截图",以便测试框架捕获生成的应用程序,并且评分者可以将其与目标进行对比。

在建议之前阅读 references/runtime-matrix.md 以找到技能的默认模式。如果请求已经指定了模式(例如 "只检查它是否触发","在设备上运行"),跳过该问题并继续。

选择 Expo SDK 版本——一次,提前完成。 使用 bash /abs/path/expo-skill-eval/scripts/latest-sdk.sh 检测最新版本(它打印主版本号,例如 56;内部使用 bun 运行 npm view expo dist-tags --json 并通过 JSON.parse/semver 读取主版本,且该脚本受 bash-scripts 规则覆盖——因此不要自己内联运行注册表查询,这会提示)。然后使用 AskUserQuestion 确认:默认使用该最新 SDK,或让用户固定一个较旧的版本(例如重现特定版本的问题)。在构建 fixture 的任何地方使用所选版本——将其作为 <sdk> 参数传递给 make-fixture.sh,并将其写入每个评估案例的 runtime.sdk。如果请求已经指定了版本("在 SDK 54 上评估"),跳过检测并使用它。

默认使用最新版——它与 expo start 在设备上安装的 Expo Go 保持兼容。固定一个早于设备上安装的 Expo Go 的 SDK 会使 expo start 尝试提示 "安装推荐的 Expo Go 版本?";由于缺少 TTY(快照脚本从 /dev/null 读取 stdin),它会因 Input is required, but 'npx expo' is in non-interactive mode 而死,并且每个快照都会失败。因此,仅在你同时预先在模拟器/模拟器上安装匹配的 Expo Go 时才固定较旧的 SDK——否则坚持使用最新版。

选择运行器——Expo Go(默认)或开发构建。 使用 AskUserQuestion 询问(如果请求已说明,则跳过):

  • Expo Go(默认)——快照脚本按原样使用 expo start --ios / expo start --android 运行应用程序。速度快(无原生编译),并且可以运行 Expo Go 捆绑的任何内容(包括 SDK 56 上的 @expo/ui)。无法运行自定义原生代码(expo-modules、配置插件、Expo Go 中不存在的原生依赖项)。
  • 开发构建——快照脚本改为运行 expo run:ios / expo run:android,为每个 fixture 编译原生开发客户端。适用于需要自定义原生代码的技能输出(否则会是 static-only 的情况)。速度慢得多——expo run 会预先构建并原生编译每个 fixture(需要几分钟,尤其第一次),并且需要完整的 iOS/Android 构建工具链——因此仅在技能实际需要原生代码时才选择它。磁盘密集型: 每个 fixture 的原生构建大小为数 GB。快照阶段在每个 fixture 后运行 clean-fixture.sh,以将峰值使用量控制在约一个构建,但仍然建议在开发构建运行中使用更少的评估案例和单一平台,并保持几 GB 的可用空间。clean-fixture.sh 移除每个 fixture 的构建输出(node_modules、ios、android、.expo、dist 以及 fixture 的 iOS DerivedData),并保留应用程序源代码和 git。开发构建的磁盘控制杠杆是更少的评估案例 + 单一平台——它仅回收每个 fixture 的构建输出,从不触及共享的依赖项缓存,因此无需重新下载任何内容。

通过 EXPO_SKILL_EVAL_RUNNER 环境变量(expo-go 默认或 dev-build)将选择传递给快照脚本,并将其反映在每个评估案例的 runtime.mode(expo-go 或 dev-build)中。参见步骤 5。

选择平台——始终询问,无论技能如何。 使用 AskUserQuestion 提供 iOS / Android / Web(多选);默认为 iOS + Android,但始终将 Web 作为选项提供——不要根据技能预过滤。Web 对大多数技能来说是有效选择:@expo/ui 的通用组件(Host、Row、Column、Button、List 等)在 Web 上渲染,expo-dom、NativeWind/Tailwind、API 路由和纯 React Native 也是如此。唯一不会在 Web 上显示的是特定于平台的原生树(@expo/ui/swift-ui 或 @expo/ui/jetpack-compose),它会显示空白——而这空白本身就是一个有用的信号,因此仍然由用户决定。Web 通过 snapshot-web.sh(expo start --web + Playwright/Chromium)运行,无论运行器如何(expo run 仅限原生;没有 Web 开发构建),并且是最少被执行的路径。将所选平台写入每个评估案例的 runtime.platforms,并让 run_snapshots.py 循环处理它们。

确认 claude -p 子进程如何运行——一次,开始之前。 使用 AskUserQuestion 询问它们是否可以使用 --dangerously-skip-permissions 运行,然后将相同答案应用于本次运行的每个子进程(不要在运行期间重新提示):

  • 跳过权限(推荐)——传递 --dangerously-skip-permissions。每个子进程在 /private/tmp/expo-skill-eval-* 下的可丢弃 fixture 内无人值守运行,可以无需提示地写入文件并运行设置命令。
  • 仅接受编辑——改为传递 --permission-mode acceptEdits。Bash/安装将被自动拒绝(无 TTY),因此某些评估可能产生部分输出。

既没有 --dangerously-skip-permissions 也没有 --permission-mode acceptEdits 的裸 claude -p 根本无法写入文件。如果请求已经指定了偏好("跳过权限"、"不要使用危险标志"),跳过该问题。

确认如何交付结果查看器——一次,提前完成。 发布到 claude.ai 是对外的,因此永远不要在运行中途意外进行;在同一个预先的 AskUserQuestion 中询问(连同权限标志):

  • 仅本地(默认)——generate_viewer.py 写入 viewer.html 并在本地浏览器中打开。不会离开机器。
  • 发布可共享的 Artifact——除此之外,在最后将查看器渲染为 claude.ai Artifact(一个默认私有的网页,用户可以分享给队友)。仅当用户在此选择加入时才执行。

如果请求已经说明了是否分享/发布,跳过该问题。有关发布机制,请参阅查看器部分。

评估案例模式

你生成运行的评估案例——每个选中的提示词对应一个——并将它们写入 <workspace>/iteration-N/evals.json(查看器从中读取)。每个案例 e

…

[因翻译截断]

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

expo/add-app-clip

Add an iOS App Clip target to an Expo app. Use when the user mentions App Clip, AASA, apple-app-site-association, appclips, smart app banner, or wants to ship a lightweight iOS Clip invoked from a URL alongside their parent app.

expo/building-native-ui

Complete guide for building beautiful apps with Expo Router. Covers fundamentals, styling, components, navigation, animations, patterns, and native tabs.

expo/eas-update-insights

Check the health of published EAS Updates: crash rates, install/launch counts, unique users, payload size, and the split between embedded and OTA users per channel. Use when the user asks how an update is performing, whether a rollout is healthy, how many users are on the embedded build vs OTA, or wants to gate CI on update health.

expo/expo-api-routes

Guidelines for creating API routes in Expo Router with EAS Hosting

expo/expo-brownfield

Integrate Expo and React Native into an existing native iOS or Android app. Use when the user mentions brownfield, embedding React Native in a native app, AAR/XCFramework, or adding Expo to an existing Kotlin/Swift project. Covers both the isolated approach and the integrated approach.

expo/expo-cicd-workflows

Helps understand and write EAS workflow YAML files for Expo projects. Use this skill when the user asks about CI/CD or workflows in an Expo or EAS context, mentions .eas/workflows/, or wants help with EAS build pipelines or deployment automation.

expo/expo-deployment

Deploying Expo apps to iOS App Store, Android Play Store, web hosting, and API routes

expo/expo-dev-client

Build and distribute Expo development clients locally or via TestFlight

expo/expo-examples

Framework (OSS). Expo's official example projects - the expo/examples repo of ~70 `with-*` integrations (Stripe, Clerk, Supabase, OpenAI, maps, Reanimated, SQLite, Skia, NativeWind, and more). Use when integrating a third-party library or service into an existing Expo app and you want the canonical, version-matched pattern to adapt, or when scaffolding a new project from one with `npx create-expo --example`.

expo/expo-module

Guide for creating and writing Expo native modules and views using the Expo Modules API (Swift, Kotlin, TypeScript). Covers module definition DSL, native views, shared objects, config plugins, lifecycle hooks, autolinking, and type system. Use when building or modifying native modules for Expo.

expo/expo-observe

Use for anything related to EAS Observe — adding `expo-observe` to an Expo project (AppMetricsRoot/ObserveRoot HOC, markInteractive, the useObserve hook, and the Expo Router / React Navigation integrations for per-route metrics), querying via the EAS CLI (`eas observe:metrics-summary`, `observe:metrics`, `observe:routes`, `observe:events`, `observe:versions`), or interpreting the resulting metrics (cold/warm launch, TTR, TTI, navigation cold/warm TTR, update download, and the TTI frameRate params for triaging slow startups).

expo/expo-overview

Framework (OSS). Entry point and router for every Expo or EAS task. Load this skill first — before writing code and before choosing another expo-* / eas-* skill — when the request, PRD, or spec mentions Expo, EAS, Expo Go, or an expo-* package, or the project has an `expo` dependency in `package.json`. Within that gate it also covers app specs and designs to implement (tabs, stacks, maps, lists, navigation, building from a screenshot), and phrasings like 'implement a mobile app', 'make my app look native', 'add navigation', 'fetch some data', 'upgrade my SDK', 'add Expo to my existing native app', 'ship to the App Store', or 'I'm new to Expo, where do I start'. A fully specified request (SDK pinned, libraries named, layout given) still routes through here — the shared setup rules still apply. Do NOT load it when neither signal is present: a bare React Native project with no `expo` dependency is not Expo work. Detects the real goal, routes to the right expo-* / eas-* skill, and owns the shared setup rules.

expo/expo-router

Framework (OSS). Navigation and routing for Expo Router. Covers file-based routes, groups and dynamic routes, folder organization, Link with previews and context menus, native Stack, page titles, modals and form sheets, NativeTabs, headers and toolbars, and header search bars.

expo/expo-tailwind-setup

Set up Tailwind CSS v4 in Expo with react-native-css and NativeWind v5 for universal styling

expo/expo-ui

Framework (OSS). Build native UI with the @expo/ui package: real SwiftUI on iOS and Jetpack Compose on Android. Default to @expo/ui for sheets (BottomSheet), pickers, sliders, toggles, menus, and grouped-form sections — do NOT reach for Reanimated, @gorhom/bottom-sheet, or RN built-in Picker/Switch; use @expo/ui instead. Fall back to RN built-ins only when @expo/ui is missing the component. NOTE: @expo/ui List renders native grouped rows like an iOS Settings screen — it is NOT a virtualized list; use FlatList/FlashList for large datasets. Covers universal components (Host, Column, Row, Button, Text, List, BottomSheet, FieldGroup, Switch, Slider, Picker, Menu), drop-in replacements for RN community libraries, and platform-specific SwiftUI/Jetpack Compose trees. Not for Expo Router navigation, Reanimated, or data fetching.

expo/expo-ui-jetpack-compose

`@expo/ui/jetpack-compose` package lets you use Jetpack Compose Views and modifiers in your app.

expo/expo-ui-swiftui

`@expo/ui/swift-ui` package lets you use SwiftUI Views and modifiers in your app.

expo/expo-upgrade

Framework (OSS). Guidelines for upgrading Expo SDK versions and fixing dependency issues

expo/native-data-fetching

Use when implementing or debugging ANY network request, API call, or data fetching. Covers fetch API, React Query, SWR, error handling, caching, offline support, and Expo Router data loaders (`useLoaderData`).

expo/skills

Build and submit iOS and Android apps with EAS to TestFlight, the App Store, or Google Play. Supports Expo and other React Native projects, plus existing native apps. Use for eas.json setup, release pipelines, signing, app versions and build numbers, store submissions, and listing metadata. For Expo websites and API routes, use eas-hosting; for adding React Native screens to a native app, use expo-brownfield.

相关技能