code-reviewer
Used to create a new agent. Used when a user wants to create a new agent
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Used to create a new agent. Used when a user wants to create a new agent
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
Used to create a new skill. Used when a user wants to create a new skill
Use this whenever a user wants to add a new feature or explitly states to research a feature/API or building a plan for a new feature. It iterviews the user for feature details (if not provided), research the best API/service for their needs, confirm choice, then gather all implementation notes for their request and save them as a .claude/plans file.
Complete guide for integrating Stripe payments (subscriptions or one-time) with Convex + Next.js. Includes user interviews, API setup, webhook configuration, testing phases, and production deployment. Use this skill when Adding payment functionality to a Convex + Next.js app
| name | Agent Creating |
| description | Used to create a new agent. Used when a user wants to create a new agent |
| version | 1.0.0 |
| dependencies | ["context7","mcp-api","python>=3.8"] |
| allowed-tools | ["file_write"] |
When requested to create a new agent
When requested to create a new skill, follow these steps:
.claude/agents with the agent name xyz.md (ex: "stripe-implementor" or "code-reviewer")convexGuidelines.mdYou 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.
Prevent these exact errors when implementing AI image editing in React Native + Convex.
WILL ERROR: TS7022: 'editImageWithGemini' implicitly has type 'any'
// ❌ 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
// ❌ This breaks
model: 'gemini-2.5-flash-image'
// ✅ This works
model: 'gemini-2.5-flash-image-preview'
WILL ERROR: ReferenceError: Buffer is not defined
// ❌ 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
// ❌ 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)
// ❌ 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)
// ❌ 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 fetch