[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CBXFBSSDTHKTZ7WRXH7BAR":3,"skill-same:01M6CBXFBSSDTHKTZ7WRXH7BAR":76},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":28,"publishedAt":35,"linkOnly":36,"markdownContent":37,"markdownBody":38,"frontMatter":39,"refName":41,"commitSha":42,"skillDirectory":43,"forksCount":14,"repositoryHtmlUrl":44,"repositoryHomepageUrl":6,"ownerHtmlUrl":45,"ownerBlogUrl":46,"ownerDescription":6,"updatedAt":47,"install":48,"resources":61},"01M6CBXFBSSDTHKTZ7WRXH7BAR","expo-api-routes",null,"Guidelines for creating API routes in Expo Router with EAS Hosting","epiphanyapps\u002Fmapyourhealth","epiphanyapps","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F7298208?v=4","01M6CBX8TV8415WB6ZC8SGRVKZ","Epiphany Apps LLC","01M6CBX8ZBWZX3B8YENG80VSHK",0,"MIT","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fexpo-api-routes\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[29,30,31,32,33,34],"expo api routes","api","expo","guidelines","router","hosting","2026-11-10 10:12:30",false,"---\nname: expo-api-routes\ndescription: Guidelines for creating API routes in Expo Router with EAS Hosting\nversion: 1.0.0\nlicense: MIT\n---\n\n## When to Use API Routes\n\nUse API routes when you need:\n\n- **Server-side secrets** — API keys, database credentials, or tokens that must never reach the client\n- **Database operations** — Direct database queries that shouldn't be exposed\n- **Third-party API proxies** — Hide API keys when calling external services (OpenAI, Stripe, etc.)\n- **Server-side validation** — Validate data before database writes\n- **Webhook endpoints** — Receive callbacks from services like Stripe or GitHub\n- **Rate limiting** — Control access at the server level\n- **Heavy computation** — Offload processing that would be slow on mobile\n\n## When NOT to Use API Routes\n\nAvoid API routes when:\n\n- **Data is already public** — Use direct fetch to public APIs instead\n- **No secrets required** — Static data or client-safe operations\n- **Real-time updates needed** — Use WebSockets or services like Supabase Realtime\n- **Simple CRUD** — Consider Firebase, Supabase, or Convex for managed backends\n- **File uploads** — Use direct-to-storage uploads (S3 presigned URLs, Cloudflare R2)\n- **Authentication only** — Use Clerk, Auth0, or Firebase Auth instead\n\n## File Structure\n\nAPI routes live in the `app` directory with `+api.ts` suffix:\n\n```\napp\u002F\n  api\u002F\n    hello+api.ts          → GET \u002Fapi\u002Fhello\n    users+api.ts          → \u002Fapi\u002Fusers\n    users\u002F[id]+api.ts     → \u002Fapi\u002Fusers\u002F:id\n  (tabs)\u002F\n    index.tsx\n```\n\n## Basic API Route\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fhello+api.ts\nexport function GET(request: Request) {\n  return Response.json({ message: \"Hello from Expo!\" });\n}\n```\n\n## HTTP Methods\n\nExport named functions for each HTTP method:\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fitems+api.ts\nexport function GET(request: Request) {\n  return Response.json({ items: [] });\n}\n\nexport async function POST(request: Request) {\n  const body = await request.json();\n  return Response.json({ created: body }, { status: 201 });\n}\n\nexport async function PUT(request: Request) {\n  const body = await request.json();\n  return Response.json({ updated: body });\n}\n\nexport async function DELETE(request: Request) {\n  return new Response(null, { status: 204 });\n}\n```\n\n## Dynamic Routes\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fusers\u002F[id]+api.ts\nexport function GET(request: Request, { id }: { id: string }) {\n  return Response.json({ userId: id });\n}\n```\n\n## Request Handling\n\n### Query Parameters\n\n```ts\nexport function GET(request: Request) {\n  const url = new URL(request.url);\n  const page = url.searchParams.get(\"page\") ?? \"1\";\n  const limit = url.searchParams.get(\"limit\") ?? \"10\";\n\n  return Response.json({ page, limit });\n}\n```\n\n### Headers\n\n```ts\nexport function GET(request: Request) {\n  const auth = request.headers.get(\"Authorization\");\n\n  if (!auth) {\n    return Response.json({ error: \"Unauthorized\" }, { status: 401 });\n  }\n\n  return Response.json({ authenticated: true });\n}\n```\n\n### JSON Body\n\n```ts\nexport async function POST(request: Request) {\n  const { email, password } = await request.json();\n\n  if (!email || !password) {\n    return Response.json({ error: \"Missing fields\" }, { status: 400 });\n  }\n\n  return Response.json({ success: true });\n}\n```\n\n## Environment Variables\n\nUse `process.env` for server-side secrets:\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fai+api.ts\nexport async function POST(request: Request) {\n  const { prompt } = await request.json();\n\n  const response = await fetch(\"https:\u002F\u002Fapi.openai.com\u002Fv1\u002Fchat\u002Fcompletions\", {\n    method: \"POST\",\n    headers: {\n      \"Content-Type\": \"application\u002Fjson\",\n      Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,\n    },\n    body: JSON.stringify({\n      model: \"gpt-4\",\n      messages: [{ role: \"user\", content: prompt }],\n    }),\n  });\n\n  const data = await response.json();\n  return Response.json(data);\n}\n```\n\nSet environment variables:\n\n- **Local**: Create `.env` file (never commit)\n- **EAS Hosting**: Use `eas env:create` or Expo dashboard\n\n## CORS Headers\n\nAdd CORS for web clients:\n\n```ts\nconst corsHeaders = {\n  \"Access-Control-Allow-Origin\": \"*\",\n  \"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, OPTIONS\",\n  \"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n};\n\nexport function OPTIONS() {\n  return new Response(null, { headers: corsHeaders });\n}\n\nexport function GET() {\n  return Response.json({ data: \"value\" }, { headers: corsHeaders });\n}\n```\n\n## Error Handling\n\n```ts\nexport async function POST(request: Request) {\n  try {\n    const body = await request.json();\n    \u002F\u002F Process...\n    return Response.json({ success: true });\n  } catch (error) {\n    console.error(\"API error:\", error);\n    return Response.json({ error: \"Internal server error\" }, { status: 500 });\n  }\n}\n```\n\n## Testing Locally\n\nStart the development server with API routes:\n\n```bash\nnpx expo serve\n```\n\nThis starts a local server at `http:\u002F\u002Flocalhost:8081` with full API route support.\n\nTest with curl:\n\n```bash\ncurl http:\u002F\u002Flocalhost:8081\u002Fapi\u002Fhello\ncurl -X POST http:\u002F\u002Flocalhost:8081\u002Fapi\u002Fusers -H \"Content-Type: application\u002Fjson\" -d '{\"name\":\"Test\"}'\n```\n\n## Deployment to EAS Hosting\n\n### Prerequisites\n\n```bash\nnpm install -g eas-cli\neas login\n```\n\n### Deploy\n\n```bash\neas deploy\n```\n\nThis builds and deploys your API routes to EAS Hosting (Cloudflare Workers).\n\n### Environment Variables for Production\n\n```bash\n# Create a secret\neas env:create --name OPENAI_API_KEY --value sk-xxx --environment production\n\n# Or use the Expo dashboard\n```\n\n### Custom Domain\n\nConfigure in `eas.json` or Expo dashboard.\n\n## EAS Hosting Runtime (Cloudflare Workers)\n\nAPI routes run on Cloudflare Workers. Key limitations:\n\n### Missing\u002FLimited APIs\n\n- **No Node.js filesystem** — `fs` module unavailable\n- **No native Node modules** — Use Web APIs or polyfills\n- **Limited execution time** — 30 second timeout for CPU-intensive tasks\n- **No persistent connections** — WebSockets require Durable Objects\n- **fetch is available** — Use standard fetch for HTTP requests\n\n### Use Web APIs Instead\n\n```ts\n\u002F\u002F Use Web Crypto instead of Node crypto\nconst hash = await crypto.subtle.digest(\n  \"SHA-256\",\n  new TextEncoder().encode(\"data\")\n);\n\n\u002F\u002F Use fetch instead of node-fetch\nconst response = await fetch(\"https:\u002F\u002Fapi.example.com\");\n\n\u002F\u002F Use Response\u002FRequest (already available)\nreturn new Response(JSON.stringify(data), {\n  headers: { \"Content-Type\": \"application\u002Fjson\" },\n});\n```\n\n### Database Options\n\nSince filesystem is unavailable, use cloud databases:\n\n- **Cloudflare D1** — SQLite at the edge\n- **Turso** — Distributed SQLite\n- **PlanetScale** — Serverless MySQL\n- **Supabase** — Postgres with REST API\n- **Neon** — Serverless Postgres\n\nExample with Turso:\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fusers+api.ts\nimport { createClient } from \"@libsql\u002Fclient\u002Fweb\";\n\nconst db = createClient({\n  url: process.env.TURSO_URL!,\n  authToken: process.env.TURSO_AUTH_TOKEN!,\n});\n\nexport async function GET() {\n  const result = await db.execute(\"SELECT * FROM users\");\n  return Response.json(result.rows);\n}\n```\n\n## Calling API Routes from Client\n\n```ts\n\u002F\u002F From React Native components\nconst response = await fetch(\"\u002Fapi\u002Fhello\");\nconst data = await response.json();\n\n\u002F\u002F With body\nconst response = await fetch(\"\u002Fapi\u002Fusers\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application\u002Fjson\" },\n  body: JSON.stringify({ name: \"John\" }),\n});\n```\n\n## Common Patterns\n\n### Authentication Middleware\n\n```ts\n\u002F\u002F utils\u002Fauth.ts\nexport async function requireAuth(request: Request) {\n  const token = request.headers.get(\"Authorization\")?.replace(\"Bearer \", \"\");\n\n  if (!token) {\n    throw new Response(JSON.stringify({ error: \"Unauthorized\" }), {\n      status: 401,\n      headers: { \"Content-Type\": \"application\u002Fjson\" },\n    });\n  }\n\n  \u002F\u002F Verify token...\n  return { userId: \"123\" };\n}\n\n\u002F\u002F app\u002Fapi\u002Fprotected+api.ts\nimport { requireAuth } from \"..\u002F..\u002Futils\u002Fauth\";\n\nexport async function GET(request: Request) {\n  const { userId } = await requireAuth(request);\n  return Response.json({ userId });\n}\n```\n\n### Proxy External API\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fweather+api.ts\nexport async function GET(request: Request) {\n  const url = new URL(request.url);\n  const city = url.searchParams.get(\"city\");\n\n  const response = await fetch(\n    `https:\u002F\u002Fapi.weather.com\u002Fv1\u002Fcurrent?city=${city}&key=${process.env.WEATHER_API_KEY}`\n  );\n\n  return Response.json(await response.json());\n}\n```\n\n## Rules\n\n- NEVER expose API keys or secrets in client code\n- ALWAYS validate and sanitize user input\n- Use proper HTTP status codes (200, 201, 400, 401, 404, 500)\n- Handle errors gracefully with try\u002Fcatch\n- Keep API routes focused — one responsibility per endpoint\n- Use TypeScript for type safety\n- Log errors server-side for debugging\n","## When to Use API Routes\n\nUse API routes when you need:\n\n- **Server-side secrets** — API keys, database credentials, or tokens that must never reach the client\n- **Database operations** — Direct database queries that shouldn't be exposed\n- **Third-party API proxies** — Hide API keys when calling external services (OpenAI, Stripe, etc.)\n- **Server-side validation** — Validate data before database writes\n- **Webhook endpoints** — Receive callbacks from services like Stripe or GitHub\n- **Rate limiting** — Control access at the server level\n- **Heavy computation** — Offload processing that would be slow on mobile\n\n## When NOT to Use API Routes\n\nAvoid API routes when:\n\n- **Data is already public** — Use direct fetch to public APIs instead\n- **No secrets required** — Static data or client-safe operations\n- **Real-time updates needed** — Use WebSockets or services like Supabase Realtime\n- **Simple CRUD** — Consider Firebase, Supabase, or Convex for managed backends\n- **File uploads** — Use direct-to-storage uploads (S3 presigned URLs, Cloudflare R2)\n- **Authentication only** — Use Clerk, Auth0, or Firebase Auth instead\n\n## File Structure\n\nAPI routes live in the `app` directory with `+api.ts` suffix:\n\n```\napp\u002F\n  api\u002F\n    hello+api.ts          → GET \u002Fapi\u002Fhello\n    users+api.ts          → \u002Fapi\u002Fusers\n    users\u002F[id]+api.ts     → \u002Fapi\u002Fusers\u002F:id\n  (tabs)\u002F\n    index.tsx\n```\n\n## Basic API Route\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fhello+api.ts\nexport function GET(request: Request) {\n  return Response.json({ message: \"Hello from Expo!\" });\n}\n```\n\n## HTTP Methods\n\nExport named functions for each HTTP method:\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fitems+api.ts\nexport function GET(request: Request) {\n  return Response.json({ items: [] });\n}\n\nexport async function POST(request: Request) {\n  const body = await request.json();\n  return Response.json({ created: body }, { status: 201 });\n}\n\nexport async function PUT(request: Request) {\n  const body = await request.json();\n  return Response.json({ updated: body });\n}\n\nexport async function DELETE(request: Request) {\n  return new Response(null, { status: 204 });\n}\n```\n\n## Dynamic Routes\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fusers\u002F[id]+api.ts\nexport function GET(request: Request, { id }: { id: string }) {\n  return Response.json({ userId: id });\n}\n```\n\n## Request Handling\n\n### Query Parameters\n\n```ts\nexport function GET(request: Request) {\n  const url = new URL(request.url);\n  const page = url.searchParams.get(\"page\") ?? \"1\";\n  const limit = url.searchParams.get(\"limit\") ?? \"10\";\n\n  return Response.json({ page, limit });\n}\n```\n\n### Headers\n\n```ts\nexport function GET(request: Request) {\n  const auth = request.headers.get(\"Authorization\");\n\n  if (!auth) {\n    return Response.json({ error: \"Unauthorized\" }, { status: 401 });\n  }\n\n  return Response.json({ authenticated: true });\n}\n```\n\n### JSON Body\n\n```ts\nexport async function POST(request: Request) {\n  const { email, password } = await request.json();\n\n  if (!email || !password) {\n    return Response.json({ error: \"Missing fields\" }, { status: 400 });\n  }\n\n  return Response.json({ success: true });\n}\n```\n\n## Environment Variables\n\nUse `process.env` for server-side secrets:\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fai+api.ts\nexport async function POST(request: Request) {\n  const { prompt } = await request.json();\n\n  const response = await fetch(\"https:\u002F\u002Fapi.openai.com\u002Fv1\u002Fchat\u002Fcompletions\", {\n    method: \"POST\",\n    headers: {\n      \"Content-Type\": \"application\u002Fjson\",\n      Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,\n    },\n    body: JSON.stringify({\n      model: \"gpt-4\",\n      messages: [{ role: \"user\", content: prompt }],\n    }),\n  });\n\n  const data = await response.json();\n  return Response.json(data);\n}\n```\n\nSet environment variables:\n\n- **Local**: Create `.env` file (never commit)\n- **EAS Hosting**: Use `eas env:create` or Expo dashboard\n\n## CORS Headers\n\nAdd CORS for web clients:\n\n```ts\nconst corsHeaders = {\n  \"Access-Control-Allow-Origin\": \"*\",\n  \"Access-Control-Allow-Methods\": \"GET, POST, PUT, DELETE, OPTIONS\",\n  \"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n};\n\nexport function OPTIONS() {\n  return new Response(null, { headers: corsHeaders });\n}\n\nexport function GET() {\n  return Response.json({ data: \"value\" }, { headers: corsHeaders });\n}\n```\n\n## Error Handling\n\n```ts\nexport async function POST(request: Request) {\n  try {\n    const body = await request.json();\n    \u002F\u002F Process...\n    return Response.json({ success: true });\n  } catch (error) {\n    console.error(\"API error:\", error);\n    return Response.json({ error: \"Internal server error\" }, { status: 500 });\n  }\n}\n```\n\n## Testing Locally\n\nStart the development server with API routes:\n\n```bash\nnpx expo serve\n```\n\nThis starts a local server at `http:\u002F\u002Flocalhost:8081` with full API route support.\n\nTest with curl:\n\n```bash\ncurl http:\u002F\u002Flocalhost:8081\u002Fapi\u002Fhello\ncurl -X POST http:\u002F\u002Flocalhost:8081\u002Fapi\u002Fusers -H \"Content-Type: application\u002Fjson\" -d '{\"name\":\"Test\"}'\n```\n\n## Deployment to EAS Hosting\n\n### Prerequisites\n\n```bash\nnpm install -g eas-cli\neas login\n```\n\n### Deploy\n\n```bash\neas deploy\n```\n\nThis builds and deploys your API routes to EAS Hosting (Cloudflare Workers).\n\n### Environment Variables for Production\n\n```bash\n# Create a secret\neas env:create --name OPENAI_API_KEY --value sk-xxx --environment production\n\n# Or use the Expo dashboard\n```\n\n### Custom Domain\n\nConfigure in `eas.json` or Expo dashboard.\n\n## EAS Hosting Runtime (Cloudflare Workers)\n\nAPI routes run on Cloudflare Workers. Key limitations:\n\n### Missing\u002FLimited APIs\n\n- **No Node.js filesystem** — `fs` module unavailable\n- **No native Node modules** — Use Web APIs or polyfills\n- **Limited execution time** — 30 second timeout for CPU-intensive tasks\n- **No persistent connections** — WebSockets require Durable Objects\n- **fetch is available** — Use standard fetch for HTTP requests\n\n### Use Web APIs Instead\n\n```ts\n\u002F\u002F Use Web Crypto instead of Node crypto\nconst hash = await crypto.subtle.digest(\n  \"SHA-256\",\n  new TextEncoder().encode(\"data\")\n);\n\n\u002F\u002F Use fetch instead of node-fetch\nconst response = await fetch(\"https:\u002F\u002Fapi.example.com\");\n\n\u002F\u002F Use Response\u002FRequest (already available)\nreturn new Response(JSON.stringify(data), {\n  headers: { \"Content-Type\": \"application\u002Fjson\" },\n});\n```\n\n### Database Options\n\nSince filesystem is unavailable, use cloud databases:\n\n- **Cloudflare D1** — SQLite at the edge\n- **Turso** — Distributed SQLite\n- **PlanetScale** — Serverless MySQL\n- **Supabase** — Postgres with REST API\n- **Neon** — Serverless Postgres\n\nExample with Turso:\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fusers+api.ts\nimport { createClient } from \"@libsql\u002Fclient\u002Fweb\";\n\nconst db = createClient({\n  url: process.env.TURSO_URL!,\n  authToken: process.env.TURSO_AUTH_TOKEN!,\n});\n\nexport async function GET() {\n  const result = await db.execute(\"SELECT * FROM users\");\n  return Response.json(result.rows);\n}\n```\n\n## Calling API Routes from Client\n\n```ts\n\u002F\u002F From React Native components\nconst response = await fetch(\"\u002Fapi\u002Fhello\");\nconst data = await response.json();\n\n\u002F\u002F With body\nconst response = await fetch(\"\u002Fapi\u002Fusers\", {\n  method: \"POST\",\n  headers: { \"Content-Type\": \"application\u002Fjson\" },\n  body: JSON.stringify({ name: \"John\" }),\n});\n```\n\n## Common Patterns\n\n### Authentication Middleware\n\n```ts\n\u002F\u002F utils\u002Fauth.ts\nexport async function requireAuth(request: Request) {\n  const token = request.headers.get(\"Authorization\")?.replace(\"Bearer \", \"\");\n\n  if (!token) {\n    throw new Response(JSON.stringify({ error: \"Unauthorized\" }), {\n      status: 401,\n      headers: { \"Content-Type\": \"application\u002Fjson\" },\n    });\n  }\n\n  \u002F\u002F Verify token...\n  return { userId: \"123\" };\n}\n\n\u002F\u002F app\u002Fapi\u002Fprotected+api.ts\nimport { requireAuth } from \"..\u002F..\u002Futils\u002Fauth\";\n\nexport async function GET(request: Request) {\n  const { userId } = await requireAuth(request);\n  return Response.json({ userId });\n}\n```\n\n### Proxy External API\n\n```ts\n\u002F\u002F app\u002Fapi\u002Fweather+api.ts\nexport async function GET(request: Request) {\n  const url = new URL(request.url);\n  const city = url.searchParams.get(\"city\");\n\n  const response = await fetch(\n    `https:\u002F\u002Fapi.weather.com\u002Fv1\u002Fcurrent?city=${city}&key=${process.env.WEATHER_API_KEY}`\n  );\n\n  return Response.json(await response.json());\n}\n```\n\n## Rules\n\n- NEVER expose API keys or secrets in client code\n- ALWAYS validate and sanitize user input\n- Use proper HTTP status codes (200, 201, 400, 401, 404, 500)\n- Handle errors gracefully with try\u002Fcatch\n- Keep API routes focused — one responsibility per endpoint\n- Use TypeScript for type safety\n- Log errors server-side for debugging\n",{"name":5,"license":15,"version":40,"description":7},"1.0.0","main","415349a94ba1a83dfbd3fc8f28f1d4ce34df49ab",".agents\u002Fskills\u002Fexpo-api-routes","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth","https:\u002F\u002Fgithub.com\u002Fepiphanyapps","www.epiphanyapps.com","2026-09-02 13:41:20",{"source":8,"skillName":5,"commands":49,"prompt":59,"zipAvailable":60},[50,53,56],{"tool":51,"command":52},"npx","npx skills add epiphanyapps\u002Fmapyourhealth --skill expo-api-routes",{"tool":54,"command":55},"bunx","bunx skills add epiphanyapps\u002Fmapyourhealth --skill expo-api-routes",{"tool":57,"command":58},"pnpm","pnpm dlx skills add epiphanyapps\u002Fmapyourhealth --skill expo-api-routes","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002F.agents\u002Fskills\u002Fexpo-api-routes\u002FSKILL.md",true,[62,68,72],{"path":63,"resourceType":64,"resourceTypeDesc":65,"sizeBytes":66,"sourceHtmlUrl":67},"AGENT-BRIEF.md","REFERENCE","参考文档",7942,"https:\u002F\u002Fgithub.com\u002Ffernando-delosrios-sp\u002Fsailpoint-utils\u002Fblob\u002Fmain\u002FEntro\u002Fentro-connect\u002F.agents\u002Fskills\u002Ftriage\u002FAGENT-BRIEF.md",{"path":69,"resourceType":64,"resourceTypeDesc":65,"sizeBytes":70,"sourceHtmlUrl":71},"agents\u002Fopenai.yaml",235,"https:\u002F\u002Fgithub.com\u002Ffernando-delosrios-sp\u002Fsailpoint-utils\u002Fblob\u002Fmain\u002FEntro\u002Fentro-connect\u002F.agents\u002Fskills\u002Ftriage\u002Fagents\u002Fopenai.yaml",{"path":73,"resourceType":64,"resourceTypeDesc":65,"sizeBytes":74,"sourceHtmlUrl":75},"OUT-OF-SCOPE.md",4667,"https:\u002F\u002Fgithub.com\u002Ffernando-delosrios-sp\u002Fsailpoint-utils\u002Fblob\u002Fmain\u002FEntro\u002Fentro-connect\u002F.agents\u002Fskills\u002Ftriage\u002FOUT-OF-SCOPE.md",[77,93,105,127,138,159],{"skillNo":78,"name":79,"nameZh":6,"description":80,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":81,"categories":82,"keywords":83,"publishedAt":35},"01M6CC1HHT3GY5AT1EKNVEPNB6","validate-skills","Validates skills in this repo against agentskills.io spec and Claude Code best practices. Use via \u002Fvalidate-skills command.","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fvalidate-skills\u002FSKILL.md",[],[84,85,86,87,88,89,90,91,92],"validate skills","validate","spec","code","best practices","validation","repo","command","use",{"skillNo":94,"name":95,"nameZh":6,"description":96,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":97,"categories":98,"keywords":99,"publishedAt":35},"01M6CC1F7HJAT7VM6GSWPMJGPF","use-dom","Use Expo DOM components to run web code in a webview on native and as-is on web. Migrate web code to native incrementally.","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fuse-dom\u002FSKILL.md",[],[100,92,101,102,103,87,104,31],"use dom","web","components","run","migrate",{"skillNo":106,"name":107,"nameZh":6,"description":108,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":109,"categories":110,"keywords":114,"publishedAt":35},"01M6CC1CDBNAEG4XPPAEDHK0K4","upgrading-react-native","React Native upgrade workflow covering updated templates, dependencies, and common pitfalls. Use when migrating a React Native app to a newer release.","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fupgrading-react-native\u002FSKILL.md",[111],{"categoryNo":112,"categoryName":113,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[115,116,117,118,119,120,121,122,123,124,92,125,126],"upgrading react native","react native","react","changelog","npm","release","ios","templates","common","workflow","react-native","android",{"skillNo":128,"name":129,"nameZh":6,"description":130,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":131,"categories":132,"keywords":133,"publishedAt":35},"01M6CC19S41G82VN6WRTTMZ233","upgrading-expo","Guidelines for upgrading Expo SDK versions and fixing dependency issues","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fupgrading-expo\u002FSKILL.md",[],[134,31,135,136,32,137],"upgrading expo","issues","sdk","dependency",{"skillNo":139,"name":140,"nameZh":6,"description":141,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":142,"categories":143,"keywords":145,"publishedAt":35},"01M6CC0NPK5PVP2BG3QDW4KNV3","react-native-best-practices","Provides React Native performance optimization guidelines for FPS, TTI, bundle size, memory leaks, re-renders, and animations. Applies to tasks involving Hermes optimization, JS thread blocking, bridge overhead, FlashList, native modules, or debugging jank and frame drops.","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Freact-native-best-practices\u002FSKILL.md",[144],{"categoryNo":112,"categoryName":113,"taxonomyType":21,"taxonomyTypeDesc":22},[116,88,117,146,147,148,149,32,150,151,152,153,154,155,156,157,158,125,31],"react native best practices","Optimization","memory","performance","debugging","tasks","js","performance optimization","bundle size","profiling","hermes","bridge","modules",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":163,"categories":164,"keywords":169,"publishedAt":35},"01M6CC090RAFTKGJ7K9SF71HMA","native-data-fetching","Use when implementing or debugging ANY network request, API call, or data fetching. Covers fetch API, axios, React Query, SWR, error handling, caching strategies, offline support.","https:\u002F\u002Fgithub.com\u002Fepiphanyapps\u002Fmapyourhealth\u002Fblob\u002Fmain\u002Fapps\u002Fmobile\u002F.agents\u002Fskills\u002Fnative-data-fetching\u002FSKILL.md",[165,166],{"categoryNo":112,"categoryName":113,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":167,"categoryName":168,"taxonomyType":26,"taxonomyTypeDesc":27},"01JBSEEDCAT000000000000033","数据分析师",[170,171,117,150,172,173,174,175,30,176,92,177],"data","native data fetching","error handling","offline","swr","network","fetch","support"]