[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CCDFZDH7BKKBQF5QKN5RTB":3,"skill-same:01M6CCDFZDH7BKKBQF5QKN5RTB":72},{"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":32,"linkOnly":33,"markdownContent":34,"markdownBody":35,"frontMatter":36,"refName":41,"commitSha":42,"skillDirectory":43,"forksCount":14,"repositoryHtmlUrl":44,"repositoryHomepageUrl":45,"ownerHtmlUrl":46,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":47,"install":48,"resources":61},"01M6CCDFZDH7BKKBQF5QKN5RTB","convex-security-check",null,"Quick security audit checklist covering authentication, function exposure, argument validation, row-level access control, and environment variable handling","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\u002Fconvex-security-check\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31],"convex","security","check","security check","convex security check","authentication","validation","audit","authorization","security audit","access","environment","checklist","2026-11-10 10:12:30",false,"---\nname: convex-security-check\ndisplayName: Convex Security Check\ndescription: Quick security audit checklist covering authentication, function exposure, argument validation, row-level access control, and environment variable handling\nversion: 1.0.0\nauthor: Convex\ntags: [convex, security, authentication, authorization, checklist]\n---\n\n# Convex Security Check\n\nA quick security audit checklist for Convex applications covering authentication, function exposure, argument validation, row-level access control, and environment variable handling.\n\n## Documentation Sources\n\nBefore implementing, do not assume; fetch the latest documentation:\n\n- Primary: https:\u002F\u002Fdocs.convex.dev\u002Fauth\n- Production Security: https:\u002F\u002Fdocs.convex.dev\u002Fproduction\n- Functions Auth: https:\u002F\u002Fdocs.convex.dev\u002Fauth\u002Ffunctions-auth\n- For broader context: https:\u002F\u002Fdocs.convex.dev\u002Fllms.txt\n\n## Instructions\n\n### Security Checklist\n\nUse this checklist to quickly audit your Convex application's security:\n\n#### 1. Authentication\n\n- [ ] Authentication provider configured (Clerk, Auth0, etc.)\n- [ ] All sensitive queries check `ctx.auth.getUserIdentity()`\n- [ ] Unauthenticated access explicitly allowed where intended\n- [ ] Session tokens properly validated\n\n#### 2. Function Exposure\n\n- [ ] Public functions (`query`, `mutation`, `action`) reviewed\n- [ ] Internal functions use `internalQuery`, `internalMutation`, `internalAction`\n- [ ] No sensitive operations exposed as public functions\n- [ ] HTTP actions validate origin\u002Fauthentication\n\n#### 3. Argument Validation\n\n- [ ] All functions have explicit `args` validators\n- [ ] All functions have explicit `returns` validators\n- [ ] No `v.any()` used for sensitive data\n- [ ] ID validators use correct table names\n\n#### 4. Row-Level Access Control\n\n- [ ] Users can only access their own data\n- [ ] Admin functions check user roles\n- [ ] Shared resources have proper access checks\n- [ ] Deletion functions verify ownership\n\n#### 5. Environment Variables\n\n- [ ] API keys stored in environment variables\n- [ ] No secrets in code or schema\n- [ ] Different keys for dev\u002Fprod environments\n- [ ] Environment variables accessed only in actions\n\n### Authentication Check\n\n```typescript\n\u002F\u002F convex\u002Fauth.ts\nimport { query, mutation } from '.\u002F_generated\u002Fserver'\nimport { v } from 'convex\u002Fvalues'\nimport { ConvexError } from 'convex\u002Fvalues'\n\n\u002F\u002F Helper to require authentication\nasync function requireAuth(ctx: QueryCtx | MutationCtx) {\n  const identity = await ctx.auth.getUserIdentity()\n  if (!identity) {\n    throw new ConvexError('Authentication required')\n  }\n  return identity\n}\n\n\u002F\u002F Secure query pattern\nexport const getMyProfile = query({\n  args: {},\n  returns: v.union(\n    v.object({\n      _id: v.id('users'),\n      name: v.string(),\n      email: v.string(),\n    }),\n    v.null(),\n  ),\n  handler: async (ctx) => {\n    const identity = await requireAuth(ctx)\n\n    return await ctx.db\n      .query('users')\n      .withIndex('by_tokenIdentifier', (q) =>\n        q.eq('tokenIdentifier', identity.tokenIdentifier),\n      )\n      .unique()\n  },\n})\n```\n\n### Function Exposure Check\n\n```typescript\n\u002F\u002F PUBLIC - Exposed to clients (review carefully!)\nexport const listPublicPosts = query({\n  args: {},\n  returns: v.array(\n    v.object({\n      \u002F* ... *\u002F\n    }),\n  ),\n  handler: async (ctx) => {\n    \u002F\u002F Anyone can call this - intentionally public\n    return await ctx.db\n      .query('posts')\n      .withIndex('by_public', (q) => q.eq('isPublic', true))\n      .collect()\n  },\n})\n\n\u002F\u002F INTERNAL - Only callable from other Convex functions\nexport const _updateUserCredits = internalMutation({\n  args: { userId: v.id('users'), amount: v.number() },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    \u002F\u002F This cannot be called directly from clients\n    await ctx.db.patch(args.userId, {\n      credits: args.amount,\n    })\n    return null\n  },\n})\n```\n\n### Argument Validation Check\n\n```typescript\n\u002F\u002F GOOD: Strict validation\nexport const createPost = mutation({\n  args: {\n    title: v.string(),\n    content: v.string(),\n    category: v.union(v.literal('tech'), v.literal('news'), v.literal('other')),\n  },\n  returns: v.id('posts'),\n  handler: async (ctx, args) => {\n    const identity = await requireAuth(ctx)\n    return await ctx.db.insert('posts', {\n      ...args,\n      authorId: identity.tokenIdentifier,\n    })\n  },\n})\n\n\u002F\u002F BAD: Weak validation\nexport const createPostUnsafe = mutation({\n  args: {\n    data: v.any(), \u002F\u002F DANGEROUS: Allows any data\n  },\n  returns: v.id('posts'),\n  handler: async (ctx, args) => {\n    return await ctx.db.insert('posts', args.data)\n  },\n})\n```\n\n### Row-Level Access Control Check\n\n```typescript\n\u002F\u002F Verify ownership before update\nexport const updateTask = mutation({\n  args: {\n    taskId: v.id('tasks'),\n    title: v.string(),\n  },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    const identity = await requireAuth(ctx)\n\n    const task = await ctx.db.get(args.taskId)\n\n    \u002F\u002F Check ownership\n    if (!task || task.userId !== identity.tokenIdentifier) {\n      throw new ConvexError('Not authorized to update this task')\n    }\n\n    await ctx.db.patch(args.taskId, { title: args.title })\n    return null\n  },\n})\n\n\u002F\u002F Verify ownership before delete\nexport const deleteTask = mutation({\n  args: { taskId: v.id('tasks') },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    const identity = await requireAuth(ctx)\n\n    const task = await ctx.db.get(args.taskId)\n\n    if (!task || task.userId !== identity.tokenIdentifier) {\n      throw new ConvexError('Not authorized to delete this task')\n    }\n\n    await ctx.db.delete(args.taskId)\n    return null\n  },\n})\n```\n\n### Environment Variables Check\n\n```typescript\n\u002F\u002F convex\u002Factions.ts\n'use node'\n\nimport { action } from '.\u002F_generated\u002Fserver'\nimport { v } from 'convex\u002Fvalues'\n\nexport const sendEmail = action({\n  args: {\n    to: v.string(),\n    subject: v.string(),\n    body: v.string(),\n  },\n  returns: v.object({ success: v.boolean() }),\n  handler: async (ctx, args) => {\n    \u002F\u002F Access API key from environment\n    const apiKey = process.env.RESEND_API_KEY\n\n    if (!apiKey) {\n      throw new Error('RESEND_API_KEY not configured')\n    }\n\n    const response = await fetch('https:\u002F\u002Fapi.resend.com\u002Femails', {\n      method: 'POST',\n      headers: {\n        Authorization: `Bearer ${apiKey}`,\n        'Content-Type': 'application\u002Fjson',\n      },\n      body: JSON.stringify({\n        from: 'noreply@example.com',\n        to: args.to,\n        subject: args.subject,\n        html: args.body,\n      }),\n    })\n\n    return { success: response.ok }\n  },\n})\n```\n\n## Examples\n\n### Complete Security Pattern\n\n```typescript\n\u002F\u002F convex\u002Fsecure.ts\nimport { query, mutation, internalMutation } from '.\u002F_generated\u002Fserver'\nimport { v } from 'convex\u002Fvalues'\nimport { ConvexError } from 'convex\u002Fvalues'\n\n\u002F\u002F Authentication helper\nasync function getAuthenticatedUser(ctx: QueryCtx | MutationCtx) {\n  const identity = await ctx.auth.getUserIdentity()\n  if (!identity) {\n    throw new ConvexError({\n      code: 'UNAUTHENTICATED',\n      message: 'You must be logged in',\n    })\n  }\n\n  const user = await ctx.db\n    .query('users')\n    .withIndex('by_tokenIdentifier', (q) =>\n      q.eq('tokenIdentifier', identity.tokenIdentifier),\n    )\n    .unique()\n\n  if (!user) {\n    throw new ConvexError({\n      code: 'USER_NOT_FOUND',\n      message: 'User profile not found',\n    })\n  }\n\n  return user\n}\n\n\u002F\u002F Check admin role\nasync function requireAdmin(ctx: QueryCtx | MutationCtx) {\n  const user = await getAuthenticatedUser(ctx)\n\n  if (user.role !== 'admin') {\n    throw new ConvexError({\n      code: 'FORBIDDEN',\n      message: 'Admin access required',\n    })\n  }\n\n  return user\n}\n\n\u002F\u002F Public: List own tasks\nexport const listMyTasks = query({\n  args: {},\n  returns: v.array(\n    v.object({\n      _id: v.id('tasks'),\n      title: v.string(),\n      completed: v.boolean(),\n    }),\n  ),\n  handler: async (ctx) => {\n    const user = await getAuthenticatedUser(ctx)\n\n    return await ctx.db\n      .query('tasks')\n      .withIndex('by_user', (q) => q.eq('userId', user._id))\n      .collect()\n  },\n})\n\n\u002F\u002F Admin only: List all users\nexport const listAllUsers = query({\n  args: {},\n  returns: v.array(\n    v.object({\n      _id: v.id('users'),\n      name: v.string(),\n      role: v.string(),\n    }),\n  ),\n  handler: async (ctx) => {\n    await requireAdmin(ctx)\n\n    return await ctx.db.query('users').collect()\n  },\n})\n\n\u002F\u002F Internal: Update user role (never exposed)\nexport const _setUserRole = internalMutation({\n  args: {\n    userId: v.id('users'),\n    role: v.union(v.literal('user'), v.literal('admin')),\n  },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    await ctx.db.patch(args.userId, { role: args.role })\n    return null\n  },\n})\n```\n\n## Best Practices\n\n- Never run `npx convex deploy` unless explicitly instructed\n- Never run any git commands unless explicitly instructed\n- Always verify user identity before returning sensitive data\n- Use internal functions for sensitive operations\n- Validate all arguments with strict validators\n- Check ownership before update\u002Fdelete operations\n- Store API keys in environment variables\n- Review all public functions for security implications\n\n## Common Pitfalls\n\n1. **Missing authentication checks** - Always verify identity\n2. **Exposing internal operations** - Use internalMutation\u002FQuery\n3. **Trusting client-provided IDs** - Verify ownership\n4. **Using v.any() for arguments** - Use specific validators\n5. **Hardcoding secrets** - Use environment variables\n\n## References\n\n- Convex Documentation: https:\u002F\u002Fdocs.convex.dev\u002F\n- Convex LLMs.txt: https:\u002F\u002Fdocs.convex.dev\u002Fllms.txt\n- Authentication: https:\u002F\u002Fdocs.convex.dev\u002Fauth\n- Production Security: https:\u002F\u002Fdocs.convex.dev\u002Fproduction\n- Functions Auth: https:\u002F\u002Fdocs.convex.dev\u002Fauth\u002Ffunctions-auth\n","# Convex Security Check\n\nA quick security audit checklist for Convex applications covering authentication, function exposure, argument validation, row-level access control, and environment variable handling.\n\n## Documentation Sources\n\nBefore implementing, do not assume; fetch the latest documentation:\n\n- Primary: https:\u002F\u002Fdocs.convex.dev\u002Fauth\n- Production Security: https:\u002F\u002Fdocs.convex.dev\u002Fproduction\n- Functions Auth: https:\u002F\u002Fdocs.convex.dev\u002Fauth\u002Ffunctions-auth\n- For broader context: https:\u002F\u002Fdocs.convex.dev\u002Fllms.txt\n\n## Instructions\n\n### Security Checklist\n\nUse this checklist to quickly audit your Convex application's security:\n\n#### 1. Authentication\n\n- [ ] Authentication provider configured (Clerk, Auth0, etc.)\n- [ ] All sensitive queries check `ctx.auth.getUserIdentity()`\n- [ ] Unauthenticated access explicitly allowed where intended\n- [ ] Session tokens properly validated\n\n#### 2. Function Exposure\n\n- [ ] Public functions (`query`, `mutation`, `action`) reviewed\n- [ ] Internal functions use `internalQuery`, `internalMutation`, `internalAction`\n- [ ] No sensitive operations exposed as public functions\n- [ ] HTTP actions validate origin\u002Fauthentication\n\n#### 3. Argument Validation\n\n- [ ] All functions have explicit `args` validators\n- [ ] All functions have explicit `returns` validators\n- [ ] No `v.any()` used for sensitive data\n- [ ] ID validators use correct table names\n\n#### 4. Row-Level Access Control\n\n- [ ] Users can only access their own data\n- [ ] Admin functions check user roles\n- [ ] Shared resources have proper access checks\n- [ ] Deletion functions verify ownership\n\n#### 5. Environment Variables\n\n- [ ] API keys stored in environment variables\n- [ ] No secrets in code or schema\n- [ ] Different keys for dev\u002Fprod environments\n- [ ] Environment variables accessed only in actions\n\n### Authentication Check\n\n```typescript\n\u002F\u002F convex\u002Fauth.ts\nimport { query, mutation } from '.\u002F_generated\u002Fserver'\nimport { v } from 'convex\u002Fvalues'\nimport { ConvexError } from 'convex\u002Fvalues'\n\n\u002F\u002F Helper to require authentication\nasync function requireAuth(ctx: QueryCtx | MutationCtx) {\n  const identity = await ctx.auth.getUserIdentity()\n  if (!identity) {\n    throw new ConvexError('Authentication required')\n  }\n  return identity\n}\n\n\u002F\u002F Secure query pattern\nexport const getMyProfile = query({\n  args: {},\n  returns: v.union(\n    v.object({\n      _id: v.id('users'),\n      name: v.string(),\n      email: v.string(),\n    }),\n    v.null(),\n  ),\n  handler: async (ctx) => {\n    const identity = await requireAuth(ctx)\n\n    return await ctx.db\n      .query('users')\n      .withIndex('by_tokenIdentifier', (q) =>\n        q.eq('tokenIdentifier', identity.tokenIdentifier),\n      )\n      .unique()\n  },\n})\n```\n\n### Function Exposure Check\n\n```typescript\n\u002F\u002F PUBLIC - Exposed to clients (review carefully!)\nexport const listPublicPosts = query({\n  args: {},\n  returns: v.array(\n    v.object({\n      \u002F* ... *\u002F\n    }),\n  ),\n  handler: async (ctx) => {\n    \u002F\u002F Anyone can call this - intentionally public\n    return await ctx.db\n      .query('posts')\n      .withIndex('by_public', (q) => q.eq('isPublic', true))\n      .collect()\n  },\n})\n\n\u002F\u002F INTERNAL - Only callable from other Convex functions\nexport const _updateUserCredits = internalMutation({\n  args: { userId: v.id('users'), amount: v.number() },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    \u002F\u002F This cannot be called directly from clients\n    await ctx.db.patch(args.userId, {\n      credits: args.amount,\n    })\n    return null\n  },\n})\n```\n\n### Argument Validation Check\n\n```typescript\n\u002F\u002F GOOD: Strict validation\nexport const createPost = mutation({\n  args: {\n    title: v.string(),\n    content: v.string(),\n    category: v.union(v.literal('tech'), v.literal('news'), v.literal('other')),\n  },\n  returns: v.id('posts'),\n  handler: async (ctx, args) => {\n    const identity = await requireAuth(ctx)\n    return await ctx.db.insert('posts', {\n      ...args,\n      authorId: identity.tokenIdentifier,\n    })\n  },\n})\n\n\u002F\u002F BAD: Weak validation\nexport const createPostUnsafe = mutation({\n  args: {\n    data: v.any(), \u002F\u002F DANGEROUS: Allows any data\n  },\n  returns: v.id('posts'),\n  handler: async (ctx, args) => {\n    return await ctx.db.insert('posts', args.data)\n  },\n})\n```\n\n### Row-Level Access Control Check\n\n```typescript\n\u002F\u002F Verify ownership before update\nexport const updateTask = mutation({\n  args: {\n    taskId: v.id('tasks'),\n    title: v.string(),\n  },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    const identity = await requireAuth(ctx)\n\n    const task = await ctx.db.get(args.taskId)\n\n    \u002F\u002F Check ownership\n    if (!task || task.userId !== identity.tokenIdentifier) {\n      throw new ConvexError('Not authorized to update this task')\n    }\n\n    await ctx.db.patch(args.taskId, { title: args.title })\n    return null\n  },\n})\n\n\u002F\u002F Verify ownership before delete\nexport const deleteTask = mutation({\n  args: { taskId: v.id('tasks') },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    const identity = await requireAuth(ctx)\n\n    const task = await ctx.db.get(args.taskId)\n\n    if (!task || task.userId !== identity.tokenIdentifier) {\n      throw new ConvexError('Not authorized to delete this task')\n    }\n\n    await ctx.db.delete(args.taskId)\n    return null\n  },\n})\n```\n\n### Environment Variables Check\n\n```typescript\n\u002F\u002F convex\u002Factions.ts\n'use node'\n\nimport { action } from '.\u002F_generated\u002Fserver'\nimport { v } from 'convex\u002Fvalues'\n\nexport const sendEmail = action({\n  args: {\n    to: v.string(),\n    subject: v.string(),\n    body: v.string(),\n  },\n  returns: v.object({ success: v.boolean() }),\n  handler: async (ctx, args) => {\n    \u002F\u002F Access API key from environment\n    const apiKey = process.env.RESEND_API_KEY\n\n    if (!apiKey) {\n      throw new Error('RESEND_API_KEY not configured')\n    }\n\n    const response = await fetch('https:\u002F\u002Fapi.resend.com\u002Femails', {\n      method: 'POST',\n      headers: {\n        Authorization: `Bearer ${apiKey}`,\n        'Content-Type': 'application\u002Fjson',\n      },\n      body: JSON.stringify({\n        from: 'noreply@example.com',\n        to: args.to,\n        subject: args.subject,\n        html: args.body,\n      }),\n    })\n\n    return { success: response.ok }\n  },\n})\n```\n\n## Examples\n\n### Complete Security Pattern\n\n```typescript\n\u002F\u002F convex\u002Fsecure.ts\nimport { query, mutation, internalMutation } from '.\u002F_generated\u002Fserver'\nimport { v } from 'convex\u002Fvalues'\nimport { ConvexError } from 'convex\u002Fvalues'\n\n\u002F\u002F Authentication helper\nasync function getAuthenticatedUser(ctx: QueryCtx | MutationCtx) {\n  const identity = await ctx.auth.getUserIdentity()\n  if (!identity) {\n    throw new ConvexError({\n      code: 'UNAUTHENTICATED',\n      message: 'You must be logged in',\n    })\n  }\n\n  const user = await ctx.db\n    .query('users')\n    .withIndex('by_tokenIdentifier', (q) =>\n      q.eq('tokenIdentifier', identity.tokenIdentifier),\n    )\n    .unique()\n\n  if (!user) {\n    throw new ConvexError({\n      code: 'USER_NOT_FOUND',\n      message: 'User profile not found',\n    })\n  }\n\n  return user\n}\n\n\u002F\u002F Check admin role\nasync function requireAdmin(ctx: QueryCtx | MutationCtx) {\n  const user = await getAuthenticatedUser(ctx)\n\n  if (user.role !== 'admin') {\n    throw new ConvexError({\n      code: 'FORBIDDEN',\n      message: 'Admin access required',\n    })\n  }\n\n  return user\n}\n\n\u002F\u002F Public: List own tasks\nexport const listMyTasks = query({\n  args: {},\n  returns: v.array(\n    v.object({\n      _id: v.id('tasks'),\n      title: v.string(),\n      completed: v.boolean(),\n    }),\n  ),\n  handler: async (ctx) => {\n    const user = await getAuthenticatedUser(ctx)\n\n    return await ctx.db\n      .query('tasks')\n      .withIndex('by_user', (q) => q.eq('userId', user._id))\n      .collect()\n  },\n})\n\n\u002F\u002F Admin only: List all users\nexport const listAllUsers = query({\n  args: {},\n  returns: v.array(\n    v.object({\n      _id: v.id('users'),\n      name: v.string(),\n      role: v.string(),\n    }),\n  ),\n  handler: async (ctx) => {\n    await requireAdmin(ctx)\n\n    return await ctx.db.query('users').collect()\n  },\n})\n\n\u002F\u002F Internal: Update user role (never exposed)\nexport const _setUserRole = internalMutation({\n  args: {\n    userId: v.id('users'),\n    role: v.union(v.literal('user'), v.literal('admin')),\n  },\n  returns: v.null(),\n  handler: async (ctx, args) => {\n    await ctx.db.patch(args.userId, { role: args.role })\n    return null\n  },\n})\n```\n\n## Best Practices\n\n- Never run `npx convex deploy` unless explicitly instructed\n- Never run any git commands unless explicitly instructed\n- Always verify user identity before returning sensitive data\n- Use internal functions for sensitive operations\n- Validate all arguments with strict validators\n- Check ownership before update\u002Fdelete operations\n- Store API keys in environment variables\n- Review all public functions for security implications\n\n## Common Pitfalls\n\n1. **Missing authentication checks** - Always verify identity\n2. **Exposing internal operations** - Use internalMutation\u002FQuery\n3. **Trusting client-provided IDs** - Verify ownership\n4. **Using v.any() for arguments** - Use specific validators\n5. **Hardcoding secrets** - Use environment variables\n\n## References\n\n- Convex Documentation: https:\u002F\u002Fdocs.convex.dev\u002F\n- Convex LLMs.txt: https:\u002F\u002Fdocs.convex.dev\u002Fllms.txt\n- Authentication: https:\u002F\u002Fdocs.convex.dev\u002Fauth\n- Production Security: https:\u002F\u002Fdocs.convex.dev\u002Fproduction\n- Functions Auth: https:\u002F\u002Fdocs.convex.dev\u002Fauth\u002Ffunctions-auth\n",{"name":5,"tags":37,"author":38,"version":39,"description":7,"displayName":40},[19,20,24,27,31],"Convex","1.0.0","Convex Security Check","main","83212e6d909b6a0fe9e93fd5a3ff1723300f5b5b",".claude\u002Fskills\u002Fconvex-security-check","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":49,"prompt":59,"zipAvailable":60},[50,53,56],{"tool":51,"command":52},"npx","npx skills add baisharg\u002FASTN --skill convex-security-check",{"tool":54,"command":55},"bunx","bunx skills add baisharg\u002FASTN --skill convex-security-check",{"tool":57,"command":58},"pnpm","pnpm dlx skills add baisharg\u002FASTN --skill convex-security-check","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fbaisharg\u002FASTN\u002Fblob\u002Fmain\u002F.claude\u002Fskills\u002Fconvex-security-check\u002FSKILL.md",true,[62,68],{"path":63,"resourceType":64,"resourceTypeDesc":65,"sizeBytes":66,"sourceHtmlUrl":67},"SOURCE.md","REFERENCE","参考文档",218,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fdefi\u002Fpendle-yield-agent\u002FSOURCE.md",{"path":69,"resourceType":64,"resourceTypeDesc":65,"sizeBytes":70,"sourceHtmlUrl":71},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fdefi\u002Fpendle-yield-agent\u002FTRUST.auto.yaml",[73,94,108,122,136,153],{"skillNo":74,"name":75,"nameZh":6,"description":76,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":84,"publishedAt":32},"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",[79],{"categoryNo":80,"categoryName":81,"taxonomyType":82,"taxonomyTypeDesc":83},"01JBSEEDCAT000000000000015","视觉设计","SCENARIO","使用场景",[85,86,87,88,25,89,90,91,92,19,93],"schema builder","schema","builder","indexes","use","table","database","design","generate",{"skillNo":95,"name":96,"nameZh":6,"description":97,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":98,"categories":99,"keywords":100,"publishedAt":32},"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",[],[101,102,103,104,105,106,107],"integration","start","tanstack","integration tanstack start","posthog","applications","stack",{"skillNo":109,"name":110,"nameZh":6,"description":111,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":112,"categories":113,"keywords":114,"publishedAt":32},"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",[],[115,116,117,118,119,120,89,86,121,19],"migration","migration helper","schema migrations safely","data","plan","execute","migrations",{"skillNo":123,"name":124,"nameZh":6,"description":125,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":126,"categories":127,"keywords":128,"publishedAt":32},"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",[],[124,129,130,25,102,131,132,133,134,119,135,120],"resume","codex","execution","verify","Bash","loop","autonomous",{"skillNo":137,"name":138,"nameZh":6,"description":139,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":140,"categories":141,"keywords":142,"publishedAt":32},"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",[],[143,144,145,130,146,147,148,149,150,151,89,152],"gsd:second opinion","second opinion","question","architecture","code","verification","openai","gpt","decisions","implementation",{"skillNo":154,"name":155,"nameZh":6,"description":156,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":157,"categories":158,"keywords":159,"publishedAt":32},"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",[],[160,161,25,26,162,163,129,130],"gsd:milestone sprint","run","interactive","auto"]