[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CCDN96HGX5V0M4N5RV8484":3,"skill-same:01M6CCDN96HGX5V0M4N5RV8484":57},{"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":18,"publishedAt":31,"linkOnly":32,"markdownContent":33,"markdownBody":34,"frontMatter":35,"refName":36,"commitSha":37,"skillDirectory":38,"forksCount":14,"repositoryHtmlUrl":39,"repositoryHomepageUrl":40,"ownerHtmlUrl":41,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":42,"install":43,"resources":56},"01M6CCDN96HGX5V0M4N5RV8484","function-creator",null,"Create Convex queries, mutations, and actions with proper validation, authentication, and error handling. Use when implementing new API endpoints.","baisharg\u002FASTN","baisharg","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F204916775?v=4","01M6CC8XHZYVK2DR22FZ1BESCG","BAISH","01M6CC8XP400QZ9DXAWTC8EG3X",2,"AGPL-3.0","https:\u002F\u002Fgithub.com\u002Fbaisharg\u002FASTN\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffunction-creator\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30],"function creator","convex","create","error handling","authentication","validation","actions","api","use","queries","mutations","endpoints","2026-11-10 10:12:30",false,"---\nname: function-creator\ndescription: Create Convex queries, mutations, and actions with proper validation, authentication, and error handling. Use when implementing new API endpoints.\n---\n\n# Convex Function Creator\n\nGenerate secure, type-safe Convex functions following all best practices.\n\n## When to Use\n\n- Creating new query functions (read data)\n- Creating new mutation functions (write data)\n- Creating new action functions (external APIs, long-running)\n- Adding API endpoints to your Convex backend\n\n## Function Types\n\n### Queries (Read-Only)\n\n- Can only read from database\n- Cannot modify data or call external APIs\n- Cached and reactive\n- Run in transactions\n\n```typescript\nimport { query } from '.\u002F_generated\u002Fserver'\nimport { v } from 'convex\u002Fvalues'\n\nexport const getTask = query({\n  args: { taskId: v.id('tasks') },\n  returns: v.union(\n    v.object({\n      _id: v.id('tasks'),\n      text: v.string(),\n      completed: v.boolean(),\n    }),\n    v.null(),\n  ),\n  handler: async (ctx, args) => {\n    return await ctx.db.get(args.taskId)\n  },\n})\n```\n\n### Mutations (Transactional Writes)\n\n- Can read and write to database\n- Cannot call external APIs\n- Run in ACID transactions\n- Automatic retries on conflicts\n\n```typescript\nimport { mutation } from '.\u002F_generated\u002Fserver'\nimport { v } from 'convex\u002Fvalues'\n\nexport const createTask = mutation({\n  args: {\n    text: v.string(),\n    priority: v.optional(\n      v.union(v.literal('low'), v.literal('medium'), v.literal('high')),\n    ),\n  },\n  returns: v.id('tasks'),\n  handler: async (ctx, args) => {\n    const identity = await ctx.auth.getUserIdentity()\n    if (!identity) throw new Error('Not authenticated')\n\n    return await ctx.db.insert('tasks', {\n      text: args.text,\n      priority: args.priority ?? 'medium',\n      completed: false,\n      createdAt: Date.now(),\n    })\n  },\n})\n```\n\n### Actions (External + Non-Transactional)\n\n- Can call external APIs (fetch, AI, etc.)\n- Can call mutations via `ctx.runMutation`\n- Cannot directly access database\n- No automatic retries\n- **Use `\"use node\"` directive when needing Node.js APIs**\n\n**Important:** If your action needs Node.js-specific APIs (crypto, third-party SDKs, etc.), add `\"use node\"` at the top of the file. Files with `\"use node\"` can ONLY contain actions, not queries or mutations.\n\n```typescript\n'use node' \u002F\u002F Required for Node.js APIs like OpenAI SDK\n\nimport { action } from '.\u002F_generated\u002Fserver'\nimport { api } from '.\u002F_generated\u002Fapi'\nimport { v } from 'convex\u002Fvalues'\nimport OpenAI from 'openai'\n\nconst openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })\n\nexport const generateTaskSuggestion = action({\n  args: { prompt: v.string() },\n  returns: v.string(),\n  handler: async (ctx, args) => {\n    const identity = await ctx.auth.getUserIdentity()\n    if (!identity) throw new Error('Not authenticated')\n\n    \u002F\u002F Call OpenAI (requires \"use node\")\n    const completion = await openai.chat.completions.create({\n      model: 'gpt-4',\n      messages: [{ role: 'user', content: args.prompt }],\n    })\n\n    const suggestion = completion.choices[0].message.content\n\n    \u002F\u002F Write to database via mutation\n    await ctx.runMutation(api.tasks.createTask, {\n      text: suggestion,\n    })\n\n    return suggestion\n  },\n})\n```\n\n**Note:** If you only need basic fetch (no Node.js APIs), you can omit `\"use node\"`. But for third-party SDKs, crypto, or other Node.js features, you must use it.\n\n## Required Components\n\n### 1. Argument Validation\n\n**Always** define `args` with validators:\n\n```typescript\nargs: {\n  id: v.id(\"tasks\"),\n  text: v.string(),\n  count: v.number(),\n  enabled: v.boolean(),\n  tags: v.array(v.string()),\n  metadata: v.optional(v.object({\n    key: v.string(),\n  })),\n}\n```\n\n### 2. Return Type Validation\n\n**Always** define `returns`:\n\n```typescript\nreturns: v.object({\n  _id: v.id('tasks'),\n  text: v.string(),\n})\n\n\u002F\u002F Or for arrays\nreturns: v.array(\n  v.object({\n    \u002F* ... *\u002F\n  }),\n)\n\n\u002F\u002F Or for nullable\nreturns: v.union(\n  v.object({\n    \u002F* ... *\u002F\n  }),\n  v.null(),\n)\n```\n\n### 3. Authentication Check\n\n**Always** verify auth in public functions:\n\n```typescript\nconst identity = await ctx.auth.getUserIdentity()\nif (!identity) {\n  throw new Error('Not authenticated')\n}\n```\n\n### 4. Authorization Check\n\n**Always** verify ownership\u002Fpermissions:\n\n```typescript\nconst task = await ctx.db.get(args.taskId)\nif (!task) {\n  throw new Error('Task not found')\n}\n\nif (task.userId !== user._id) {\n  throw new Error('Unauthorized')\n}\n```\n\n## Complete Examples\n\n### Secure Query with Auth\n\n```typescript\nexport const getMyTasks = query({\n  args: {\n    status: v.optional(v.union(v.literal('active'), v.literal('completed'))),\n  },\n  returns: v.array(\n    v.object({\n      _id: v.id('tasks'),\n      text: v.string(),\n      completed: v.boolean(),\n    }),\n  ),\n  handler: async (ctx, args) => {\n    const identity = await ctx.auth.getUserIdentity()\n    if (!identity) throw new Error('Not authenticated')\n\n    const user = await ctx.db\n      .query('users')\n      .withIndex('by_token', (q) =>\n        q.eq('tokenIdentifier', identity.tokenIdentifier),\n      )\n      .unique()\n\n    if (!user) throw new Error('User not found')\n\n    let query = ctx.db\n      .query('tasks')\n      .withIndex('by_user', (q) => q.eq('userId', user._id))\n\n    const tasks = await query.collect()\n\n    if (args.status) {\n      return tasks.filter((t) =>\n        args.status === 'completed' ? t.completed : !t.completed,\n      )\n    }\n\n    return tasks\n  },\n})\n```\n\n### Secure Mutation with Validation\n\n```typescript\nexport const updateTask = mutation({\n  args: {\n    taskId: v.id('tasks'),\n    text: v.optional(v.string()),\n    completed: v.optional(v.boolean()),\n  },\n  returns: v.id('tasks'),\n  handler: async (ctx, args) => {\n    \u002F\u002F 1. Authentication\n    const identity = await ctx.auth.getUserIdentity()\n    if (!identity) throw new Error('Not authenticated')\n\n    \u002F\u002F 2. Get user\n    const user = await ctx.db\n      .query('users')\n      .withIndex('by_token', (q) =>\n        q.eq('tokenIdentifier', identity.tokenIdentifier),\n      )\n      .unique()\n\n    if (!user) throw new Error('User not found')\n\n    \u002F\u002F 3. Get resource\n    const task = await ctx.db.get(args.taskId)\n    if (!task) throw new Error('Task not found')\n\n    \u002F\u002F 4. Authorization\n    if (task.userId !== user._id) {\n      throw new Error('Unauthorized')\n    }\n\n    \u002F\u002F 5. Update\n    const updates: Partial\u003Ctypeof task> = {}\n    if (args.text !== undefined) updates.text = args.text\n    if (args.completed !== undefined) updates.completed = args.completed\n\n    await ctx.db.patch(args.taskId, updates)\n    return args.taskId\n  },\n})\n```\n\n### Action Calling External API\n\n**Create separate file for actions that need Node.js:**\n\n```typescript\n\u002F\u002F convex\u002FtaskActions.ts\n'use node' \u002F\u002F Required for SendGrid SDK\n\nimport { action } from '.\u002F_generated\u002Fserver'\nimport { api } from '.\u002F_generated\u002Fapi'\nimport { v } from 'convex\u002Fvalues'\nimport sendgrid from '@sendgrid\u002Fmail'\n\nsendgrid.setApiKey(process.env.SENDGRID_API_KEY)\n\nexport const sendTaskReminder = action({\n  args: { taskId: v.id('tasks') },\n  returns: v.boolean(),\n  handler: async (ctx, args) => {\n    \u002F\u002F 1. Auth\n    const identity = await ctx.auth.getUserIdentity()\n    if (!identity) throw new Error('Not authenticated')\n\n    \u002F\u002F 2. Get data via query\n    const task = await ctx.runQuery(api.tasks.getTask, {\n      taskId: args.taskId,\n    })\n\n    if (!task) throw new Error('Task not found')\n\n    \u002F\u002F 3. Call external service (using Node.js SDK)\n    await sendgrid.send({\n      to: identity.email,\n      from: 'noreply@example.com',\n      subject: 'Task Reminder',\n      text: `Don't forget: ${task.text}`,\n    })\n\n    \u002F\u002F 4. Update via mutation\n    await ctx.runMutation(api.tasks.markReminderSent, {\n      taskId: args.taskId,\n    })\n\n    return true\n  },\n})\n```\n\n**Note:** Keep queries and mutations in `convex\u002Ftasks.ts` (without \"use node\"), and actions that need Node.js in `convex\u002FtaskActions.ts` (with \"use node\").\n\n## Internal Functions\n\nFor backend-only functions (called by scheduler, other functions):\n\n```typescript\nimport { internalMutation } from '.\u002F_generated\u002Fserver'\n\nexport const processExpiredTasks = internalMutation({\n  args: {},\n  handler: async (ctx) => {\n    \u002F\u002F No auth needed - only callable from backend\n    const now = Date.now()\n    const expired = await ctx.db\n      .query('tasks')\n      .withIndex('by_due_date', (q) => q.lt('dueDate', now))\n      .collect()\n\n    for (const task of expired) {\n      await ctx.db.patch(task._id, { status: 'expired' })\n    }\n  },\n})\n```\n\n## Checklist\n\n- [ ] `args` defined with validators\n- [ ] `returns` defined with validator\n- [ ] Authentication check (`ctx.auth.getUserIdentity()`)\n- [ ] Authorization check (ownership\u002Fpermissions)\n- [ ] All promises awaited\n- [ ] Indexed queries (no `.filter()` on queries)\n- [ ] Error handling with descriptive messages\n- [ ] Scheduled functions use `internal.*` not `api.*`\n- [ ] If using Node.js APIs: `\"use node\"` at top of file\n- [ ] If file has `\"use node\"`: Only actions (no queries\u002Fmutations)\n- [ ] Actions in separate file from queries\u002Fmutations when using \"use node\"\n","# Convex Function Creator\n\nGenerate secure, type-safe Convex functions following all best practices.\n\n## When to Use\n\n- Creating new query functions (read data)\n- Creating new mutation functions (write data)\n- Creating new action functions (external APIs, long-running)\n- Adding API endpoints to your Convex backend\n\n## Function Types\n\n### Queries (Read-Only)\n\n- Can only read from database\n- Cannot modify data or call external APIs\n- Cached and reactive\n- Run in transactions\n\n```typescript\nimport { query } from '.\u002F_generated\u002Fserver'\nimport { v } from 'convex\u002Fvalues'\n\nexport const getTask = query({\n  args: { taskId: v.id('tasks') },\n  returns: v.union(\n    v.object({\n      _id: v.id('tasks'),\n      text: v.string(),\n      completed: v.boolean(),\n    }),\n    v.null(),\n  ),\n  handler: async (ctx, args) => {\n    return await ctx.db.get(args.taskId)\n  },\n})\n```\n\n### Mutations (Transactional Writes)\n\n- Can read and write to database\n- Cannot call external APIs\n- Run in ACID transactions\n- Automatic retries on conflicts\n\n```typescript\nimport { mutation } from '.\u002F_generated\u002Fserver'\nimport { v } from 'convex\u002Fvalues'\n\nexport const createTask = mutation({\n  args: {\n    text: v.string(),\n    priority: v.optional(\n      v.union(v.literal('low'), v.literal('medium'), v.literal('high')),\n    ),\n  },\n  returns: v.id('tasks'),\n  handler: async (ctx, args) => {\n    const identity = await ctx.auth.getUserIdentity()\n    if (!identity) throw new Error('Not authenticated')\n\n    return await ctx.db.insert('tasks', {\n      text: args.text,\n      priority: args.priority ?? 'medium',\n      completed: false,\n      createdAt: Date.now(),\n    })\n  },\n})\n```\n\n### Actions (External + Non-Transactional)\n\n- Can call external APIs (fetch, AI, etc.)\n- Can call mutations via `ctx.runMutation`\n- Cannot directly access database\n- No automatic retries\n- **Use `\"use node\"` directive when needing Node.js APIs**\n\n**Important:** If your action needs Node.js-specific APIs (crypto, third-party SDKs, etc.), add `\"use node\"` at the top of the file. Files with `\"use node\"` can ONLY contain actions, not queries or mutations.\n\n```typescript\n'use node' \u002F\u002F Required for Node.js APIs like OpenAI SDK\n\nimport { action } from '.\u002F_generated\u002Fserver'\nimport { api } from '.\u002F_generated\u002Fapi'\nimport { v } from 'convex\u002Fvalues'\nimport OpenAI from 'openai'\n\nconst openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })\n\nexport const generateTaskSuggestion = action({\n  args: { prompt: v.string() },\n  returns: v.string(),\n  handler: async (ctx, args) => {\n    const identity = await ctx.auth.getUserIdentity()\n    if (!identity) throw new Error('Not authenticated')\n\n    \u002F\u002F Call OpenAI (requires \"use node\")\n    const completion = await openai.chat.completions.create({\n      model: 'gpt-4',\n      messages: [{ role: 'user', content: args.prompt }],\n    })\n\n    const suggestion = completion.choices[0].message.content\n\n    \u002F\u002F Write to database via mutation\n    await ctx.runMutation(api.tasks.createTask, {\n      text: suggestion,\n    })\n\n    return suggestion\n  },\n})\n```\n\n**Note:** If you only need basic fetch (no Node.js APIs), you can omit `\"use node\"`. But for third-party SDKs, crypto, or other Node.js features, you must use it.\n\n## Required Components\n\n### 1. Argument Validation\n\n**Always** define `args` with validators:\n\n```typescript\nargs: {\n  id: v.id(\"tasks\"),\n  text: v.string(),\n  count: v.number(),\n  enabled: v.boolean(),\n  tags: v.array(v.string()),\n  metadata: v.optional(v.object({\n    key: v.string(),\n  })),\n}\n```\n\n### 2. Return Type Validation\n\n**Always** define `returns`:\n\n```typescript\nreturns: v.object({\n  _id: v.id('tasks'),\n  text: v.string(),\n})\n\n\u002F\u002F Or for arrays\nreturns: v.array(\n  v.object({\n    \u002F* ... *\u002F\n  }),\n)\n\n\u002F\u002F Or for nullable\nreturns: v.union(\n  v.object({\n    \u002F* ... *\u002F\n  }),\n  v.null(),\n)\n```\n\n### 3. Authentication Check\n\n**Always** verify auth in public functions:\n\n```typescript\nconst identity = await ctx.auth.getUserIdentity()\nif (!identity) {\n  throw new Error('Not authenticated')\n}\n```\n\n### 4. Authorization Check\n\n**Always** verify ownership\u002Fpermissions:\n\n```typescript\nconst task = await ctx.db.get(args.taskId)\nif (!task) {\n  throw new Error('Task not found')\n}\n\nif (task.userId !== user._id) {\n  throw new Error('Unauthorized')\n}\n```\n\n## Complete Examples\n\n### Secure Query with Auth\n\n```typescript\nexport const getMyTasks = query({\n  args: {\n    status: v.optional(v.union(v.literal('active'), v.literal('completed'))),\n  },\n  returns: v.array(\n    v.object({\n      _id: v.id('tasks'),\n      text: v.string(),\n      completed: v.boolean(),\n    }),\n  ),\n  handler: async (ctx, args) => {\n    const identity = await ctx.auth.getUserIdentity()\n    if (!identity) throw new Error('Not authenticated')\n\n    const user = await ctx.db\n      .query('users')\n      .withIndex('by_token', (q) =>\n        q.eq('tokenIdentifier', identity.tokenIdentifier),\n      )\n      .unique()\n\n    if (!user) throw new Error('User not found')\n\n    let query = ctx.db\n      .query('tasks')\n      .withIndex('by_user', (q) => q.eq('userId', user._id))\n\n    const tasks = await query.collect()\n\n    if (args.status) {\n      return tasks.filter((t) =>\n        args.status === 'completed' ? t.completed : !t.completed,\n      )\n    }\n\n    return tasks\n  },\n})\n```\n\n### Secure Mutation with Validation\n\n```typescript\nexport const updateTask = mutation({\n  args: {\n    taskId: v.id('tasks'),\n    text: v.optional(v.string()),\n    completed: v.optional(v.boolean()),\n  },\n  returns: v.id('tasks'),\n  handler: async (ctx, args) => {\n    \u002F\u002F 1. Authentication\n    const identity = await ctx.auth.getUserIdentity()\n    if (!identity) throw new Error('Not authenticated')\n\n    \u002F\u002F 2. Get user\n    const user = await ctx.db\n      .query('users')\n      .withIndex('by_token', (q) =>\n        q.eq('tokenIdentifier', identity.tokenIdentifier),\n      )\n      .unique()\n\n    if (!user) throw new Error('User not found')\n\n    \u002F\u002F 3. Get resource\n    const task = await ctx.db.get(args.taskId)\n    if (!task) throw new Error('Task not found')\n\n    \u002F\u002F 4. Authorization\n    if (task.userId !== user._id) {\n      throw new Error('Unauthorized')\n    }\n\n    \u002F\u002F 5. Update\n    const updates: Partial\u003Ctypeof task> = {}\n    if (args.text !== undefined) updates.text = args.text\n    if (args.completed !== undefined) updates.completed = args.completed\n\n    await ctx.db.patch(args.taskId, updates)\n    return args.taskId\n  },\n})\n```\n\n### Action Calling External API\n\n**Create separate file for actions that need Node.js:**\n\n```typescript\n\u002F\u002F convex\u002FtaskActions.ts\n'use node' \u002F\u002F Required for SendGrid SDK\n\nimport { action } from '.\u002F_generated\u002Fserver'\nimport { api } from '.\u002F_generated\u002Fapi'\nimport { v } from 'convex\u002Fvalues'\nimport sendgrid from '@sendgrid\u002Fmail'\n\nsendgrid.setApiKey(process.env.SENDGRID_API_KEY)\n\nexport const sendTaskReminder = action({\n  args: { taskId: v.id('tasks') },\n  returns: v.boolean(),\n  handler: async (ctx, args) => {\n    \u002F\u002F 1. Auth\n    const identity = await ctx.auth.getUserIdentity()\n    if (!identity) throw new Error('Not authenticated')\n\n    \u002F\u002F 2. Get data via query\n    const task = await ctx.runQuery(api.tasks.getTask, {\n      taskId: args.taskId,\n    })\n\n    if (!task) throw new Error('Task not found')\n\n    \u002F\u002F 3. Call external service (using Node.js SDK)\n    await sendgrid.send({\n      to: identity.email,\n      from: 'noreply@example.com',\n      subject: 'Task Reminder',\n      text: `Don't forget: ${task.text}`,\n    })\n\n    \u002F\u002F 4. Update via mutation\n    await ctx.runMutation(api.tasks.markReminderSent, {\n      taskId: args.taskId,\n    })\n\n    return true\n  },\n})\n```\n\n**Note:** Keep queries and mutations in `convex\u002Ftasks.ts` (without \"use node\"), and actions that need Node.js in `convex\u002FtaskActions.ts` (with \"use node\").\n\n## Internal Functions\n\nFor backend-only functions (called by scheduler, other functions):\n\n```typescript\nimport { internalMutation } from '.\u002F_generated\u002Fserver'\n\nexport const processExpiredTasks = internalMutation({\n  args: {},\n  handler: async (ctx) => {\n    \u002F\u002F No auth needed - only callable from backend\n    const now = Date.now()\n    const expired = await ctx.db\n      .query('tasks')\n      .withIndex('by_due_date', (q) => q.lt('dueDate', now))\n      .collect()\n\n    for (const task of expired) {\n      await ctx.db.patch(task._id, { status: 'expired' })\n    }\n  },\n})\n```\n\n## Checklist\n\n- [ ] `args` defined with validators\n- [ ] `returns` defined with validator\n- [ ] Authentication check (`ctx.auth.getUserIdentity()`)\n- [ ] Authorization check (ownership\u002Fpermissions)\n- [ ] All promises awaited\n- [ ] Indexed queries (no `.filter()` on queries)\n- [ ] Error handling with descriptive messages\n- [ ] Scheduled functions use `internal.*` not `api.*`\n- [ ] If using Node.js APIs: `\"use node\"` at top of file\n- [ ] If file has `\"use node\"`: Only actions (no queries\u002Fmutations)\n- [ ] Actions in separate file from queries\u002Fmutations when using \"use node\"\n",{"name":5,"description":7},"main","83212e6d909b6a0fe9e93fd5a3ff1723300f5b5b",".claude\u002Fskills\u002Ffunction-creator","https:\u002F\u002Fgithub.com\u002Fbaisharg\u002FASTN","https:\u002F\u002Fsafetytalent.org","https:\u002F\u002Fgithub.com\u002Fbaisharg","2026-11-13 01:54:27",{"source":8,"skillName":5,"commands":44,"prompt":54,"zipAvailable":55},[45,48,51],{"tool":46,"command":47},"npx","npx skills add baisharg\u002FASTN --skill function-creator",{"tool":49,"command":50},"bunx","bunx skills add baisharg\u002FASTN --skill function-creator",{"tool":52,"command":53},"pnpm","pnpm dlx skills add baisharg\u002FASTN --skill function-creator","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fbaisharg\u002FASTN\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Ffunction-creator\u002FSKILL.md",true,[],[58,78,92,106,120,137],{"skillNo":59,"name":60,"nameZh":6,"description":61,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":62,"categories":63,"keywords":69,"publishedAt":31},"01M6CCE5DVER8DQWJDY51HAJF7","schema-builder","Design and generate Convex database schemas with proper validation, indexes, and relationships. Use when creating schema.ts or modifying table definitions.","https:\u002F\u002Fgithub.com\u002Fbaisharg\u002FASTN\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fschema-builder\u002FSKILL.md",[64],{"categoryNo":65,"categoryName":66,"taxonomyType":67,"taxonomyTypeDesc":68},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",[70,71,72,73,24,27,74,75,76,20,77],"schema builder","schema","builder","indexes","table","database","design","generate",{"skillNo":79,"name":80,"nameZh":6,"description":81,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":31},"01M6CCE36AA57CG36R4VHKFRXV","integration-tanstack-start","PostHog integration for TanStack Start full-stack applications","https:\u002F\u002Fgithub.com\u002Fbaisharg\u002FASTN\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fposthog-integration-tanstack-start\u002FSKILL.md",[],[85,86,87,88,89,90,91],"integration","start","tanstack","integration tanstack start","posthog","applications","stack",{"skillNo":93,"name":94,"nameZh":6,"description":95,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":96,"categories":97,"keywords":98,"publishedAt":31},"01M6CCE0FK6N8XAB093X7TTQ4F","migration-helper","Plan and execute Convex schema migrations safely, including adding fields, creating tables, and data transformations. Use when schema changes affect existing data.","https:\u002F\u002Fgithub.com\u002Fbaisharg\u002FASTN\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fmigration-helper\u002FSKILL.md",[],[99,100,101,102,103,104,27,71,105,20],"migration","migration helper","schema migrations safely","data","plan","execute","migrations",{"skillNo":107,"name":108,"nameZh":6,"description":109,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":110,"categories":111,"keywords":112,"publishedAt":31},"01M6CCDY3644G8WXXP0BDNMZPR","gsd:sprint","Autonomous phase execution with Codex validation. Runs plan\u002Fexecute\u002Fverify cycles in a bash loop until done or halted.","https:\u002F\u002Fgithub.com\u002Fbaisharg\u002FASTN\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fgsd-sprint\u002FSKILL.md",[],[108,113,114,24,86,115,116,117,118,103,119,104],"resume","codex","execution","verify","Bash","loop","autonomous",{"skillNo":121,"name":122,"nameZh":6,"description":123,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":124,"categories":125,"keywords":126,"publishedAt":31},"01M6CCDVTZRTFWWGREMV6FF956","gsd:second-opinion","Get a second opinion from OpenAI Codex (GPT-5.2-codex) on code, architecture, or implementation decisions. Use when you want independent verification or an alternative perspective.","https:\u002F\u002Fgithub.com\u002Fbaisharg\u002FASTN\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fgsd-second-opinion\u002FSKILL.md",[],[127,128,129,114,130,131,132,133,134,135,27,136],"gsd:second opinion","second opinion","question","architecture","code","verification","openai","gpt","decisions","implementation",{"skillNo":138,"name":139,"nameZh":6,"description":140,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":141,"categories":142,"keywords":143,"publishedAt":31},"01M6CCDSDPYYNEDERHP01N30PT","gsd:milestone-sprint","Run entire milestone autonomously with Codex validation. Auto-detects current milestone, executes all phases, and runs audit.","https:\u002F\u002Fgithub.com\u002Fbaisharg\u002FASTN\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fgsd-milestone-sprint\u002FSKILL.md",[],[144,145,24,146,147,148,113,114],"gsd:milestone sprint","run","audit","interactive","auto"]