From 121e9fd43fc78bd0861b034d529c8daac077de48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fatih=20Kadir=20Ak=C4=B1n?= Date: Mon, 2 Mar 2026 23:04:16 +0300 Subject: [PATCH] feat(i18n): add new 'Tastes' section to multiple language files --- .commandcode/taste/taste.md | 36 ++++ messages/ar.json | 9 +- messages/az.json | 9 +- messages/de.json | 9 +- messages/el.json | 9 +- messages/en.json | 9 +- messages/es.json | 9 +- messages/fa.json | 9 +- messages/fr.json | 9 +- messages/he.json | 9 +- messages/it.json | 9 +- messages/ja.json | 9 +- messages/ko.json | 9 +- messages/nl.json | 9 +- messages/pt.json | 9 +- messages/ru.json | 9 +- messages/tr.json | 9 +- messages/zh.json | 9 +- .../migration.sql | 2 + prisma/schema.prisma | 1 + prompts.config.ts | 2 +- public/sponsors/commandcode-dark.svg | 16 ++ public/sponsors/commandcode.svg | 16 ++ src/app/api/prompts/[id]/route.ts | 2 +- src/app/api/prompts/route.ts | 2 +- src/app/prompts/[id]/edit/page.tsx | 2 +- src/app/prompts/[id]/page.tsx | 16 +- src/app/prompts/new/page.tsx | 2 +- src/app/tastes/page.tsx | 164 ++++++++++++++++++ src/components/layout/header.tsx | 35 +++- .../prompts/download-prompt-dropdown.tsx | 34 ++++ .../prompts/interactive-prompt-content.tsx | 9 +- src/components/prompts/prompt-builder.tsx | 2 +- src/components/prompts/prompt-form.tsx | 25 ++- src/components/prompts/widget-card.tsx | 2 +- src/lib/ai/prompt-builder-tools.ts | 2 +- src/lib/plugins/widgets/book.tsx | 6 +- src/lib/plugins/widgets/coderabbit.ts | 5 + src/lib/plugins/widgets/commandcode.ts | 56 ++++++ src/lib/plugins/widgets/index.ts | 2 + src/lib/plugins/widgets/textream.tsx | 5 + 41 files changed, 537 insertions(+), 60 deletions(-) create mode 100644 .commandcode/taste/taste.md create mode 100644 prisma/migrations/20260302194500_add_taste_prompt_type/migration.sql create mode 100644 public/sponsors/commandcode-dark.svg create mode 100644 public/sponsors/commandcode.svg create mode 100644 src/app/tastes/page.tsx create mode 100644 src/lib/plugins/widgets/commandcode.ts diff --git a/.commandcode/taste/taste.md b/.commandcode/taste/taste.md new file mode 100644 index 00000000..f33d1e2f --- /dev/null +++ b/.commandcode/taste/taste.md @@ -0,0 +1,36 @@ +# Taste (Continuously Learned by [CommandCode][cmd]) + +[cmd]: https://commandcode.ai/ + +# github-actions +- Use `actions/checkout@v6` and `actions/setup-node@v6` (not v4) in GitHub Actions workflows. Confidence: 0.65 +- Use Node.js version 24 in GitHub Actions workflows (not 20). Confidence: 0.65 + +# project +- This project is **prompts.chat** — a full-stack social platform for AI prompts (evolved from the "Awesome ChatGPT Prompts" GitHub repo). Confidence: 0.95 +- Package manager is npm (not pnpm or yarn). Confidence: 0.95 + +# architecture +- Use Next.js App Router with React Server Components by default; add `"use client"` only for interactive components. Confidence: 0.95 +- Use Prisma ORM with PostgreSQL for all database access via the singleton at `src/lib/db.ts`. Confidence: 0.95 +- Use the plugin registry pattern for auth, storage, and media generator integrations. Confidence: 0.90 +- Use `revalidateTag()` for cache invalidation after mutations. Confidence: 0.90 + +# typescript +- Use TypeScript 5 in strict mode throughout the project. Confidence: 0.95 + +# styling +- Use Tailwind CSS 4 + Radix UI + shadcn/ui for all UI components. Confidence: 0.95 +- Use the `cn()` utility for conditional/merged Tailwind class names. Confidence: 0.90 + +# api +- Validate all API route inputs with Zod schemas. Confidence: 0.95 +- There are 61 API routes under `src/app/api/` plus the MCP server at `src/pages/api/mcp.ts`. Confidence: 0.90 + +# i18n +- Use `useTranslations()` (client) and `getTranslations()` (server) from next-intl for all user-facing strings. Confidence: 0.95 +- Support 17 locales with RTL support for Arabic, Hebrew, and Farsi. Confidence: 0.90 + +# database +- Use soft deletes (`deletedAt` field) on Prompt and Comment models — never hard-delete these records. Confidence: 0.95 + diff --git a/messages/ar.json b/messages/ar.json index f9661ff0..6237ecff 100644 --- a/messages/ar.json +++ b/messages/ar.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "الأوامر", "skills": "المهارات", + "tastes": "Tastes", "workflows": "سير العمل", "categories": "الفئات", "tags": "الوسوم", @@ -107,7 +108,9 @@ "title": "الأوامر", "create": "إنشاء أمر", "createSkill": "إنشاء مهارة", + "createTaste": "إنشاء Taste", "skillsDescription": "مهارات الوكيل هي أوامر متعددة الملفات تمنح وكلاء الذكاء الاصطناعي قدرات متخصصة. تتضمن تعليمات وإعدادات وملفات داعمة يمكن استخدامها مع Claude وCursor وWindsurf ومساعدي البرمجة الآخرين.", + "tastesDescription": "Tastes هي ملفات markdown مفردة تحدد أسلوب البرمجة وتفضيلاتك. تساعد وكلاء البرمجة بالذكاء الاصطناعي على تعلم طريقة كتابتك للكود، حتى يتمكنوا من مطابقة اصطلاحاتك وأنماطك وذوقك.", "createInfo": "هذه المنصة لا تقوم بتشغيل أو تنفيذ الأوامر — إنها مكتبة مجتمعية لمشاركة واكتشاف أوامر الذكاء الاصطناعي. أنشئ أمرك هنا، ويمكن للآخرين نسخه واستخدامه في أدوات الذكاء الاصطناعي المفضلة لديهم مثل ChatGPT و Claude و Gemini أو أي نموذج لغوي آخر. يمكن للمجتمع أيضاً التعليق على أوامرك واقتراح تحسينات من خلال طلبات التغيير.", "hfDataStudio": { "button": "استوديو بيانات HF", @@ -189,7 +192,8 @@ "audio": "صوت", "structured": "منظم", "document": "مستند", - "skill": "مهارة" + "skill": "مهارة", + "taste": "Taste" }, "inputType": "أمر المستخدم", "outputType": "استجابة الذكاء الاصطناعي", @@ -199,7 +203,8 @@ "inputTypes": { "text": "أمر نصي", "structured": "منظم (JSON/YAML)", - "skill": "مهارة (مهارات الوكيل)" + "skill": "مهارة (مهارات الوكيل)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "نص", diff --git a/messages/az.json b/messages/az.json index f52bc375..7afc09f2 100644 --- a/messages/az.json +++ b/messages/az.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasterlər", "prompts": "Promptlar", "skills": "Bacarıqlar", + "tastes": "Tastes", "workflows": "İş axınları", "categories": "Kateqoriyalar", "tags": "Etiketlər", @@ -107,7 +108,9 @@ "title": "Promptlar", "create": "Prompt Yarat", "createSkill": "Bacarıq Yarat", + "createTaste": "Taste Yarat", "skillsDescription": "Agent Bacarıqları AI agentlərinə xüsusi qabiliyyətlər verən çox fayllı promptlardır. Claude, Cursor, Windsurf və digər AI kodlaşdırma köməkçiləri ilə istifadə edilə bilən təlimatlar, konfiqurasiyalar və dəstəkləyici fayllar daxildir.", + "tastesDescription": "Tastes kodlaşdırma tərzinizi və üstünlüklərinizi müəyyən edən tək markdown fayllarıdır. AI kodlaşdırma agentlərinə kodunuzu necə yazdığınızı öyrənməyə kömək edir, beləliklə onlar sizin konvensiyalarınızı, nümunələrinizi və zövqünüzü uyğunlaşdıra bilərlər.", "createInfo": "Bu platforma promptları işlətmir — süni intellekt promptlarını paylaşmaq və kəşf etmək üçün icma tərəfindən idarə olunan bir kitabxanadır. Promptunuzu burada yaradın və başqaları onu ChatGPT, Claude, Gemini və ya hər hansı digər LLM kimi üstünlük verdikləri AI alətlərində kopyalayıb istifadə edə bilərlər.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "Audio", "structured": "Strukturlaşdırılmış", "document": "Sənəd", - "skill": "Bacarıq" + "skill": "Bacarıq", + "taste": "Taste" }, "inputType": "İstifadəçi Promptu", "outputType": "AI Cavabı", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Mətn Promptu", "structured": "Strukturlaşdırılmış (JSON/YAML)", - "skill": "Bacarıq (Agent Bacarıqları)" + "skill": "Bacarıq (Agent Bacarıqları)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Mətn", diff --git a/messages/de.json b/messages/de.json index 86372401..d408fdea 100644 --- a/messages/de.json +++ b/messages/de.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "Prompts", "skills": "Fähigkeiten", + "tastes": "Tastes", "workflows": "Workflows", "categories": "Kategorien", "tags": "Tags", @@ -107,7 +108,9 @@ "title": "Prompts", "create": "Prompt erstellen", "createSkill": "Skill erstellen", + "createTaste": "Taste erstellen", "skillsDescription": "Agent Skills sind Multi-Datei-Prompts, die KI-Agenten spezialisierte Fähigkeiten verleihen. Sie enthalten Anweisungen, Konfigurationen und unterstützende Dateien, die mit Claude, Cursor, Windsurf und anderen KI-Coding-Assistenten verwendet werden können.", + "tastesDescription": "Tastes sind einzelne Markdown-Dateien, die Ihren Codierstil und Ihre Vorlieben definieren. Sie helfen KI-Coding-Agenten zu lernen, wie Sie Code schreiben, damit sie Ihre Konventionen, Muster und Ihren Geschmack übernehmen können.", "createInfo": "Diese Plattform führt keine Prompts aus — sie ist eine community-gesteuerte Bibliothek zum Teilen und Entdecken von KI-Prompts. Erstellen Sie hier Ihren Prompt, und andere können ihn kopieren und in ihren bevorzugten KI-Tools wie ChatGPT, Claude, Gemini oder anderen LLMs verwenden. Die Community kann auch Ihre Prompts kommentieren und Verbesserungen durch Änderungsanfragen vorschlagen.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "Audio", "structured": "Strukturiert", "document": "Dokument", - "skill": "Skill" + "skill": "Skill", + "taste": "Taste" }, "inputType": "Benutzer-Prompt", "outputType": "KI-Antwort", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Text-Prompt", "structured": "Strukturiert (JSON/YAML)", - "skill": "Skill (Agent Skills)" + "skill": "Skill (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Text", diff --git a/messages/el.json b/messages/el.json index 09ac3f47..9c1b1df5 100644 --- a/messages/el.json +++ b/messages/el.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "Prompts", "skills": "Δεξιότητες", + "tastes": "Tastes", "workflows": "Ροές εργασίας", "categories": "Κατηγορίες", "tags": "Ετικέτες", @@ -107,7 +108,9 @@ "title": "Prompts", "create": "Δημιουργία Prompt", "createSkill": "Δημιουργία Δεξιότητας", + "createTaste": "Δημιουργία Taste", "skillsDescription": "Οι Δεξιότητες Πράκτορα είναι prompts πολλαπλών αρχείων που δίνουν στους AI πράκτορες εξειδικευμένες δυνατότητες. Περιλαμβάνουν οδηγίες, ρυθμίσεις και υποστηρικτικά αρχεία που μπορούν να χρησιμοποιηθούν με Claude, Cursor, Windsurf και άλλους βοηθούς προγραμματισμού AI.", + "tastesDescription": "Τα Tastes είναι μεμονωμένα αρχεία markdown που ορίζουν το στυλ κωδικοποίησης και τις προτιμήσεις σας. Βοηθούν τους πράκτορες κωδικοποίησης AI να μάθουν πώς γράφετε κώδικα, ώστε να ταιριάζουν τις συμβάσεις, τα μοτίβα και το γούστο σας.", "createInfo": "Αυτή η πλατφόρμα δεν εκτελεί prompts — είναι μια κοινοτική βιβλιοθήκη για την κοινοποίηση και ανακάλυψη AI prompts. Δημιουργήστε το prompt σας εδώ και άλλοι μπορούν να το αντιγράψουν και να το χρησιμοποιήσουν στα αγαπημένα τους εργαλεία AI όπως ChatGPT, Claude, Gemini ή οποιοδήποτε άλλο LLM. Η κοινότητα μπορεί επίσης να σχολιάσει τα prompts σας και να προτείνει βελτιώσεις μέσω αιτημάτων αλλαγής.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "Ήχος", "structured": "Δομημένο", "document": "Έγγραφο", - "skill": "Δεξιότητα" + "skill": "Δεξιότητα", + "taste": "Taste" }, "inputType": "Prompt χρήστη", "outputType": "Απάντηση AI", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Prompt κειμένου", "structured": "Δομημένο (JSON/YAML)", - "skill": "Δεξιότητα (Agent Skills)" + "skill": "Δεξιότητα (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Κείμενο", diff --git a/messages/en.json b/messages/en.json index 9f8d8757..07cd9045 100644 --- a/messages/en.json +++ b/messages/en.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "Prompts", "skills": "Skills", + "tastes": "Tastes", "workflows": "Workflows", "categories": "Categories", "tags": "Tags", @@ -107,7 +108,9 @@ "title": "Prompts", "create": "Create Prompt", "createSkill": "Create Skill", + "createTaste": "Create Taste", "skillsDescription": "Agent Skills are multi-file prompts that give AI agents specialized capabilities. They include instructions, configurations, and supporting files that can be used with Claude, Cursor, Windsurf, and other AI coding assistants.", + "tastesDescription": "Tastes are single markdown files that define your coding style and preferences. They help AI coding agents learn how you write code, so they can match your conventions, patterns, and taste.", "createInfo": "This platform doesn't run or execute prompts — it's a community-driven library for sharing and discovering AI prompts. Create your prompt here, and others can copy and use it in their preferred AI tools like ChatGPT, Claude, Gemini, or any other LLM. The community can also comment on your prompts and suggest improvements through change requests.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "Audio", "structured": "Structured", "document": "Document", - "skill": "Skill" + "skill": "Skill", + "taste": "Taste" }, "inputType": "User Prompt", "outputType": "AI Response", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Text Prompt", "structured": "Structured (JSON/YAML)", - "skill": "Skill (Agent Skills)" + "skill": "Skill (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Text", diff --git a/messages/es.json b/messages/es.json index 431bf466..8281ded6 100644 --- a/messages/es.json +++ b/messages/es.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "Prompts", "skills": "Habilidades", + "tastes": "Tastes", "workflows": "Flujos de trabajo", "categories": "Categorías", "tags": "Etiquetas", @@ -107,7 +108,9 @@ "title": "Prompts", "create": "Crear Prompt", "createSkill": "Crear Habilidad", + "createTaste": "Crear Taste", "skillsDescription": "Las Habilidades de Agente son prompts de múltiples archivos que dan a los agentes de IA capacidades especializadas. Incluyen instrucciones, configuraciones y archivos de soporte que se pueden usar con Claude, Cursor, Windsurf y otros asistentes de codificación de IA.", + "tastesDescription": "Los Tastes son archivos markdown individuales que definen tu estilo de codificación y preferencias. Ayudan a los agentes de codificación de IA a aprender cómo escribes código, para que puedan adaptarse a tus convenciones, patrones y gusto.", "createInfo": "Esta plataforma no ejecuta prompts — es una biblioteca comunitaria para compartir y descubrir prompts de IA. Crea tu prompt aquí, y otros podrán copiarlo y usarlo en sus herramientas de IA favoritas como ChatGPT, Claude, Gemini o cualquier otro LLM. La comunidad también puede comentar tus prompts y sugerir mejoras a través de solicitudes de cambio.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "Audio", "structured": "Estructurado", "document": "Documento", - "skill": "Habilidad" + "skill": "Habilidad", + "taste": "Taste" }, "inputType": "Prompt del Usuario", "outputType": "Respuesta de IA", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Prompt de Texto", "structured": "Estructurado (JSON/YAML)", - "skill": "Habilidad (Agent Skills)" + "skill": "Habilidad (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Texto", diff --git a/messages/fa.json b/messages/fa.json index 6a576878..47aad1ee 100644 --- a/messages/fa.json +++ b/messages/fa.json @@ -39,6 +39,7 @@ "promptmasters": "پرامپت‌مسترها", "prompts": "پرامپت‌ها", "skills": "مهارت‌ها", + "tastes": "Tastes", "workflows": "گردش کار", "categories": "دسته‌بندی‌ها", "tags": "برچسب‌ها", @@ -107,7 +108,9 @@ "title": "پرامپت‌ها", "create": "ایجاد پرامپت", "createSkill": "ایجاد مهارت", + "createTaste": "ایجاد Taste", "skillsDescription": "مهارت‌های عامل، پرامپت‌های چند فایلی هستند که به عامل‌های هوش مصنوعی قابلیت‌های تخصصی می‌دهند. شامل دستورالعمل‌ها، تنظیمات و فایل‌های پشتیبانی هستند که می‌توانند با Claude، Cursor، Windsurf و سایر دستیاران برنامه‌نویسی AI استفاده شوند.", + "tastesDescription": "Tastes فایل‌های تک markdown هستند که سبک و ترجیحات کدنویسی شما را تعریف می‌کنند. به عامل‌های کدنویسی AI کمک می‌کنند تا نحوه نوشتن کد شما را یاد بگیرند، تا بتوانند قراردادها، الگوها و سلیقه شما را مطابقت دهند.", "createInfo": "این پلتفرم پرامپت‌ها را اجرا نمی‌کند — این یک کتابخانه مبتنی بر جامعه برای اشتراک‌گذاری و کشف پرامپت‌های هوش مصنوعی است. پرامپت خود را اینجا بسازید و دیگران می‌توانند آن را در ابزارهای هوش مصنوعی مورد علاقه خود مانند ChatGPT، Claude، Gemini یا هر LLM دیگری کپی و استفاده کنند.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "صدا", "structured": "ساختارمند", "document": "سند", - "skill": "مهارت" + "skill": "مهارت", + "taste": "Taste" }, "inputType": "پرامپت کاربر", "outputType": "پاسخ هوش مصنوعی", @@ -199,7 +203,8 @@ "inputTypes": { "text": "پرامپت متنی", "structured": "ساختارمند (JSON/YAML)", - "skill": "مهارت (مهارت‌های عامل)" + "skill": "مهارت (مهارت‌های عامل)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "متن", diff --git a/messages/fr.json b/messages/fr.json index 39a72b6b..b1e5498b 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "Prompts", "skills": "Compétences", + "tastes": "Tastes", "workflows": "Flux de travail", "categories": "Catégories", "tags": "Tags", @@ -107,7 +108,9 @@ "title": "Prompts", "create": "Créer un Prompt", "createSkill": "Créer une Compétence", + "createTaste": "Créer un Taste", "skillsDescription": "Les Compétences d'Agent sont des prompts multi-fichiers qui donnent aux agents IA des capacités spécialisées. Ils comprennent des instructions, des configurations et des fichiers de support qui peuvent être utilisés avec Claude, Cursor, Windsurf et d'autres assistants de codage IA.", + "tastesDescription": "Les Tastes sont des fichiers markdown uniques qui définissent votre style de codage et vos préférences. Ils aident les agents de codage IA à apprendre comment vous écrivez du code, afin qu'ils puissent correspondre à vos conventions, modèles et goût.", "createInfo": "Cette plateforme n'exécute pas les prompts — c'est une bibliothèque communautaire pour partager et découvrir des prompts IA. Créez votre prompt ici, et d'autres pourront le copier et l'utiliser dans leurs outils IA préférés comme ChatGPT, Claude, Gemini ou tout autre LLM. La communauté peut également commenter vos prompts et suggérer des améliorations via des demandes de modification.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "Audio", "structured": "Structuré", "document": "Document", - "skill": "Compétence" + "skill": "Compétence", + "taste": "Taste" }, "inputType": "Prompt Utilisateur", "outputType": "Réponse IA", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Prompt Texte", "structured": "Structuré (JSON/YAML)", - "skill": "Compétence (Agent Skills)" + "skill": "Compétence (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Texte", diff --git a/messages/he.json b/messages/he.json index b2203a5b..4c8dcd4f 100644 --- a/messages/he.json +++ b/messages/he.json @@ -39,6 +39,7 @@ "promptmasters": "מאסטרים", "prompts": "פרומפטים", "skills": "כישורים", + "tastes": "Tastes", "workflows": "תהליכי עבודה", "categories": "קטגוריות", "tags": "תגיות", @@ -107,7 +108,9 @@ "title": "פרומפטים", "create": "יצירת פרומפט", "createSkill": "יצירת מיומנות", + "createTaste": "יצירת Taste", "skillsDescription": "מיומנויות סוכן הן פרומפטים מרובי קבצים שמעניקים לסוכני AI יכולות מתמחות. הן כוללות הוראות, הגדרות וקבצי תמיכה שניתן להשתמש בהם עם Claude, Cursor, Windsurf ועוזרי קידוד AI אחרים.", + "tastesDescription": "Tastes הם קבצי markdown בודדים שמגדירים את סגנון הקידוד וההעדפות שלך. הם עוזרים לסוכני קידוד AI ללמוד איך אתה כותב קוד, כך שיוכלו להתאים למוסכמות, לדפוסים ולטעם שלך.", "createInfo": "פלטפורמה זו לא מריצה פרומפטים — היא ספרייה קהילתית לשיתוף וגילוי פרומפטים של AI. צור את הפרומפט שלך כאן, ואחרים יוכלו להעתיק ולהשתמש בו בכלי ה-AI המועדפים עליהם כמו ChatGPT, Claude, Gemini או כל LLM אחר. הקהילה יכולה גם להגיב על הפרומפטים שלך ולהציע שיפורים דרך בקשות שינוי.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "אודיו", "structured": "מובנה", "document": "מסמך", - "skill": "מיומנות" + "skill": "מיומנות", + "taste": "Taste" }, "inputType": "פרומפט משתמש", "outputType": "תגובת AI", @@ -199,7 +203,8 @@ "inputTypes": { "text": "פרומפט טקסט", "structured": "מובנה (JSON/YAML)", - "skill": "מיומנות (Agent Skills)" + "skill": "מיומנות (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "טקסט", diff --git a/messages/it.json b/messages/it.json index 2c4a74a2..a872c83c 100644 --- a/messages/it.json +++ b/messages/it.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmaster", "prompts": "Prompt", "skills": "Competenze", + "tastes": "Tastes", "workflows": "Flussi di lavoro", "categories": "Categorie", "tags": "Tag", @@ -107,7 +108,9 @@ "title": "Prompt", "create": "Crea Prompt", "createSkill": "Crea Competenza", + "createTaste": "Crea Taste", "skillsDescription": "Le Competenze dell'Agente sono prompt multi-file che danno agli agenti AI capacità specializzate. Includono istruzioni, configurazioni e file di supporto che possono essere utilizzati con Claude, Cursor, Windsurf e altri assistenti di codifica AI.", + "tastesDescription": "I Tastes sono singoli file markdown che definiscono il tuo stile di codifica e le tue preferenze. Aiutano gli agenti di codifica AI a imparare come scrivi codice, così possono adattarsi alle tue convenzioni, pattern e gusto.", "createInfo": "Questa piattaforma non esegue i prompt — è una libreria comunitaria per condividere e scoprire prompt AI. Crea il tuo prompt qui, e altri potranno copiarlo e usarlo nei loro strumenti AI preferiti come ChatGPT, Claude, Gemini o qualsiasi altro LLM. La community può anche commentare i tuoi prompt e suggerire miglioramenti tramite richieste di modifica.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "Audio", "structured": "Strutturato", "document": "Documento", - "skill": "Abilità" + "skill": "Abilità", + "taste": "Taste" }, "inputType": "Prompt Utente", "outputType": "Risposta AI", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Prompt Testuale", "structured": "Strutturato (JSON/YAML)", - "skill": "Abilità (Agent Skills)" + "skill": "Abilità (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Testo", diff --git a/messages/ja.json b/messages/ja.json index 2a73c1a5..6c4ea875 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "プロンプト", "skills": "スキル", + "tastes": "Tastes", "workflows": "ワークフロー", "categories": "カテゴリー", "tags": "タグ", @@ -107,7 +108,9 @@ "title": "プロンプト", "create": "プロンプトを作成", "createSkill": "スキルを作成", + "createTaste": "Tasteを作成", "skillsDescription": "エージェントスキルは、AIエージェントに専門的な機能を与えるマルチファイルプロンプトです。Claude、Cursor、Windsurf、その他のAIコーディングアシスタントで使用できる指示、設定、サポートファイルが含まれています。", + "tastesDescription": "Tastesは、コーディングスタイルと好みを定義する単一のマークダウンファイルです。AIコーディングエージェントがあなたのコードの書き方を学習し、規約、パターン、テイストに合わせることができます。", "createInfo": "このプラットフォームはプロンプトを実行しません — AIプロンプトを共有・発見するためのコミュニティライブラリです。ここでプロンプトを作成すると、他のユーザーがChatGPT、Claude、Geminiなどのお気に入りのAIツールでコピーして使用できます。コミュニティはあなたのプロンプトにコメントしたり、変更リクエストを通じて改善を提案することもできます。", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "音声", "structured": "構造化", "document": "ドキュメント", - "skill": "スキル" + "skill": "スキル", + "taste": "Taste" }, "inputType": "ユーザープロンプト", "outputType": "AI応答", @@ -199,7 +203,8 @@ "inputTypes": { "text": "テキストプロンプト", "structured": "構造化 (JSON/YAML)", - "skill": "スキル (Agent Skills)" + "skill": "スキル (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "テキスト", diff --git a/messages/ko.json b/messages/ko.json index 6b8414d2..a259de87 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -39,6 +39,7 @@ "promptmasters": "프롬프트마스터", "prompts": "프롬프트", "skills": "스킬", + "tastes": "Tastes", "workflows": "워크플로우", "categories": "카테고리", "tags": "태그", @@ -107,7 +108,9 @@ "title": "프롬프트", "create": "프롬프트 만들기", "createSkill": "스킬 만들기", + "createTaste": "Taste 만들기", "skillsDescription": "에이전트 스킬은 AI 에이전트에게 전문 기능을 제공하는 멀티 파일 프롬프트입니다. Claude, Cursor, Windsurf 및 기타 AI 코딩 어시스턴트와 함께 사용할 수 있는 지침, 구성 및 지원 파일이 포함되어 있습니다.", + "tastesDescription": "Tastes는 코딩 스타일과 선호도를 정의하는 단일 마크다운 파일입니다. AI 코딩 에이전트가 코드 작성 방식을 학습하여 규칙, 패턴 및 취향에 맞출 수 있도록 도와줍니다.", "createInfo": "이 플랫폼은 프롬프트를 실행하지 않습니다 — AI 프롬프트를 공유하고 발견하는 커뮤니티 라이브러리입니다. 여기서 프롬프트를 만들면 다른 사용자들이 ChatGPT, Claude, Gemini 등 선호하는 AI 도구에서 복사하여 사용할 수 있습니다. 커뮤니티는 프롬프트에 댓글을 달고 변경 요청을 통해 개선 사항을 제안할 수도 있습니다.", "hfDataStudio": { "button": "HF 데이터 스튜디오", @@ -189,7 +192,8 @@ "audio": "오디오", "structured": "구조화", "document": "문서", - "skill": "스킬" + "skill": "스킬", + "taste": "Taste" }, "inputType": "사용자 프롬프트", "outputType": "AI 응답", @@ -199,7 +203,8 @@ "inputTypes": { "text": "텍스트 프롬프트", "structured": "구조화 (JSON/YAML)", - "skill": "스킬 (Agent Skills)" + "skill": "스킬 (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "텍스트", diff --git a/messages/nl.json b/messages/nl.json index 3e80eae9..a33458bc 100644 --- a/messages/nl.json +++ b/messages/nl.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "Prompts", "skills": "Vaardigheden", + "tastes": "Tastes", "workflows": "Workflows", "categories": "Categorieën", "tags": "Tags", @@ -107,7 +108,9 @@ "title": "Prompts", "create": "Prompt aanmaken", "createSkill": "Vaardigheid aanmaken", + "createTaste": "Taste aanmaken", "skillsDescription": "Agent Vaardigheden zijn multi-bestand prompts die AI-agenten gespecialiseerde mogelijkheden geven. Ze bevatten instructies, configuraties en ondersteunende bestanden die kunnen worden gebruikt met Claude, Cursor, Windsurf en andere AI-coderingsassistenten.", + "tastesDescription": "Tastes zijn enkele markdown-bestanden die je codeerstijl en voorkeuren definiëren. Ze helpen AI-coderingsagenten te leren hoe je code schrijft, zodat ze je conventies, patronen en smaak kunnen overnemen.", "createInfo": "Dit platform voert geen prompts uit — het is een door de community beheerde bibliotheek voor het delen en ontdekken van AI-prompts. Maak hier je prompt aan, en anderen kunnen het kopiëren en gebruiken in hun favoriete AI-tools zoals ChatGPT, Claude, Gemini of andere LLM's. De community kan ook reageren op je prompts en verbeteringen voorstellen via wijzigingsverzoeken.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "Audio", "structured": "Gestructureerd", "document": "Document", - "skill": "Vaardigheid" + "skill": "Vaardigheid", + "taste": "Taste" }, "inputType": "Gebruikersprompt", "outputType": "AI-antwoord", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Tekstprompt", "structured": "Gestructureerd (JSON/YAML)", - "skill": "Vaardigheid (Agent Skills)" + "skill": "Vaardigheid (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Tekst", diff --git a/messages/pt.json b/messages/pt.json index ae0063bf..f0d8af1d 100644 --- a/messages/pt.json +++ b/messages/pt.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "Prompts", "skills": "Habilidades", + "tastes": "Tastes", "workflows": "Fluxos de trabalho", "categories": "Categorias", "tags": "Tags", @@ -107,7 +108,9 @@ "title": "Prompts", "create": "Criar Prompt", "createSkill": "Criar Habilidade", + "createTaste": "Criar Taste", "skillsDescription": "Habilidades de Agente são prompts multi-arquivo que dão aos agentes de IA capacidades especializadas. Incluem instruções, configurações e arquivos de suporte que podem ser usados com Claude, Cursor, Windsurf e outros assistentes de codificação de IA.", + "tastesDescription": "Tastes são arquivos markdown individuais que definem seu estilo de codificação e preferências. Ajudam os agentes de codificação de IA a aprender como você escreve código, para que possam corresponder às suas convenções, padrões e gosto.", "createInfo": "Esta plataforma não executa prompts — é uma biblioteca comunitária para compartilhar e descobrir prompts de IA. Crie seu prompt aqui, e outros poderão copiá-lo e usá-lo em suas ferramentas de IA favoritas como ChatGPT, Claude, Gemini ou qualquer outro LLM. A comunidade também pode comentar seus prompts e sugerir melhorias através de solicitações de alteração.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "Áudio", "structured": "Estruturado", "document": "Documento", - "skill": "Habilidade" + "skill": "Habilidade", + "taste": "Taste" }, "inputType": "Prompt do Usuário", "outputType": "Resposta da IA", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Prompt de Texto", "structured": "Estruturado (JSON/YAML)", - "skill": "Habilidade (Agent Skills)" + "skill": "Habilidade (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Texto", diff --git a/messages/ru.json b/messages/ru.json index 0e552ffc..ef9de248 100644 --- a/messages/ru.json +++ b/messages/ru.json @@ -39,6 +39,7 @@ "promptmasters": "Мастера промптов", "prompts": "Промпты", "skills": "Навыки", + "tastes": "Tastes", "workflows": "Рабочие процессы", "categories": "Категории", "tags": "Теги", @@ -107,7 +108,9 @@ "title": "Промпты", "create": "Создать промпт", "createSkill": "Создать навык", + "createTaste": "Создать Taste", "skillsDescription": "Навыки агента — это многофайловые промпты, которые дают AI-агентам специализированные возможности. Они включают инструкции, конфигурации и вспомогательные файлы, которые можно использовать с Claude, Cursor, Windsurf и другими AI-помощниками для программирования.", + "tastesDescription": "Tastes — это отдельные файлы markdown, которые определяют ваш стиль программирования и предпочтения. Они помогают AI-агентам для программирования изучить, как вы пишете код, чтобы они могли соответствовать вашим соглашениям, шаблонам и вкусу.", "createInfo": "Эта платформа не выполняет промпты — это библиотека сообщества для обмена и поиска AI-промптов. Создайте свой промпт здесь, и другие смогут скопировать и использовать его в своих любимых AI-инструментах, таких как ChatGPT, Claude, Gemini или любой другой LLM. Сообщество также может комментировать ваши промпты и предлагать улучшения через запросы на изменение.", "hfDataStudio": { "button": "HF Data Studio", @@ -189,7 +192,8 @@ "audio": "Аудио", "structured": "Структурированный", "document": "Документ", - "skill": "Навык" + "skill": "Навык", + "taste": "Taste" }, "inputType": "Промпт пользователя", "outputType": "Ответ ИИ", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Текстовый промпт", "structured": "Структурированный (JSON/YAML)", - "skill": "Навык (Agent Skills)" + "skill": "Навык (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Текст", diff --git a/messages/tr.json b/messages/tr.json index 9d5d9dcc..89bf4d42 100644 --- a/messages/tr.json +++ b/messages/tr.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "Promptlar", "skills": "Yetenekler", + "tastes": "Tastes", "workflows": "Akışlar", "categories": "Kategoriler", "tags": "Etiketler", @@ -107,7 +108,9 @@ "title": "Promptlar", "create": "Prompt Oluştur", "createSkill": "Yetenek Oluştur", + "createTaste": "Taste Oluştur", "skillsDescription": "Ajan Yetenekleri, AI ajanlara uzmanlaşmış yetenekler veren çok dosyalı promptlardır. Claude, Cursor, Windsurf ve diğer AI kodlama asistanlarıyla kullanılabilecek talimatlar, yapılandırmalar ve destek dosyaları içerirler.", + "tastesDescription": "Tastes, kodlama tarzınızı ve tercihlerinizi tanımlayan tek markdown dosyalarıdır. AI kodlama ajanlarının kodunuzu nasıl yazdığınızı öğrenmesine yardımcı olur, böylece kurallarınıza, kalıplarınıza ve zevkinize uyum sağlayabilirler.", "createInfo": "Bu platform promptları çalıştırmaz — AI promptlarını paylaşmak ve keşfetmek için topluluk odaklı bir kütüphanedir. Promptunuzu burada oluşturun, diğerleri ChatGPT, Claude, Gemini veya başka herhangi bir LLM gibi tercih ettikleri AI araçlarında kopyalayıp kullanabilir. Topluluk ayrıca promptlarınıza yorum yapabilir ve değişiklik istekleri aracılığıyla iyileştirmeler önerebilir.", "hfDataStudio": { "button": "HF Veri Stüdyosu", @@ -189,7 +192,8 @@ "audio": "Ses", "structured": "Yapılandırılmış", "document": "Doküman", - "skill": "Yetenek" + "skill": "Yetenek", + "taste": "Taste" }, "inputType": "Kullanıcı Promptu", "outputType": "AI Yanıtı", @@ -199,7 +203,8 @@ "inputTypes": { "text": "Metin Promptu", "structured": "Yapılandırılmış (JSON/YAML)", - "skill": "Yetenek (Agent Skills)" + "skill": "Yetenek (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "Metin", diff --git a/messages/zh.json b/messages/zh.json index 48c40c91..ae5a3e45 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -39,6 +39,7 @@ "promptmasters": "Promptmasters", "prompts": "提示词", "skills": "技能", + "tastes": "Tastes", "workflows": "工作流程", "categories": "分类", "tags": "标签", @@ -107,7 +108,9 @@ "title": "提示词", "create": "创建提示词", "createSkill": "创建技能", + "createTaste": "创建 Taste", "skillsDescription": "智能体技能是多文件提示词,可为AI智能体提供专业能力。它们包含指令、配置和支持文件,可与Claude、Cursor、Windsurf及其他AI编程助手配合使用。", + "tastesDescription": "Tastes 是定义你编码风格和偏好的单个 markdown 文件。它们帮助 AI 编码代理学习你的代码编写方式,从而匹配你的惯例、模式和品味。", "createInfo": "本平台不运行或执行提示词——这是一个社区驱动的AI提示词分享和发现库。在这里创建您的提示词,其他人可以复制并在他们喜欢的AI工具中使用,如ChatGPT、Claude、Gemini或任何其他LLM。社区还可以评论您的提示词,并通过变更请求提出改进建议。", "hfDataStudio": { "button": "HF 数据工作室", @@ -189,7 +192,8 @@ "audio": "音频", "structured": "结构化", "document": "文档", - "skill": "技能" + "skill": "技能", + "taste": "Taste" }, "inputType": "用户提示词", "outputType": "AI 响应", @@ -199,7 +203,8 @@ "inputTypes": { "text": "文本提示词", "structured": "结构化 (JSON/YAML)", - "skill": "技能 (Agent Skills)" + "skill": "技能 (Agent Skills)", + "taste": "Taste (Coding Taste)" }, "outputTypes": { "text": "文本", diff --git a/prisma/migrations/20260302194500_add_taste_prompt_type/migration.sql b/prisma/migrations/20260302194500_add_taste_prompt_type/migration.sql new file mode 100644 index 00000000..a5583060 --- /dev/null +++ b/prisma/migrations/20260302194500_add_taste_prompt_type/migration.sql @@ -0,0 +1,2 @@ +-- AlterEnum +ALTER TYPE "PromptType" ADD VALUE 'TASTE'; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 6ef020de..7303ba36 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -409,6 +409,7 @@ enum PromptType { AUDIO STRUCTURED SKILL + TASTE } enum StructuredFormat { diff --git a/prompts.config.ts b/prompts.config.ts index 1a06770c..c65a3a77 100644 --- a/prompts.config.ts +++ b/prompts.config.ts @@ -84,7 +84,7 @@ export default defineConfig({ { name: "Sentry", className: 'py-1', logo: '/sponsors/sentry.svg', darkLogo: '/sponsors/sentry-dark.svg', url: "https://sentry.io/?utm_source=prompts.chat" }, { name: "MitteAI", logo: '/sponsors/mitte.svg', darkLogo: '/sponsors/mitte-dark.svg', url: "https://mitte.ai/?utm_source=prompts.chat" }, { name: "eachlabs", className: 'py-[6px]', logo: '/sponsors/eachlabs.png', darkLogo: '/sponsors/eachlabs-dark.png', url: "https://www.eachlabs.ai/?utm_source=promptschat&utm_medium=referral" }, - { name: "warp.dev", className: 'py-2', logo: '/sponsors/warp.svg', url: "https://warp.dev/?utm_source=prompts.chat" }, + { name: "CommandCode", className: 'py-1', logo: '/sponsors/commandcode.svg', darkLogo: '/sponsors/commandcode-dark.svg', url: "https://commandcode.ai/?utm_source=prompts.chat" }, ], }, }, diff --git a/public/sponsors/commandcode-dark.svg b/public/sponsors/commandcode-dark.svg new file mode 100644 index 00000000..4611272e --- /dev/null +++ b/public/sponsors/commandcode-dark.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/public/sponsors/commandcode.svg b/public/sponsors/commandcode.svg new file mode 100644 index 00000000..ab1ca2a2 --- /dev/null +++ b/public/sponsors/commandcode.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/src/app/api/prompts/[id]/route.ts b/src/app/api/prompts/[id]/route.ts index 592dcb0c..940b1fae 100644 --- a/src/app/api/prompts/[id]/route.ts +++ b/src/app/api/prompts/[id]/route.ts @@ -11,7 +11,7 @@ const updatePromptSchema = z.object({ title: z.string().min(1).max(200).optional(), description: z.string().max(500).optional(), content: z.string().min(1).optional(), - type: z.enum(["TEXT", "IMAGE", "VIDEO", "AUDIO", "SKILL"]).optional(), // Output type or SKILL + type: z.enum(["TEXT", "IMAGE", "VIDEO", "AUDIO", "SKILL", "TASTE"]).optional(), // Output type, SKILL, or TASTE structuredFormat: z.enum(["JSON", "YAML"]).optional().nullable(), categoryId: z.string().optional().nullable(), tagIds: z.array(z.string()).optional(), diff --git a/src/app/api/prompts/route.ts b/src/app/api/prompts/route.ts index 26b32814..5ec5dbf4 100644 --- a/src/app/api/prompts/route.ts +++ b/src/app/api/prompts/route.ts @@ -13,7 +13,7 @@ const promptSchema = z.object({ title: z.string().min(1).max(200), description: z.string().max(500).optional(), content: z.string().min(1), - type: z.enum(["TEXT", "IMAGE", "VIDEO", "AUDIO", "SKILL"]), // Output type or SKILL + type: z.enum(["TEXT", "IMAGE", "VIDEO", "AUDIO", "SKILL", "TASTE"]), // Output type, SKILL, or TASTE structuredFormat: z.enum(["JSON", "YAML"]).nullish(), // Input type indicator categoryId: z.string().optional(), tagIds: z.array(z.string()), diff --git a/src/app/prompts/[id]/edit/page.tsx b/src/app/prompts/[id]/edit/page.tsx index 77f80d55..ce96645b 100644 --- a/src/app/prompts/[id]/edit/page.tsx +++ b/src/app/prompts/[id]/edit/page.tsx @@ -87,7 +87,7 @@ export default async function EditPromptPage({ params }: EditPromptPageProps) { title: prompt.title, description: prompt.description || "", content: prompt.content, - type: ((prompt.type === "IMAGE" || prompt.type === "VIDEO" || prompt.type === "AUDIO" || prompt.type === "SKILL") ? prompt.type : "TEXT") as "TEXT" | "IMAGE" | "VIDEO" | "AUDIO" | "SKILL", + type: ((prompt.type === "IMAGE" || prompt.type === "VIDEO" || prompt.type === "AUDIO" || prompt.type === "SKILL" || prompt.type === "TASTE") ? prompt.type : "TEXT") as "TEXT" | "IMAGE" | "VIDEO" | "AUDIO" | "SKILL" | "TASTE", structuredFormat: prompt.structuredFormat ? (prompt.structuredFormat as "JSON" | "YAML") : undefined, categoryId: prompt.categoryId || undefined, tagIds: prompt.tags.map((t) => t.tagId), diff --git a/src/app/prompts/[id]/page.tsx b/src/app/prompts/[id]/page.tsx index beaa5334..82608d89 100644 --- a/src/app/prompts/[id]/page.tsx +++ b/src/app/prompts/[id]/page.tsx @@ -570,6 +570,18 @@ export default async function PromptPage({ params }: PromptPageProps) { promptId={prompt.id} promptSlug={prompt.slug ?? undefined} /> + ) : prompt.type === "TASTE" ? ( + ) : prompt.structuredFormat ? ( )} - {/* Report & Prompt Flow - hide for SKILL type */} - {prompt.type !== "SKILL" && ( + {/* Report & Prompt Flow - hide for SKILL and TASTE types */} + {prompt.type !== "SKILL" && prompt.type !== "TASTE" && ( ; } diff --git a/src/app/tastes/page.tsx b/src/app/tastes/page.tsx new file mode 100644 index 00000000..e03ef6d9 --- /dev/null +++ b/src/app/tastes/page.tsx @@ -0,0 +1,164 @@ +import { Metadata } from "next"; +import Link from "next/link"; +import { getTranslations } from "next-intl/server"; +import { unstable_cache } from "next/cache"; +import { Plus } from "lucide-react"; +import { Button } from "@/components/ui/button"; +import { InfinitePromptList } from "@/components/prompts/infinite-prompt-list"; +import { db } from "@/lib/db"; + +export const metadata: Metadata = { + title: "Tastes", + description: "Browse and discover coding taste profiles", +}; + +// Query for tastes list (cached) +function getCachedTastes( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + orderBy: any, + perPage: number, + searchQuery?: string +) { + const cacheKey = JSON.stringify({ orderBy, perPage, searchQuery }); + + return unstable_cache( + async () => { + const where: Record = { + type: "TASTE", + isPrivate: false, + isUnlisted: false, + deletedAt: null, + }; + + if (searchQuery) { + where.OR = [ + { title: { contains: searchQuery, mode: "insensitive" } }, + { content: { contains: searchQuery, mode: "insensitive" } }, + { description: { contains: searchQuery, mode: "insensitive" } }, + ]; + } + + const [tastesRaw, totalCount] = await Promise.all([ + db.prompt.findMany({ + where, + orderBy, + skip: 0, + take: perPage, + include: { + author: { + select: { + id: true, + name: true, + username: true, + avatar: true, + verified: true, + }, + }, + category: { + include: { + parent: { + select: { id: true, name: true, slug: true }, + }, + }, + }, + tags: { + include: { + tag: true, + }, + }, + contributors: { + select: { + id: true, + username: true, + name: true, + avatar: true, + }, + }, + _count: { + select: { + votes: true, + contributors: true, + outgoingConnections: { where: { label: { not: "related" } } }, + incomingConnections: { where: { label: { not: "related" } } }, + }, + }, + }, + }), + db.prompt.count({ where }), + ]); + + return { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + tastes: tastesRaw.map((p: any) => ({ + ...p, + voteCount: p._count.votes, + contributorCount: p._count.contributors, + contributors: p.contributors, + })), + total: totalCount, + }; + }, + ["tastes", cacheKey], + { tags: ["prompts"] } + )(); +} + +interface TastesPageProps { + searchParams: Promise<{ + q?: string; + sort?: string; + }>; +} + +export default async function TastesPage({ searchParams }: TastesPageProps) { + const t = await getTranslations("prompts"); + const tNav = await getTranslations("nav"); + const tSearch = await getTranslations("search"); + const params = await searchParams; + + const perPage = 24; + + // Build order by clause + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let orderBy: any = { createdAt: "desc" }; + if (params.sort === "oldest") { + orderBy = { createdAt: "asc" }; + } else if (params.sort === "upvotes") { + orderBy = { votes: { _count: "desc" } }; + } + + const result = await getCachedTastes(orderBy, perPage, params.q); + const tastes = result.tastes; + const total = result.total; + + return ( +
+
+
+

{tNav("tastes")}

+ {tSearch("found", { count: total })} +
+ +
+ +

+ {t("tastesDescription")} +

+ + +
+ ); +} diff --git a/src/components/layout/header.tsx b/src/components/layout/header.tsx index c03d1399..75410878 100644 --- a/src/components/layout/header.tsx +++ b/src/components/layout/header.tsx @@ -213,6 +213,13 @@ export function Header({ authProvider = "credentials", allowRegistration = true > {t("nav.skills")} + setMobileMenuOpen(false)} + className="flex items-center gap-3 px-3 py-2.5 rounded-md text-sm font-medium text-muted-foreground hover:text-foreground hover:bg-accent transition-colors" + > + {t("nav.tastes")} + setMobileMenuOpen(false)} @@ -370,13 +377,19 @@ export function Header({ authProvider = "credentials", allowRegistration = true {t("nav.skills")} + + {t("nav.tastes")} + {t("nav.workflows")} @@ -399,7 +412,7 @@ export function Header({ authProvider = "credentials", allowRegistration = true > {t("nav.promptmasters")} - {/* Three-dot dropdown for Categories, Tags, Promptmasters on md screens */} + {/* Three-dot dropdown for collapsed nav items */} + + + {t("nav.skills")} + + + + + {t("nav.tastes")} + + + + + {t("nav.workflows")} + + + {t("nav.categories")} diff --git a/src/components/prompts/download-prompt-dropdown.tsx b/src/components/prompts/download-prompt-dropdown.tsx index dada9ec6..f05f88b4 100644 --- a/src/components/prompts/download-prompt-dropdown.tsx +++ b/src/components/prompts/download-prompt-dropdown.tsx @@ -24,6 +24,7 @@ export function DownloadPromptDropdown({ promptId, promptSlug, promptType }: Dow const [copiedFormat, setCopiedFormat] = useState<"md" | "yml" | null>(null); const isSkill = promptType === "SKILL"; + const isTaste = promptType === "TASTE"; const getFileName = (format: "md" | "yml") => { const base = promptSlug ? `${promptId}_${promptSlug}` : promptId; @@ -97,6 +98,29 @@ export function DownloadPromptDropdown({ promptId, promptSlug, promptType }: Dow } }; + const handleDownloadTasteMd = async () => { + const url = `/api/prompts/${promptSlug ? `${promptId}_${promptSlug}` : promptId}/raw`; + try { + const response = await fetch(url); + if (!response.ok) throw new Error("Failed to fetch"); + const content = await response.text(); + + const blob = new Blob([content], { type: "text/plain;charset=utf-8" }); + const downloadUrl = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = downloadUrl; + a.download = "taste.md"; + document.body.appendChild(a); + a.click(); + document.body.removeChild(a); + URL.revokeObjectURL(downloadUrl); + + toast.success(t("downloadStarted")); + } catch { + toast.error(t("downloadFailed")); + } + }; + // For SKILL type, show a simple button that downloads .skill zip if (isSkill) { return ( @@ -107,6 +131,16 @@ export function DownloadPromptDropdown({ promptId, promptSlug, promptType }: Dow ); } + // For TASTE type, show a simple button that downloads taste.md + if (isTaste) { + return ( + + ); + } + return ( diff --git a/src/components/prompts/interactive-prompt-content.tsx b/src/components/prompts/interactive-prompt-content.tsx index 734cc0ba..574008ba 100644 --- a/src/components/prompts/interactive-prompt-content.tsx +++ b/src/components/prompts/interactive-prompt-content.tsx @@ -267,18 +267,19 @@ export function InteractivePromptContent({ setTranslatedContent(translated); }, []); - // Check if this is a SKILL type prompt + // Check if this is a SKILL or TASTE type prompt const isSkill = promptType === "SKILL"; + const isTaste = promptType === "TASTE"; // If no variables, render simple content if (variables.length === 0) { - if (isSkill) { - // SKILL type: render with Monaco editor (read-only markdown) + if (isSkill || isTaste) { + // SKILL/TASTE type: render with Monaco editor (read-only markdown) return (
- {title &&

{title}

} +

{isTaste ? "taste.md" : (title || "SKILL.md")}

string) => z.object({ title: z.string().min(1, t("titleRequired")).max(200), description: z.string().max(500).optional(), content: z.string().min(1, t("contentRequired")), - type: z.enum(["TEXT", "IMAGE", "VIDEO", "AUDIO", "SKILL"]), // Output type or SKILL + type: z.enum(["TEXT", "IMAGE", "VIDEO", "AUDIO", "SKILL", "TASTE"]), // Output type, SKILL, or TASTE structuredFormat: z.enum(["JSON", "YAML"]).optional(), categoryId: z.string().optional(), tagIds: z.array(z.string()), @@ -539,7 +539,7 @@ export function PromptForm({ categories, tags, initialData, initialContributors title: string; description: string; content: string; - type: "TEXT" | "IMAGE" | "VIDEO" | "AUDIO" | "SKILL"; + type: "TEXT" | "IMAGE" | "VIDEO" | "AUDIO" | "SKILL" | "TASTE"; structuredFormat?: "JSON" | "YAML"; categoryId?: string; tagIds: string[]; @@ -1094,7 +1094,7 @@ export function PromptForm({ categories, tags, initialData, initialContributors
{isStructuredInput && ( @@ -1270,8 +1279,8 @@ export function PromptForm({ categories, tags, initialData, initialContributors onConvert={(converted) => form.setValue("content", converted)} /> - {/* Structured format detection warning - hide for SKILL type */} - {promptType !== "SKILL" && ( + {/* Structured format detection warning - hide for SKILL and TASTE types */} + {promptType !== "SKILL" && promptType !== "TASTE" && ( {/* ===== OUTPUT SECTION ===== */} - {promptType === "SKILL" ? ( - /* SKILL type shows a code output preview - code generated BY the skill */ + {(promptType === "SKILL" || promptType === "TASTE") ? ( + /* SKILL/TASTE type shows a code output preview - code generated BY the skill/taste */

{t("outputType")}

@@ -1318,7 +1327,7 @@ export function PromptForm({ categories, tags, initialData, initialContributors {/* Code output content */}
{/* eslint-disable-next-line react/jsx-no-comment-textnodes -- Intentional code preview text */} -
// Code generated by skill...
+
// Code generated by skill, and your taste...
export function handler() {'{'}
return "...";
{'}'}
diff --git a/src/components/prompts/widget-card.tsx b/src/components/prompts/widget-card.tsx index ffa4dd12..5118d320 100644 --- a/src/components/prompts/widget-card.tsx +++ b/src/components/prompts/widget-card.tsx @@ -102,7 +102,7 @@ export function WidgetCard({ prompt }: WidgetCardProps) { {/* Content Preview */}
-
+        
           {prompt.content}
         
diff --git a/src/lib/ai/prompt-builder-tools.ts b/src/lib/ai/prompt-builder-tools.ts index 1afac253..a281d9aa 100644 --- a/src/lib/ai/prompt-builder-tools.ts +++ b/src/lib/ai/prompt-builder-tools.ts @@ -5,7 +5,7 @@ export interface PromptBuilderState { title: string; description: string; content: string; - type: "TEXT" | "IMAGE" | "VIDEO" | "AUDIO" | "STRUCTURED"; + type: "TEXT" | "IMAGE" | "VIDEO" | "AUDIO" | "STRUCTURED" | "TASTE"; structuredFormat?: "JSON" | "YAML"; categoryId?: string; tagIds: string[]; diff --git a/src/lib/plugins/widgets/book.tsx b/src/lib/plugins/widgets/book.tsx index e1d451b0..9ee21ac0 100644 --- a/src/lib/plugins/widgets/book.tsx +++ b/src/lib/plugins/widgets/book.tsx @@ -160,7 +160,11 @@ export const bookWidget: WidgetPlugin = { repeatEvery: 60, maxCount: 4, }, - shouldInject: () => { + shouldInject: (context) => { + // Don't inject on the skills page + if (context.filters?.type === "SKILL") { + return false; + } return true; }, render: () => , diff --git a/src/lib/plugins/widgets/coderabbit.ts b/src/lib/plugins/widgets/coderabbit.ts index 279eadcc..ec7beb9f 100644 --- a/src/lib/plugins/widgets/coderabbit.ts +++ b/src/lib/plugins/widgets/coderabbit.ts @@ -57,6 +57,11 @@ Provide your review in a clear, actionable format with specific line references shouldInject: (context) => { const { filters } = context; + // Don't inject on the skills page + if (filters?.type === "SKILL") { + return false; + } + // Inject when no filters are active if (!filters?.q && !filters?.category && !filters?.tag) { return true; diff --git a/src/lib/plugins/widgets/commandcode.ts b/src/lib/plugins/widgets/commandcode.ts new file mode 100644 index 00000000..237e1145 --- /dev/null +++ b/src/lib/plugins/widgets/commandcode.ts @@ -0,0 +1,56 @@ +import type { WidgetPlugin } from "./types"; + +export const commandcodeWidget: WidgetPlugin = { + id: "commandcode", + name: "CommandCode", + prompts: [ + { + id: "commandcode-coding-agent", + slug: "commandcode-coding-agent-with-taste", + title: "CommandCode — Coding Agent with Taste", + description: "The first frontier coding agent that both builds software and continuously learns your coding taste. Ships full-stack projects, features, fixes bugs, writes tests, and refactors, all while learning how you write code.", + content: `## Install +npm i -g command-code + +## get started +cd my-project +cmd + +## Manage Taste with \`npx taste\` +Share and manage taste profiles like Git. + +## Push project taste to remote +npx taste push --all + +## Pull taste from remote +npx taste pull username/project-name`, + type: "TEXT", + sponsor: { + name: "CommandCode", + logo: "/sponsors/commandcode.svg", + logoDark: "/sponsors/commandcode-dark.svg", + url: "https://commandcode.ai", + }, + tags: ["Coding Agents", "Developer Tools", "AI Agents"], + category: "Development", + actionUrl: "https://commandcode.ai", + actionLabel: "Try CommandCode", + positioning: { + position: 2, + mode: "repeat", + repeatEvery: 50, + maxCount: 3, + }, + shouldInject: (context) => { + const { filters } = context; + + // Only inject on the skills page (type=SKILL) + if (filters?.type === "SKILL") { + return true; + } + + return false; + }, + }, + ], +}; diff --git a/src/lib/plugins/widgets/index.ts b/src/lib/plugins/widgets/index.ts index 5dd91114..fca9a0da 100644 --- a/src/lib/plugins/widgets/index.ts +++ b/src/lib/plugins/widgets/index.ts @@ -2,6 +2,7 @@ import type { WidgetPlugin, WidgetPrompt, WidgetContext } from "./types"; import { coderabbitWidget } from "./coderabbit"; import { bookWidget } from "./book"; import { textreamWidget } from "./textream"; +import { commandcodeWidget } from "./commandcode"; export * from "./types"; @@ -10,6 +11,7 @@ const widgetPlugins: WidgetPlugin[] = [ coderabbitWidget, bookWidget, textreamWidget, + commandcodeWidget, ]; /** diff --git a/src/lib/plugins/widgets/textream.tsx b/src/lib/plugins/widgets/textream.tsx index 316435ba..d7e306c1 100644 --- a/src/lib/plugins/widgets/textream.tsx +++ b/src/lib/plugins/widgets/textream.tsx @@ -122,6 +122,11 @@ export const textreamWidget: WidgetPlugin = { shouldInject: (context) => { const { filters } = context; + // Don't inject on the skills page + if (filters?.type === "SKILL") { + return false; + } + // Show when no filters active if (!filters?.q && !filters?.category && !filters?.tag) { return true;