一键导入
production-harden
Transform vibe-coded MVPs into production-grade, reusable templates. Systematically audit and fix the Five Mortal Sins of production code.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Transform vibe-coded MVPs into production-grade, reusable templates. Systematically audit and fix the Five Mortal Sins of production code.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Automatically detect and save person-related information (names, roles, contact info, relationships, organizations) to Core Memory (Caduceus). Triggers when user mentions people with descriptive details like job titles, phone numbers, emails, responsibilities, or relationships to other people or organizations.
Send professional client updates with deliverables via email and WhatsApp notification. Use when user wants to share work, send assets, or give a client an update on progress.
Distill Claude Code session operations into reusable tinctures (Skills, Commands, Agents). Uses category theory for structural preservation, information theory for potency analysis, and the Golden Ratio for classification. Use when you want to capture effective workflows, or when the user says "distill", "extract this", "make a tincture", "capture this workflow", or "turn this into a skill/command".
Fuse two things into one unified creation. Use when user says fuse, fusion, combine, merge, or wants to unite documents, projects, concepts, ideas, frameworks, or any two entities into something greater than either alone.
Pattern for building interactive CLI tutors in Go with standardized colors, progress tracking, and pedagogical elements
Brutal enforcer of production-grade coding practices. The bane of vibe-coded slop and spaghetti code. Mars audits codebases for the hidden sins that separate "it works on my machine" from battle-tested production systems.
| name | production-harden |
| description | Transform vibe-coded MVPs into production-grade, reusable templates. Systematically audit and fix the Five Mortal Sins of production code. |
| triggers | ["/production-harden","/harden","make this production ready","turn this into a template"] |
Purpose: Systematically transform a working MVP into a production-grade, reusable template by addressing the Five Mortal Sins of vibe-coded projects.
as never or as any type bypasses1. Run /mars or manually check each sin
2. Document all findings by severity:
- CRITICAL: Security/data loss risks
- SEVERE: Will cause outages
- MODERATE: Degraded experience
- MINOR: Technical debt
3. Create prioritized todo list
Create these files in src/app/:
error.tsx - Catches route errors
"use client";
import { useEffect } from "react";
interface ErrorProps {
error: Error & { digest?: string };
reset: () => void;
}
export default function Error({ error, reset }: ErrorProps) {
useEffect(() => {
console.error("Application error:", error);
}, [error]);
return (
<div className="min-h-[50vh] flex flex-col items-center justify-center p-8">
<h1 className="text-2xl font-bold mb-4">Something went wrong</h1>
<button onClick={reset} className="px-4 py-2 bg-blue-500 text-white rounded">
Try again
</button>
</div>
);
}
global-error.tsx - Catches root layout errors
"use client";
export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<html>
<body>
<h1>Critical Error</h1>
<button onClick={reset}>Try again</button>
</body>
</html>
);
}
not-found.tsx - Custom 404
import Link from "next/link";
export default function NotFound() {
return (
<div className="min-h-[50vh] flex flex-col items-center justify-center">
<h1 className="text-4xl font-bold mb-4">404</h1>
<p className="mb-4">Page not found</p>
<Link href="/" className="text-blue-500 hover:underline">
Go home
</Link>
</div>
);
}
"use client";
import Image from "next/image";
import { useState } from "react";
const FALLBACK_IMAGE = "/images/placeholder.png";
interface GameImageProps {
src: string;
alt: string;
fill?: boolean;
width?: number;
height?: number;
sizes?: string;
className?: string;
}
export function GameImage({ src, alt, fill, width, height, sizes, className = "object-contain" }: GameImageProps) {
const [imgSrc, setImgSrc] = useState(src);
const [hasError, setHasError] = useState(false);
const handleError = () => {
if (!hasError) {
setHasError(true);
setImgSrc(FALLBACK_IMAGE);
}
};
if (fill) {
return <Image src={imgSrc} alt={alt} fill sizes={sizes} className={className} onError={handleError} />;
}
return <Image src={imgSrc} alt={alt} width={width} height={height} className={className} onError={handleError} />;
}
// src/lib/schemas.ts
import { z } from "zod";
// Define schemas matching your TypeScript types
export const ItemSchema = z.object({
name: z.string(),
rarity: z.enum(["Common", "Rare", "Epic", "Legendary"]),
description: z.string().nullable(),
// ... other fields
});
export const ItemsFileSchema = z.record(z.string(), ItemSchema);
// Validation helper
export function validateData<T>(schema: z.ZodType<T>, data: unknown, name: string): T {
const result = schema.safeParse(data);
if (!result.success) {
console.error(`Validation failed for ${name}:`, result.error.format());
throw new Error(`Invalid ${name} data`);
}
return result.data;
}
// In data.ts - validate at module load (build time for SSG)
import { validateData, ItemsFileSchema } from "./schemas";
import itemsData from "../../data/items.json";
const validatedItems = validateData(ItemsFileSchema, itemsData, "items");
// Avoid `as never` by using generics
interface FilterBarProps<T extends string> {
options: { value: T; label: string }[];
selected: T[];
onChange: (selected: T[]) => void;
}
export function FilterBar<T extends string>({ options, selected, onChange }: FilterBarProps<T>) {
// Component implementation
}
// Usage with proper typing
const [selectedTags, setSelectedTags] = useState<ItemTag[]>([]);
<FilterBar<ItemTag> options={tagOptions} selected={selectedTags} onChange={setSelectedTags} />
// For client components, split into:
// 1. src/components/pages/items-content.tsx (client component with useState)
// 2. src/app/items/page.tsx (server component with metadata)
// page.tsx
import type { Metadata } from "next";
import { ItemsContent } from "@/components/pages/items-content";
export const metadata: Metadata = {
title: "Items | My App",
description: "Browse all items with filtering and search.",
openGraph: {
title: "Items | My App",
description: "Browse all items with filtering and search.",
},
};
export default function ItemsPage() {
return <ItemsContent />;
}
// Use semantic HTML
<article aria-label={`${item.name} - ${item.rarity}`}>
{/* content */}
</article>
// Add aria attributes to interactive elements
<button
aria-pressed={isSelected}
aria-label={`Filter by ${option.label}`}
>
{option.label}
</button>
// Group related controls
<div role="group" aria-label="Filter by rarity">
{/* filter buttons */}
</div>
# Document all environment variables
# Copy to .env.local and configure
# Required
# DATABASE_URL=postgresql://...
# Optional
# NEXT_PUBLIC_GA_ID=G-XXXXXXXXXX
# Note: This project uses static data, no external APIs required
{
"compilerOptions": {
"strict": true,
// ... other options
}
}
# Type check
npx tsc --noEmit
# Build (validates Zod schemas at build time)
npm run build
# Deploy
vercel --prod
When Zod validation fails during build, it reveals real issues:
.nullable() not .optional())For pages needing both metadata and interactivity:
// Single source of truth for ordering
export const RARITY_ORDER = ["Common", "Rare", "Epic", "Legendary"] as const;
// Typed color maps
export const rarityColors: Record<Rarity, string> = {
Common: "text-gray-500",
Rare: "text-blue-500",
// ...
};
| Phase | Tasks | Time |
|---|---|---|
| Audit | Review all files, document issues | 15-30 min |
| Error Handling | Boundaries, fallbacks, validation | 30-60 min |
| Type Safety | Fix assertions, add Zod | 30-60 min |
| Polish | SEO, accessibility, .env | 20-30 min |
| Deploy | Build, test, deploy | 10-15 min |
Total: 2-3 hours for a typical MVP
as never or as any in codebase