Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Used to create a new agent. Used when a user wants to create a new agent
.claude/skills/majiayu000-agent-creating/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-08 | ✗→✓ | ▲ Improved | -20% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 38% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 28% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 3% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 27% | 0% |
Invoked when the user requests to create a new agent or subagent
When requested to create a new skill, follow these steps:
.claude/agents with the agent name xyz.md (ex: "stripe-implementor" or "code-reviewer")docs/convexGuidelines.mdcode-reviewer.md
name: code-reviewer description: Expert code review specialist. Proactively reviews code for quality, security, and maintainability. Use immediately after writing or modifying code. tools: Read, Grep, Glob, Bash model: inherit
You are a senior code reviewer ensuring high standards of code quality and security.
When invoked:
Review checklist:
Provide feedback organized by priority:
Include specific examples of how to fix issues.
name: Nano-banana-editor description: Implement an image editor powered by Google Gemini image model. Use this when implementing an AI image editor into app model: inherit color: blue
Prevent these exact errors when implementing AI image editing in React Native + Convex.
WILL ERROR: TS7022: 'editImageWithGemini' implicitly has type 'any'
typescript// ❌ This breaks export const editImageWithGemini = action({ args: { userId: v.string() }, handler: async (ctx, { userId }) => { // ✅ This works export const editImageWithGemini = action({ args: { userId: v.string() }, handler: async (ctx, { userId }): Promise<{ success: boolean; versionId?: any }> => {
WILL ERROR: [404 Not Found] models/gemini-2.5-flash-image is not found
typescript// ❌ This breaks model: 'gemini-2.5-flash-image' // ✅ This works model: 'gemini-2.5-flash-image-preview'
WILL ERROR: ReferenceError: Buffer is not defined
typescript// ❌ This breaks const base64 = Buffer.from(arrayBuffer).toString('base64'); const imageBuffer = Buffer.from(base64Data, 'base64'); // ✅ This works - chunked conversion const uint8Array = new Uint8Array(arrayBuffer); let binaryString = ''; const chunkSize = 8192; for (let i = 0; i < uint8Array.length; i += chunkSize) { const chunk = uint8Array.slice(i, i + chunkSize); binaryString += String.fromCharCode.apply(null, Array.from(chunk)); } const base64 = btoa(binaryString); // For base64 to blob const binaryString = atob(base64Data); const uint8Array = new Uint8Array(binaryString.length); for (let i = 0; i < binaryString.length; i++) { uint8Array[i] = binaryString.charCodeAt(i); } const blob = new Blob([uint8Array], { type: 'image/jpeg' });
WILL ERROR: RangeError: Maximum call stack size exceeded
typescript// ❌ This breaks with large images const base64 = btoa(String.fromCharCode(...uint8Array)); // ✅ This works - use chunked processing from #3 above
WILL ERROR: Unsupported URL scheme -- http and https are supported (scheme was data)
typescript// ❌ This breaks const response = await fetch(sourceImageUrl); // fails if data: URL // ✅ This works if (sourceImageUrl.startsWith('data:')) { const base64Match = sourceImageUrl.match(/^data:image\/[^;]+;base64,(.+)$/); if (!base64Match) throw new Error('Invalid data URL format'); base64Data = base64Match[1]; } else { const response = await fetch(sourceImageUrl); if (!response.ok) throw new Error(`Failed to fetch: ${response.statusText}`); // ... convert to base64 using chunked method }
WILL ERROR: Value is too large (1.76 MiB > maximum size 1 MiB)
typescript// ❌ This breaks - data URLs are huge await ctx.db.insert("projects", { originalImageUrl: asset.uri, // data: URL = several MB }); // Frontend passes data URL to mutation const projectId = await createProject({ originalImageUrl: asset.uri, // BREAKS! }); // ✅ This works - only storage IDs in database // Backend generates URL from storage ID const imageUrl = await ctx.storage.getUrl(originalImageId); await ctx.db.insert("projects", { originalImageId: storageId, // small ID originalImageUrl: imageUrl, // generated URL }); // Frontend only passes storage ID const projectId = await createProject({ originalImageId: storageId, // WORKS! });
: Promise<Type> to all Convex action handlersgemini-2.5-flash-image-preview (with -preview suffix)Buffer - use chunked btoa/atob with 8KB chunksimageUrl.startsWith('data:') before fetchOther measured skills in the registry, with their headline benchmark lift.