[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71K6SWAFGRBE49DX5P9RMYR":3,"skill-same:01M71K6SWAFGRBE49DX5P9RMYR":68},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":27,"publishedAt":42,"linkOnly":43,"markdownContent":44,"markdownBody":45,"frontMatter":46,"refName":47,"commitSha":48,"skillDirectory":49,"forksCount":50,"repositoryHtmlUrl":51,"repositoryHomepageUrl":6,"ownerHtmlUrl":52,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":53,"install":54,"resources":67},"01M71K6SWAFGRBE49DX5P9RMYR","pinme-email",null,"Use this skill when a PinMe project (Worker TypeScript) needs to integrate email sending (send_email). Guides AI to generate correct Worker TS code.","developAgent\u002Fbmad-start","developAgent","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F264530239?v=4","01M71J8X6CY24V5ZZHFGETRMSW","01M71J8X739FS28DGQAAY7V4QR",1,"MIT","https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.bob\u002Fskills\u002Fpinme-email\u002FSKILL.md",[17,22],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000005","邮件与沟通","SCENARIO","使用场景",{"categoryNo":23,"categoryName":24,"taxonomyType":25,"taxonomyTypeDesc":26},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[28,29,30,31,32,33,34,35,36,37,38,39,40,41],"email","pinme","pinme email","project","correct","send","worker","use","when","code","guides","generate","typescript","integrate","2026-11-10 10:12:30",false,"---\nname: pinme-email\ndescription: Use this skill when a PinMe project (Worker TypeScript) needs to integrate email sending (send_email). Guides AI to generate correct Worker TS code.\n---\n\n# PinMe Worker Email API Integration\n\nGuides how to call PinMe platform's email sending API in a PinMe Worker (TypeScript).\n\n## Environment Variables\n\nThe following environment variables are automatically injected when the Worker is created — no manual configuration needed:\n\n```typescript\n\u002F\u002F backend\u002Fsrc\u002Fworker.ts\nexport interface Env {\n  DB: D1Database;\n  API_KEY: string;      \u002F\u002F Project API Key — used for send_email authentication\n  BASE_URL?: string;    \u002F\u002F Optional override for PinMe API base URL, defaults to https:\u002F\u002Fpinme.cloud\n}\n```\n\n> `API_KEY` is the sole credential for the Worker to call PinMe platform APIs. When `BASE_URL` is not set, it defaults to `https:\u002F\u002Fpinme.cloud`.\n\n---\n\n## Send Email API\n\n**Endpoint:** `POST {BASE_URL}\u002Fapi\u002Fv4\u002Fsend_email`\n**Authentication:** `X-API-Key` header (using `env.API_KEY`)\n**Sender:** Automatically set to `{project_name}@pinme.cloud`\n\n### Request Format\n\n```json\n{\n  \"to\": \"user@example.com\",\n  \"subject\": \"Your verification code\",\n  \"html\": \"\u003Cp>Your code is \u003Cstrong>123456\u003C\u002Fstrong>\u003C\u002Fp>\"\n}\n```\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `to` | string | Yes | Recipient email address |\n| `subject` | string | Yes | Email subject |\n| `html` | string | Yes | HTML body |\n\n### Response Format\n\n**Success (200):**\n```json\n{ \"code\": 200, \"msg\": \"ok\", \"data\": { \"ok\": true } }\n```\n\n**Errors:**\n\n| HTTP Status | Meaning | data.error Example |\n|-------------|---------|-------------------|\n| 401 | API Key missing or invalid | `\"X-API-Key header is required\"` \u002F `\"Invalid API key\"` |\n| 400 | Parameter validation failed | `\"Invalid email address\"` \u002F `\"Subject is required\"` |\n| 500 | Email service error | `\"Failed to send email\"` |\n\n### Worker Example Code\n\n```typescript\nasync function sendEmail(env: Env, to: string, subject: string, html: string): Promise\u003C{ ok: boolean; error?: string }> {\n  const baseUrl = env.BASE_URL ?? 'https:\u002F\u002Fpinme.cloud';\n  const resp = await fetch(`${baseUrl}\u002Fapi\u002Fv4\u002Fsend_email`, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application\u002Fjson',\n      'X-API-Key': env.API_KEY,\n    },\n    body: JSON.stringify({ to, subject, html }),\n  });\n\n  const result = await resp.json() as { code: number; msg: string; data?: { ok?: boolean; error?: string } };\n\n  if (resp.status !== 200 || result.code !== 200) {\n    return { ok: false, error: result.data?.error || result.msg || 'Unknown error' };\n  }\n  return { ok: true };\n}\n\n\u002F\u002F Usage in routes\nasync function handleSendVerification(request: Request, env: Env): Promise\u003CResponse> {\n  const { email } = await request.json() as { email: string };\n  const code = Math.random().toString().slice(2, 8);\n\n  const result = await sendEmail(env, email, 'Verification Code',\n    `\u003Cp>Your code is \u003Cstrong>${code}\u003C\u002Fstrong>\u003C\u002Fp>`);\n\n  if (!result.ok) {\n    return json({ error: result.error }, 500);\n  }\n  return json({ ok: true });\n}\n```\n\n---\n\n## Error Handling Pattern\n\nPinMe platform API unified response format:\n\n```typescript\ninterface PinmeResponse\u003CT = unknown> {\n  code: number;   \u002F\u002F 200=success, other=failure\n  msg: string;    \u002F\u002F \"ok\" | \"error\" | \"invalid params\"\n  data?: T;       \u002F\u002F Business data on success, may contain { error: string } on failure\n}\n```\n\n### Recommended Unified Error Handler\n\n```typescript\nasync function callPinmeAPI\u003CT>(url: string, apiKey: string, body: unknown): Promise\u003C{ data?: T; error?: string }> {\n  let resp: Response;\n  try {\n    resp = await fetch(url, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application\u002Fjson', 'X-API-Key': apiKey },\n      body: JSON.stringify(body),\n    });\n  } catch {\n    return { error: 'Network error' };\n  }\n\n  if (!resp.ok) {\n    try {\n      const err = await resp.json() as PinmeResponse;\n      return { error: err.data && typeof err.data === 'object' && 'error' in err.data\n        ? (err.data as { error: string }).error\n        : err.msg || `HTTP ${resp.status}` };\n    } catch {\n      return { error: `HTTP ${resp.status}` };\n    }\n  }\n\n  const result = await resp.json() as PinmeResponse\u003CT>;\n  if (result.code !== 200) {\n    return { error: result.data && typeof result.data === 'object' && 'error' in result.data\n      ? (result.data as { error: string }).error\n      : result.msg };\n  }\n  return { data: result.data as T };\n}\n```\n\n### Usage Example\n\n```typescript\nconst baseUrl = env.BASE_URL ?? 'https:\u002F\u002Fpinme.cloud';\n\n\u002F\u002F Send email\nconst emailResult = await callPinmeAPI\u003C{ ok: boolean }>(\n  `${baseUrl}\u002Fapi\u002Fv4\u002Fsend_email`, env.API_KEY,\n  { to: 'user@example.com', subject: 'Hello', html: '\u003Cp>Hi\u003C\u002Fp>' },\n);\nif (emailResult.error) return json({ error: emailResult.error }, 500);\n```\n","# PinMe Worker Email API Integration\n\nGuides how to call PinMe platform's email sending API in a PinMe Worker (TypeScript).\n\n## Environment Variables\n\nThe following environment variables are automatically injected when the Worker is created — no manual configuration needed:\n\n```typescript\n\u002F\u002F backend\u002Fsrc\u002Fworker.ts\nexport interface Env {\n  DB: D1Database;\n  API_KEY: string;      \u002F\u002F Project API Key — used for send_email authentication\n  BASE_URL?: string;    \u002F\u002F Optional override for PinMe API base URL, defaults to https:\u002F\u002Fpinme.cloud\n}\n```\n\n> `API_KEY` is the sole credential for the Worker to call PinMe platform APIs. When `BASE_URL` is not set, it defaults to `https:\u002F\u002Fpinme.cloud`.\n\n---\n\n## Send Email API\n\n**Endpoint:** `POST {BASE_URL}\u002Fapi\u002Fv4\u002Fsend_email`\n**Authentication:** `X-API-Key` header (using `env.API_KEY`)\n**Sender:** Automatically set to `{project_name}@pinme.cloud`\n\n### Request Format\n\n```json\n{\n  \"to\": \"user@example.com\",\n  \"subject\": \"Your verification code\",\n  \"html\": \"\u003Cp>Your code is \u003Cstrong>123456\u003C\u002Fstrong>\u003C\u002Fp>\"\n}\n```\n\n| Field | Type | Required | Description |\n|-------|------|----------|-------------|\n| `to` | string | Yes | Recipient email address |\n| `subject` | string | Yes | Email subject |\n| `html` | string | Yes | HTML body |\n\n### Response Format\n\n**Success (200):**\n```json\n{ \"code\": 200, \"msg\": \"ok\", \"data\": { \"ok\": true } }\n```\n\n**Errors:**\n\n| HTTP Status | Meaning | data.error Example |\n|-------------|---------|-------------------|\n| 401 | API Key missing or invalid | `\"X-API-Key header is required\"` \u002F `\"Invalid API key\"` |\n| 400 | Parameter validation failed | `\"Invalid email address\"` \u002F `\"Subject is required\"` |\n| 500 | Email service error | `\"Failed to send email\"` |\n\n### Worker Example Code\n\n```typescript\nasync function sendEmail(env: Env, to: string, subject: string, html: string): Promise\u003C{ ok: boolean; error?: string }> {\n  const baseUrl = env.BASE_URL ?? 'https:\u002F\u002Fpinme.cloud';\n  const resp = await fetch(`${baseUrl}\u002Fapi\u002Fv4\u002Fsend_email`, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application\u002Fjson',\n      'X-API-Key': env.API_KEY,\n    },\n    body: JSON.stringify({ to, subject, html }),\n  });\n\n  const result = await resp.json() as { code: number; msg: string; data?: { ok?: boolean; error?: string } };\n\n  if (resp.status !== 200 || result.code !== 200) {\n    return { ok: false, error: result.data?.error || result.msg || 'Unknown error' };\n  }\n  return { ok: true };\n}\n\n\u002F\u002F Usage in routes\nasync function handleSendVerification(request: Request, env: Env): Promise\u003CResponse> {\n  const { email } = await request.json() as { email: string };\n  const code = Math.random().toString().slice(2, 8);\n\n  const result = await sendEmail(env, email, 'Verification Code',\n    `\u003Cp>Your code is \u003Cstrong>${code}\u003C\u002Fstrong>\u003C\u002Fp>`);\n\n  if (!result.ok) {\n    return json({ error: result.error }, 500);\n  }\n  return json({ ok: true });\n}\n```\n\n---\n\n## Error Handling Pattern\n\nPinMe platform API unified response format:\n\n```typescript\ninterface PinmeResponse\u003CT = unknown> {\n  code: number;   \u002F\u002F 200=success, other=failure\n  msg: string;    \u002F\u002F \"ok\" | \"error\" | \"invalid params\"\n  data?: T;       \u002F\u002F Business data on success, may contain { error: string } on failure\n}\n```\n\n### Recommended Unified Error Handler\n\n```typescript\nasync function callPinmeAPI\u003CT>(url: string, apiKey: string, body: unknown): Promise\u003C{ data?: T; error?: string }> {\n  let resp: Response;\n  try {\n    resp = await fetch(url, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application\u002Fjson', 'X-API-Key': apiKey },\n      body: JSON.stringify(body),\n    });\n  } catch {\n    return { error: 'Network error' };\n  }\n\n  if (!resp.ok) {\n    try {\n      const err = await resp.json() as PinmeResponse;\n      return { error: err.data && typeof err.data === 'object' && 'error' in err.data\n        ? (err.data as { error: string }).error\n        : err.msg || `HTTP ${resp.status}` };\n    } catch {\n      return { error: `HTTP ${resp.status}` };\n    }\n  }\n\n  const result = await resp.json() as PinmeResponse\u003CT>;\n  if (result.code !== 200) {\n    return { error: result.data && typeof result.data === 'object' && 'error' in result.data\n      ? (result.data as { error: string }).error\n      : result.msg };\n  }\n  return { data: result.data as T };\n}\n```\n\n### Usage Example\n\n```typescript\nconst baseUrl = env.BASE_URL ?? 'https:\u002F\u002Fpinme.cloud';\n\n\u002F\u002F Send email\nconst emailResult = await callPinmeAPI\u003C{ ok: boolean }>(\n  `${baseUrl}\u002Fapi\u002Fv4\u002Fsend_email`, env.API_KEY,\n  { to: 'user@example.com', subject: 'Hello', html: '\u003Cp>Hi\u003C\u002Fp>' },\n);\nif (emailResult.error) return json({ error: emailResult.error }, 500);\n```\n",{"name":5,"description":7},"main","1907bbe850fb749efa8b499b8da7ebb78a663519",".bob\u002Fskills\u002Fpinme-email",0,"https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start","https:\u002F\u002Fgithub.com\u002FdevelopAgent","2026-07-19 05:19:22",{"source":8,"skillName":5,"commands":55,"prompt":65,"zipAvailable":66},[56,59,62],{"tool":57,"command":58},"npx","npx skills add developAgent\u002Fbmad-start --skill pinme-email",{"tool":60,"command":61},"bunx","bunx skills add developAgent\u002Fbmad-start --skill pinme-email",{"tool":63,"command":64},"pnpm","pnpm dlx skills add developAgent\u002Fbmad-start --skill pinme-email","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.bob\u002Fskills\u002Fpinme-email\u002FSKILL.md",true,[],[69,88,115,133,147,173],{"skillNo":70,"name":71,"nameZh":6,"description":72,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":78,"publishedAt":87},"01M71R3M9DJTTY0ARFQ6K04NMP","gds-correct-course","Manage significant changes during sprint execution. Use when the user says \"correct course\" or \"propose sprint change\"","https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.rovodev\u002Fskills\u002Fgds-correct-course\u002FSKILL.md",[75],{"categoryNo":76,"categoryName":77,"taxonomyType":25,"taxonomyTypeDesc":26},"01JBSEEDCAT000000000000039","教师与教育",[79,80,32,81,82,83,36,35,84,85,86],"gds correct course","course","user","changes","change","execution","manage","sprint","2026-11-10 13:02:02",{"skillNo":89,"name":90,"nameZh":6,"description":91,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":98,"publishedAt":87},"01M71R3GENSFD1A1XVZTTQG1KF","gds-code-review","Review code changes adversarially using parallel review layers (Blind Hunter, Edge Case Hunter, Acceptance Auditor) with structured triage into actionable categories. Use when the user says \"run code review\" or \"review this code\"","https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.rovodev\u002Fskills\u002Fgds-code-review\u002FSKILL.md",[94,97],{"categoryNo":95,"categoryName":96,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000007","代码审查",{"categoryNo":23,"categoryName":24,"taxonomyType":25,"taxonomyTypeDesc":26},[99,37,100,101,102,82,103,104,105,106,107,108,109,36,110,35,111,112,113,114],"code review","review","gds code review","categories","triage","review code","run","parallel","case","with","run code","acceptance","edge","actionable","layers","hunter",{"skillNo":116,"name":117,"nameZh":6,"description":118,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":119,"categories":120,"keywords":121,"publishedAt":87},"01M71R3DD098MQRD6F8S4GG0AW","gds-check-implementation-readiness","Verify GDD, UX, Architecture, and Epics alignment before production. Use when the user says \"check readiness\" or \"implementation readiness\"","https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.rovodev\u002Fskills\u002Fgds-check-implementation-readiness\u002FSKILL.md",[],[122,123,124,125,126,127,81,128,129,130,131,36,35,132],"check","readiness","Implementation Readiness","gds check implementation readiness","implementation","check readiness","Production","ux","verify","architecture","alignment",{"skillNo":134,"name":135,"nameZh":6,"description":136,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":137,"categories":138,"keywords":139,"publishedAt":87},"01M71R3ACAA1G0NVQ330JQNJPK","gds-brainstorm-game","Facilitate game brainstorming sessions with game-specific techniques. Use when the user says \"brainstorm game\" or \"game ideas\"","https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.rovodev\u002Fskills\u002Fgds-brainstorm-game\u002FSKILL.md",[],[140,141,142,81,143,108,36,35,144,145,146],"gds brainstorm game","game","brainstorm","brainstorming","techniques","sessions","ideas",{"skillNo":148,"name":149,"nameZh":6,"description":150,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":151,"categories":152,"keywords":156,"publishedAt":87},"01M71R377MJ6WJTTFARGKH3HX7","gds-agent-tech-writer","Technical documentation specialist and knowledge curator for game projects. Use when the user asks to talk to Paige or requests the Technical Writer.","https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.rovodev\u002Fskills\u002Fgds-agent-tech-writer\u002FSKILL.md",[153],{"categoryNo":154,"categoryName":155,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",[157,158,159,160,35,161,162,163,164,36,81,165,166,167,168,169,170,171,141,172],"gds agent tech writer","tech","writer","technical writer","technical","knowledge","for","projects","technical documentation","talk","specialist","documentation specialist","knowledge curator","requests","documentation","curator",{"skillNo":174,"name":175,"nameZh":6,"description":176,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":177,"categories":178,"keywords":180,"publishedAt":87},"01M71R34RGT2ZX3TSFA2CRT0NC","gds-agent-game-solo-dev","Elite indie game developer for rapid prototyping and solo quick-flow development. Use when the user asks to talk to Indie or requests the Game Solo Dev.","https:\u002F\u002Fgithub.com\u002FdevelopAgent\u002Fbmad-start\u002Fblob\u002Fmain\u002F.rovodev\u002Fskills\u002Fgds-agent-game-solo-dev\u002FSKILL.md",[179],{"categoryNo":154,"categoryName":155,"taxonomyType":20,"taxonomyTypeDesc":21},[181,141,182,183,184,185,81,166,170,186,187,36,35,188,163,189,190],"solo","gds agent game solo dev","dev","flow","developer","RAPID","game developer","prototyping","development","quick"]