diff --git a/messages/ar.json b/messages/ar.json index 8a316410..7bb2d2e5 100644 --- a/messages/ar.json +++ b/messages/ar.json @@ -38,7 +38,8 @@ "feed": "الخلاصة", "promptmasters": "Promptmasters", "prompts": "الأوامر", - "categories": "التصنيفات", + "skills": "المهارات", + "categories": "الفئات", "tags": "الوسوم", "settings": "الإعدادات", "admin": "الإدارة", @@ -102,6 +103,8 @@ "prompts": { "title": "الأوامر", "create": "إنشاء أمر", + "createSkill": "إنشاء مهارة", + "skillsDescription": "مهارات الوكيل هي أوامر متعددة الملفات تمنح وكلاء الذكاء الاصطناعي قدرات متخصصة. تتضمن تعليمات وإعدادات وملفات داعمة يمكن استخدامها مع Claude وCursor وWindsurf ومساعدي البرمجة الآخرين.", "createInfo": "هذه المنصة لا تقوم بتشغيل أو تنفيذ الأوامر — إنها مكتبة مجتمعية لمشاركة واكتشاف أوامر الذكاء الاصطناعي. أنشئ أمرك هنا، ويمكن للآخرين نسخه واستخدامه في أدوات الذكاء الاصطناعي المفضلة لديهم مثل ChatGPT و Claude و Gemini أو أي نموذج لغوي آخر. يمكن للمجتمع أيضاً التعليق على أوامرك واقتراح تحسينات من خلال طلبات التغيير.", "hfDataStudio": { "button": "استوديو بيانات HF", @@ -244,7 +247,29 @@ "run": "تشغيل", "downloadMarkdown": "تحميل MD", "downloadYaml": "تحميل YAML", - "downloadSkillMd": "تحميل SKILL.md", + "downloadSkillMd": "تنزيل SKILL.md", + "downloadSkill": "تنزيل مهارة", + "skillFiles": "ملفات المهارة", + "copy": "نسخ", + "download": "تحميل", + "addFile": "إضافة ملف", + "deleteFile": "حذف ملف", + "file": "ملف", + "files": "ملفات", + "addNewFile": "إضافة ملف جديد", + "addNewFileDescription": "أدخل اسم الملف مع الامتداد. استخدم / للمجلدات (مثل config.json, src/utils.ts)", + "deleteFileConfirm": "حذف الملف؟", + "deleteFileDescription": "هل أنت متأكد من حذف \"{filename}\"؟ لا يمكن التراجع عن هذا الإجراء.", + "validation": { + "filenameEmpty": "اسم الملف لا يمكن أن يكون فارغاً", + "filenameInvalidChars": "اسم الملف يحتوي على أحرف غير صالحة", + "pathStartEndSlash": "المسار لا يمكن أن يبدأ أو ينتهي بـ /", + "pathConsecutiveSlashes": "المسار لا يمكن أن يحتوي على شرطات متتالية", + "pathContainsDotDot": "المسار لا يمكن أن يحتوي على ..", + "filenameReserved": "SKILL.md موجود بالفعل", + "filenameDuplicate": "ملف بهذا الاسم موجود بالفعل", + "pathTooLong": "المسار طويل جداً (الحد الأقصى 200 حرف)" + }, "copyMarkdownUrl": "نسخ رابط MD", "copyYamlUrl": "نسخ رابط YAML", "downloadStarted": "بدأ التحميل", @@ -366,6 +391,9 @@ "submit": "إرسال طلب التغيير", "created": "تم إرسال طلب التغيير بنجاح", "status": "الحالة", + "pending": "قيد الانتظار", + "approved": "مقبول", + "rejected": "مرفوض", "approve": "قبول", "reject": "رفض", "reviewNote": "ملاحظة المراجعة", diff --git a/messages/az.json b/messages/az.json index aded4f14..f7b4a71b 100644 --- a/messages/az.json +++ b/messages/az.json @@ -38,6 +38,7 @@ "feed": "Lent", "promptmasters": "Promptmasterlər", "prompts": "Promptlar", + "skills": "Bacarıqlar", "categories": "Kateqoriyalar", "tags": "Etiketlər", "settings": "Parametrlər", @@ -102,6 +103,8 @@ "prompts": { "title": "Promptlar", "create": "Prompt Yarat", + "createSkill": "Bacarıq 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.", "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", @@ -232,6 +235,28 @@ "downloadMarkdown": "MD Yüklə", "downloadYaml": "YAML Yüklə", "downloadSkillMd": "SKILL.md Yüklə", + "downloadSkill": ".skill Yüklə", + "skillFiles": "Bacarıq Faylları", + "copy": "Kopyala", + "download": "Yüklə", + "addFile": "Fayl Əlavə Et", + "deleteFile": "Faylı Sil", + "file": "fayl", + "files": "fayllar", + "addNewFile": "Yeni Fayl Əlavə Et", + "addNewFileDescription": "Uzantı ilə fayl adını daxil edin. Qovluqlar üçün / istifadə edin (məs., config.json, src/utils.ts)", + "deleteFileConfirm": "Fayl Silinsin?", + "deleteFileDescription": "\"{filename}\" faylını silmək istədiyinizə əminsiniz? Bu əməliyyat geri qaytarıla bilməz.", + "validation": { + "filenameEmpty": "Fayl adı boş ola bilməz", + "filenameInvalidChars": "Fayl adında yanlış simvollar var", + "pathStartEndSlash": "Yol / ilə başlaya və ya bitə bilməz", + "pathConsecutiveSlashes": "Yolda ardıcıl xətt ola bilməz", + "pathContainsDotDot": "Yolda .. ola bilməz", + "filenameReserved": "SKILL.md artıq mövcuddur", + "filenameDuplicate": "Bu adda fayl artıq mövcuddur", + "pathTooLong": "Yol çox uzundur (maksimum 200 simvol)" + }, "copyMarkdownUrl": "MD Linkini Kopyala", "copyYamlUrl": "YAML Linkini Kopyala", "downloadStarted": "Yükləmə başladı", @@ -366,6 +391,9 @@ "submit": "Dəyişiklik Sorğusu Göndər", "created": "Dəyişiklik sorğusu uğurla göndərildi", "status": "Status", + "pending": "Gözləyir", + "approved": "Təsdiqləndi", + "rejected": "Rədd edildi", "approve": "Təsdiq et", "reject": "Rədd et", "reviewNote": "Nəzərdən Keçirmə Qeydi", diff --git a/messages/de.json b/messages/de.json index 4b36b143..b70e3580 100644 --- a/messages/de.json +++ b/messages/de.json @@ -38,6 +38,7 @@ "feed": "Feed", "promptmasters": "Promptmasters", "prompts": "Prompts", + "skills": "Skills", "categories": "Kategorien", "tags": "Tags", "settings": "Einstellungen", @@ -102,6 +103,8 @@ "prompts": { "title": "Prompts", "create": "Prompt erstellen", + "createSkill": "Skill 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.", "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", @@ -232,6 +235,28 @@ "downloadMarkdown": "MD herunterladen", "downloadYaml": "YAML herunterladen", "downloadSkillMd": "SKILL.md herunterladen", + "downloadSkill": ".skill herunterladen", + "skillFiles": "Skill-Dateien", + "copy": "Kopieren", + "download": "Herunterladen", + "addFile": "Datei hinzufügen", + "deleteFile": "Datei löschen", + "file": "Datei", + "files": "Dateien", + "addNewFile": "Neue Datei hinzufügen", + "addNewFileDescription": "Geben Sie einen Dateinamen mit Erweiterung ein. Verwenden Sie / für Verzeichnisse (z.B. config.json, src/utils.ts)", + "deleteFileConfirm": "Datei löschen?", + "deleteFileDescription": "Sind Sie sicher, dass Sie \"{filename}\" löschen möchten? Diese Aktion kann nicht rückgängig gemacht werden.", + "validation": { + "filenameEmpty": "Dateiname darf nicht leer sein", + "filenameInvalidChars": "Dateiname enthält ungültige Zeichen", + "pathStartEndSlash": "Pfad darf nicht mit / beginnen oder enden", + "pathConsecutiveSlashes": "Pfad darf keine aufeinanderfolgenden Schrägstriche enthalten", + "pathContainsDotDot": "Pfad darf kein .. enthalten", + "filenameReserved": "SKILL.md existiert bereits", + "filenameDuplicate": "Eine Datei mit diesem Namen existiert bereits", + "pathTooLong": "Pfad ist zu lang (max. 200 Zeichen)" + }, "copyMarkdownUrl": "MD-Link kopieren", "copyYamlUrl": "YAML-Link kopieren", "downloadStarted": "Download gestartet", @@ -366,6 +391,9 @@ "submit": "Änderungsanfrage absenden", "created": "Änderungsanfrage erfolgreich eingereicht", "status": "Status", + "pending": "Ausstehend", + "approved": "Genehmigt", + "rejected": "Abgelehnt", "approve": "Genehmigen", "reject": "Ablehnen", "reviewNote": "Überprüfungsnotiz", diff --git a/messages/el.json b/messages/el.json index 9eaba0ad..e122179d 100644 --- a/messages/el.json +++ b/messages/el.json @@ -38,6 +38,7 @@ "feed": "Ροή", "promptmasters": "Promptmasters", "prompts": "Prompts", + "skills": "Δεξιότητες", "categories": "Κατηγορίες", "tags": "Ετικέτες", "settings": "Ρυθμίσεις", @@ -102,6 +103,8 @@ "prompts": { "title": "Prompts", "create": "Δημιουργία Prompt", + "createSkill": "Δημιουργία Δεξιότητας", + "skillsDescription": "Οι Δεξιότητες Πράκτορα είναι prompts πολλαπλών αρχείων που δίνουν στους AI πράκτορες εξειδικευμένες δυνατότητες. Περιλαμβάνουν οδηγίες, ρυθμίσεις και υποστηρικτικά αρχεία που μπορούν να χρησιμοποιηθούν με Claude, Cursor, Windsurf και άλλους βοηθούς προγραμματισμού AI.", "createInfo": "Αυτή η πλατφόρμα δεν εκτελεί prompts — είναι μια κοινοτική βιβλιοθήκη για την κοινοποίηση και ανακάλυψη AI prompts. Δημιουργήστε το prompt σας εδώ και άλλοι μπορούν να το αντιγράψουν και να το χρησιμοποιήσουν στα αγαπημένα τους εργαλεία AI όπως ChatGPT, Claude, Gemini ή οποιοδήποτε άλλο LLM. Η κοινότητα μπορεί επίσης να σχολιάσει τα prompts σας και να προτείνει βελτιώσεις μέσω αιτημάτων αλλαγής.", "hfDataStudio": { "button": "HF Data Studio", @@ -232,6 +235,28 @@ "downloadMarkdown": "Λήψη MD", "downloadYaml": "Λήψη YAML", "downloadSkillMd": "Λήψη SKILL.md", + "downloadSkill": "Λήψη .skill", + "skillFiles": "Αρχεία Δεξιοτήτων", + "copy": "Αντιγραφή", + "download": "Λήψη", + "addFile": "Προσθήκη Αρχείου", + "deleteFile": "Διαγραφή Αρχείου", + "file": "αρχείο", + "files": "αρχεία", + "addNewFile": "Προσθήκη Νέου Αρχείου", + "addNewFileDescription": "Εισάγετε ένα όνομα αρχείου με επέκταση. Χρησιμοποιήστε / για καταλόγους (π.χ., config.json, src/utils.ts)", + "deleteFileConfirm": "Διαγραφή Αρχείου;", + "deleteFileDescription": "Είστε βέβαιοι ότι θέλετε να διαγράψετε το \"{filename}\"; Αυτή η ενέργεια δεν μπορεί να αναιρεθεί.", + "validation": { + "filenameEmpty": "Το όνομα αρχείου δεν μπορεί να είναι κενό", + "filenameInvalidChars": "Το όνομα αρχείου περιέχει μη έγκυρους χαρακτήρες", + "pathStartEndSlash": "Η διαδρομή δεν μπορεί να ξεκινά ή να τελειώνει με /", + "pathConsecutiveSlashes": "Η διαδρομή δεν μπορεί να περιέχει διαδοχικές κάθετους", + "pathContainsDotDot": "Η διαδρομή δεν μπορεί να περιέχει ..", + "filenameReserved": "Το SKILL.md υπάρχει ήδη", + "filenameDuplicate": "Ένα αρχείο με αυτό το όνομα υπάρχει ήδη", + "pathTooLong": "Η διαδρομή είναι πολύ μεγάλη (μέγιστο 200 χαρακτήρες)" + }, "copyMarkdownUrl": "Αντιγραφή συνδέσμου MD", "copyYamlUrl": "Αντιγραφή συνδέσμου YAML", "downloadStarted": "Η λήψη ξεκίνησε", @@ -366,6 +391,9 @@ "submit": "Υποβολή αίτησης αλλαγής", "created": "Η αίτηση αλλαγής υποβλήθηκε επιτυχώς", "status": "Κατάσταση", + "pending": "Εκκρεμεί", + "approved": "Εγκρίθηκε", + "rejected": "Απορρίφθηκε", "approve": "Έγκριση", "reject": "Απόρριψη", "reviewNote": "Σημείωση αξιολόγησης", diff --git a/messages/en.json b/messages/en.json index af3f141a..5cc74e7c 100644 --- a/messages/en.json +++ b/messages/en.json @@ -38,6 +38,7 @@ "feed": "Feed", "promptmasters": "Promptmasters", "prompts": "Prompts", + "skills": "Skills", "categories": "Categories", "tags": "Tags", "settings": "Settings", @@ -102,6 +103,8 @@ "prompts": { "title": "Prompts", "create": "Create Prompt", + "createSkill": "Create Skill", + "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.", "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", @@ -232,6 +235,28 @@ "downloadMarkdown": "Download MD", "downloadYaml": "Download YAML", "downloadSkillMd": "Download SKILL.md", + "downloadSkill": "Download .skill", + "skillFiles": "Skill Files", + "copy": "Copy", + "download": "Download", + "addFile": "Add File", + "deleteFile": "Delete File", + "file": "file", + "files": "files", + "addNewFile": "Add New File", + "addNewFileDescription": "Enter a filename with extension. Use / for directories (e.g., config.json, src/utils.ts)", + "deleteFileConfirm": "Delete File?", + "deleteFileDescription": "Are you sure you want to delete \"{filename}\"? This action cannot be undone.", + "validation": { + "filenameEmpty": "Filename cannot be empty", + "filenameInvalidChars": "Filename contains invalid characters", + "pathStartEndSlash": "Path cannot start or end with /", + "pathConsecutiveSlashes": "Path cannot contain consecutive slashes", + "pathContainsDotDot": "Path cannot contain ..", + "filenameReserved": "SKILL.md already exists", + "filenameDuplicate": "A file with this name already exists", + "pathTooLong": "Path is too long (max 200 characters)" + }, "copyMarkdownUrl": "Copy MD Link", "copyYamlUrl": "Copy YAML Link", "downloadStarted": "Download started", @@ -366,6 +391,9 @@ "submit": "Submit Change Request", "created": "Change request submitted successfully", "status": "Status", + "pending": "Pending", + "approved": "Approved", + "rejected": "Rejected", "approve": "Approve", "reject": "Reject", "reviewNote": "Review Note", diff --git a/messages/es.json b/messages/es.json index d13b951b..8518b58c 100644 --- a/messages/es.json +++ b/messages/es.json @@ -38,6 +38,7 @@ "feed": "Feed", "promptmasters": "Promptmasters", "prompts": "Prompts", + "skills": "Habilidades", "categories": "Categorías", "tags": "Etiquetas", "settings": "Configuración", @@ -102,6 +103,8 @@ "prompts": { "title": "Prompts", "create": "Crear Prompt", + "createSkill": "Crear Habilidad", + "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.", "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", @@ -245,6 +248,28 @@ "downloadMarkdown": "Descargar MD", "downloadYaml": "Descargar YAML", "downloadSkillMd": "Descargar SKILL.md", + "downloadSkill": "Descargar .skill", + "skillFiles": "Archivos de Habilidad", + "copy": "Copiar", + "download": "Descargar", + "addFile": "Agregar Archivo", + "deleteFile": "Eliminar Archivo", + "file": "archivo", + "files": "archivos", + "addNewFile": "Agregar Nuevo Archivo", + "addNewFileDescription": "Ingrese un nombre de archivo con extensión. Use / para directorios (ej., config.json, src/utils.ts)", + "deleteFileConfirm": "¿Eliminar Archivo?", + "deleteFileDescription": "¿Está seguro de que desea eliminar \"{filename}\"? Esta acción no se puede deshacer.", + "validation": { + "filenameEmpty": "El nombre del archivo no puede estar vacío", + "filenameInvalidChars": "El nombre del archivo contiene caracteres inválidos", + "pathStartEndSlash": "La ruta no puede comenzar o terminar con /", + "pathConsecutiveSlashes": "La ruta no puede contener barras consecutivas", + "pathContainsDotDot": "La ruta no puede contener ..", + "filenameReserved": "SKILL.md ya existe", + "filenameDuplicate": "Ya existe un archivo con este nombre", + "pathTooLong": "La ruta es demasiado larga (máx. 200 caracteres)" + }, "copyMarkdownUrl": "Copiar enlace MD", "copyYamlUrl": "Copiar enlace YAML", "downloadStarted": "Descarga iniciada", @@ -366,6 +391,9 @@ "submit": "Enviar Solicitud de Cambio", "created": "Solicitud de cambio enviada exitosamente", "status": "Estado", + "pending": "Pendiente", + "approved": "Aprobado", + "rejected": "Rechazado", "approve": "Aprobar", "reject": "Rechazar", "reviewNote": "Nota de Revisión", diff --git a/messages/fa.json b/messages/fa.json index 2bfb37b2..50dc5082 100644 --- a/messages/fa.json +++ b/messages/fa.json @@ -38,6 +38,7 @@ "feed": "فید", "promptmasters": "پرامپت‌مسترها", "prompts": "پرامپت‌ها", + "skills": "مهارت‌ها", "categories": "دسته‌بندی‌ها", "tags": "برچسب‌ها", "settings": "تنظیمات", @@ -102,6 +103,8 @@ "prompts": { "title": "پرامپت‌ها", "create": "ایجاد پرامپت", + "createSkill": "ایجاد مهارت", + "skillsDescription": "مهارت‌های عامل، پرامپت‌های چند فایلی هستند که به عامل‌های هوش مصنوعی قابلیت‌های تخصصی می‌دهند. شامل دستورالعمل‌ها، تنظیمات و فایل‌های پشتیبانی هستند که می‌توانند با Claude، Cursor، Windsurf و سایر دستیاران برنامه‌نویسی AI استفاده شوند.", "createInfo": "این پلتفرم پرامپت‌ها را اجرا نمی‌کند — این یک کتابخانه مبتنی بر جامعه برای اشتراک‌گذاری و کشف پرامپت‌های هوش مصنوعی است. پرامپت خود را اینجا بسازید و دیگران می‌توانند آن را در ابزارهای هوش مصنوعی مورد علاقه خود مانند ChatGPT، Claude، Gemini یا هر LLM دیگری کپی و استفاده کنند.", "hfDataStudio": { "button": "HF Data Studio", @@ -232,6 +235,28 @@ "downloadMarkdown": "دانلود MD", "downloadYaml": "دانلود YAML", "downloadSkillMd": "دانلود SKILL.md", + "downloadSkill": "دانلود .skill", + "skillFiles": "فایل‌های مهارت", + "copy": "کپی", + "download": "دانلود", + "addFile": "افزودن فایل", + "deleteFile": "حذف فایل", + "file": "فایل", + "files": "فایل‌ها", + "addNewFile": "افزودن فایل جدید", + "addNewFileDescription": "نام فایل با پسوند را وارد کنید. از / برای پوشه‌ها استفاده کنید (مثل config.json, src/utils.ts)", + "deleteFileConfirm": "فایل حذف شود؟", + "deleteFileDescription": "آیا مطمئن هستید که می‌خواهید \"{filename}\" را حذف کنید؟ این عمل قابل بازگشت نیست.", + "validation": { + "filenameEmpty": "نام فایل نمی‌تواند خالی باشد", + "filenameInvalidChars": "نام فایل شامل کاراکترهای نامعتبر است", + "pathStartEndSlash": "مسیر نمی‌تواند با / شروع یا پایان یابد", + "pathConsecutiveSlashes": "مسیر نمی‌تواند شامل اسلش‌های متوالی باشد", + "pathContainsDotDot": "مسیر نمی‌تواند شامل .. باشد", + "filenameReserved": "SKILL.md از قبل وجود دارد", + "filenameDuplicate": "فایلی با این نام از قبل وجود دارد", + "pathTooLong": "مسیر خیلی طولانی است (حداکثر ۲۰۰ کاراکتر)" + }, "copyMarkdownUrl": "کپی لینک MD", "copyYamlUrl": "کپی لینک YAML", "downloadStarted": "دانلود شروع شد", @@ -366,6 +391,9 @@ "submit": "ارسال درخواست تغییر", "created": "درخواست تغییر با موفقیت ارسال شد", "status": "وضعیت", + "pending": "در انتظار", + "approved": "تأیید شده", + "rejected": "رد شده", "approve": "تأیید", "reject": "رد", "reviewNote": "یادداشت بررسی", diff --git a/messages/fr.json b/messages/fr.json index 2e96dd7d..5923a904 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -38,6 +38,7 @@ "feed": "Flux", "promptmasters": "Promptmasters", "prompts": "Prompts", + "skills": "Compétences", "categories": "Catégories", "tags": "Tags", "settings": "Paramètres", @@ -102,6 +103,8 @@ "prompts": { "title": "Prompts", "create": "Créer un Prompt", + "createSkill": "Créer une Compétence", + "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.", "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", @@ -232,6 +235,28 @@ "downloadMarkdown": "Télécharger MD", "downloadYaml": "Télécharger YAML", "downloadSkillMd": "Télécharger SKILL.md", + "downloadSkill": "Télécharger .skill", + "skillFiles": "Fichiers de Compétence", + "copy": "Copier", + "download": "Télécharger", + "addFile": "Ajouter un Fichier", + "deleteFile": "Supprimer le Fichier", + "file": "fichier", + "files": "fichiers", + "addNewFile": "Ajouter un Nouveau Fichier", + "addNewFileDescription": "Entrez un nom de fichier avec extension. Utilisez / pour les répertoires (ex., config.json, src/utils.ts)", + "deleteFileConfirm": "Supprimer le Fichier ?", + "deleteFileDescription": "Êtes-vous sûr de vouloir supprimer \"{filename}\" ? Cette action est irréversible.", + "validation": { + "filenameEmpty": "Le nom du fichier ne peut pas être vide", + "filenameInvalidChars": "Le nom du fichier contient des caractères invalides", + "pathStartEndSlash": "Le chemin ne peut pas commencer ou se terminer par /", + "pathConsecutiveSlashes": "Le chemin ne peut pas contenir de barres obliques consécutives", + "pathContainsDotDot": "Le chemin ne peut pas contenir ..", + "filenameReserved": "SKILL.md existe déjà", + "filenameDuplicate": "Un fichier avec ce nom existe déjà", + "pathTooLong": "Le chemin est trop long (max. 200 caractères)" + }, "copyMarkdownUrl": "Copier le lien MD", "copyYamlUrl": "Copier le lien YAML", "downloadStarted": "Téléchargement démarré", @@ -366,6 +391,9 @@ "submit": "Soumettre la Demande de Modification", "created": "Demande de modification soumise avec succès", "status": "Statut", + "pending": "En attente", + "approved": "Approuvé", + "rejected": "Rejeté", "approve": "Approuver", "reject": "Rejeter", "reviewNote": "Note de Révision", diff --git a/messages/he.json b/messages/he.json index 166b0989..fa013499 100644 --- a/messages/he.json +++ b/messages/he.json @@ -38,6 +38,7 @@ "feed": "פיד", "promptmasters": "מאסטרים", "prompts": "פרומפטים", + "skills": "מיומנויות", "categories": "קטגוריות", "tags": "תגיות", "settings": "הגדרות", @@ -101,7 +102,9 @@ }, "prompts": { "title": "פרומפטים", - "create": "צור פרומפט", + "create": "יצירת פרומפט", + "createSkill": "יצירת מיומנות", + "skillsDescription": "מיומנויות סוכן הן פרומפטים מרובי קבצים שמעניקים לסוכני AI יכולות מתמחות. הן כוללות הוראות, הגדרות וקבצי תמיכה שניתן להשתמש בהם עם Claude, Cursor, Windsurf ועוזרי קידוד AI אחרים.", "createInfo": "פלטפורמה זו לא מריצה פרומפטים — היא ספרייה קהילתית לשיתוף וגילוי פרומפטים של AI. צור את הפרומפט שלך כאן, ואחרים יוכלו להעתיק ולהשתמש בו בכלי ה-AI המועדפים עליהם כמו ChatGPT, Claude, Gemini או כל LLM אחר. הקהילה יכולה גם להגיב על הפרומפטים שלך ולהציע שיפורים דרך בקשות שינוי.", "hfDataStudio": { "button": "HF Data Studio", @@ -232,6 +235,28 @@ "downloadMarkdown": "הורד MD", "downloadYaml": "הורד YAML", "downloadSkillMd": "הורד SKILL.md", + "downloadSkill": "הורד .skill", + "skillFiles": "קבצי מיומנות", + "copy": "העתק", + "download": "הורד", + "addFile": "הוסף קובץ", + "deleteFile": "מחק קובץ", + "file": "קובץ", + "files": "קבצים", + "addNewFile": "הוסף קובץ חדש", + "addNewFileDescription": "הזן שם קובץ עם סיומת. השתמש ב-/ לתיקיות (למשל, config.json, src/utils.ts)", + "deleteFileConfirm": "למחוק קובץ?", + "deleteFileDescription": "האם אתה בטוח שברצונך למחוק את \"{filename}\"? פעולה זו אינה ניתנת לביטול.", + "validation": { + "filenameEmpty": "שם הקובץ לא יכול להיות ריק", + "filenameInvalidChars": "שם הקובץ מכיל תווים לא חוקיים", + "pathStartEndSlash": "הנתיב לא יכול להתחיל או להסתיים ב-/", + "pathConsecutiveSlashes": "הנתיב לא יכול להכיל לוכסנים עוקבים", + "pathContainsDotDot": "הנתיב לא יכול להכיל ..", + "filenameReserved": "SKILL.md כבר קיים", + "filenameDuplicate": "קובץ עם שם זה כבר קיים", + "pathTooLong": "הנתיב ארוך מדי (מקסימום 200 תווים)" + }, "copyMarkdownUrl": "העתק קישור MD", "copyYamlUrl": "העתק קישור YAML", "downloadStarted": "ההורדה החלה", @@ -366,6 +391,9 @@ "submit": "שלח בקשת שינוי", "created": "בקשת השינוי נשלחה בהצלחה", "status": "סטטוס", + "pending": "ממתין", + "approved": "אושר", + "rejected": "נדחה", "approve": "אשר", "reject": "דחה", "reviewNote": "הערת סקירה", diff --git a/messages/it.json b/messages/it.json index 2c332039..9ed92e10 100644 --- a/messages/it.json +++ b/messages/it.json @@ -38,6 +38,7 @@ "feed": "Feed", "promptmasters": "Promptmaster", "prompts": "Prompt", + "skills": "Competenze", "categories": "Categorie", "tags": "Tag", "settings": "Impostazioni", @@ -102,6 +103,8 @@ "prompts": { "title": "Prompt", "create": "Crea Prompt", + "createSkill": "Crea Competenza", + "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.", "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", @@ -232,6 +235,28 @@ "downloadMarkdown": "Scarica MD", "downloadYaml": "Scarica YAML", "downloadSkillMd": "Scarica SKILL.md", + "downloadSkill": "Scarica .skill", + "skillFiles": "File di Skill", + "copy": "Copia", + "download": "Scarica", + "addFile": "Aggiungi File", + "deleteFile": "Elimina File", + "file": "file", + "files": "file", + "addNewFile": "Aggiungi Nuovo File", + "addNewFileDescription": "Inserisci un nome file con estensione. Usa / per le directory (es., config.json, src/utils.ts)", + "deleteFileConfirm": "Eliminare File?", + "deleteFileDescription": "Sei sicuro di voler eliminare \"{filename}\"? Questa azione non può essere annullata.", + "validation": { + "filenameEmpty": "Il nome del file non può essere vuoto", + "filenameInvalidChars": "Il nome del file contiene caratteri non validi", + "pathStartEndSlash": "Il percorso non può iniziare o terminare con /", + "pathConsecutiveSlashes": "Il percorso non può contenere barre consecutive", + "pathContainsDotDot": "Il percorso non può contenere ..", + "filenameReserved": "SKILL.md esiste già", + "filenameDuplicate": "Un file con questo nome esiste già", + "pathTooLong": "Il percorso è troppo lungo (max 200 caratteri)" + }, "copyMarkdownUrl": "Copia link MD", "copyYamlUrl": "Copia link YAML", "downloadStarted": "Download avviato", @@ -366,6 +391,9 @@ "submit": "Invia Richiesta di Modifica", "created": "Richiesta di modifica inviata con successo", "status": "Stato", + "pending": "In attesa", + "approved": "Approvato", + "rejected": "Rifiutato", "approve": "Approva", "reject": "Rifiuta", "reviewNote": "Nota di Revisione", diff --git a/messages/ja.json b/messages/ja.json index 8d1f41c6..8388b7e9 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -38,6 +38,7 @@ "feed": "フィード", "promptmasters": "Promptmasters", "prompts": "プロンプト", + "skills": "スキル", "categories": "カテゴリー", "tags": "タグ", "settings": "設定", @@ -102,6 +103,8 @@ "prompts": { "title": "プロンプト", "create": "プロンプトを作成", + "createSkill": "スキルを作成", + "skillsDescription": "エージェントスキルは、AIエージェントに専門的な機能を与えるマルチファイルプロンプトです。Claude、Cursor、Windsurf、その他のAIコーディングアシスタントで使用できる指示、設定、サポートファイルが含まれています。", "createInfo": "このプラットフォームはプロンプトを実行しません — AIプロンプトを共有・発見するためのコミュニティライブラリです。ここでプロンプトを作成すると、他のユーザーがChatGPT、Claude、Geminiなどのお気に入りのAIツールでコピーして使用できます。コミュニティはあなたのプロンプトにコメントしたり、変更リクエストを通じて改善を提案することもできます。", "hfDataStudio": { "button": "HF Data Studio", @@ -245,6 +248,28 @@ "downloadMarkdown": "MDをダウンロード", "downloadYaml": "YAMLをダウンロード", "downloadSkillMd": "SKILL.mdをダウンロード", + "downloadSkill": ".skillをダウンロード", + "skillFiles": "スキルファイル", + "copy": "コピー", + "download": "ダウンロード", + "addFile": "ファイルを追加", + "deleteFile": "ファイルを削除", + "file": "ファイル", + "files": "ファイル", + "addNewFile": "新しいファイルを追加", + "addNewFileDescription": "拡張子付きのファイル名を入力してください。ディレクトリには / を使用してください(例: config.json, src/utils.ts)", + "deleteFileConfirm": "ファイルを削除しますか?", + "deleteFileDescription": "「{filename}」を削除してもよろしいですか?この操作は取り消せません。", + "validation": { + "filenameEmpty": "ファイル名は空にできません", + "filenameInvalidChars": "ファイル名に無効な文字が含まれています", + "pathStartEndSlash": "パスは / で始めたり終わったりできません", + "pathConsecutiveSlashes": "パスに連続したスラッシュは使用できません", + "pathContainsDotDot": "パスに .. は使用できません", + "filenameReserved": "SKILL.md は既に存在します", + "filenameDuplicate": "この名前のファイルは既に存在します", + "pathTooLong": "パスが長すぎます(最大200文字)" + }, "copyMarkdownUrl": "MDリンクをコピー", "copyYamlUrl": "YAMLリンクをコピー", "downloadStarted": "ダウンロード開始", @@ -366,6 +391,9 @@ "submit": "変更リクエストを送信", "created": "変更リクエストを送信しました", "status": "ステータス", + "pending": "保留中", + "approved": "承認済み", + "rejected": "却下済み", "approve": "承認", "reject": "却下", "reviewNote": "レビューノート", diff --git a/messages/ko.json b/messages/ko.json index 05e1062b..2416186c 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -38,6 +38,7 @@ "feed": "피드", "promptmasters": "프롬프트마스터", "prompts": "프롬프트", + "skills": "스킬", "categories": "카테고리", "tags": "태그", "settings": "설정", @@ -101,7 +102,9 @@ }, "prompts": { "title": "프롬프트", - "create": "프롬프트 생성", + "create": "프롬프트 만들기", + "createSkill": "스킬 만들기", + "skillsDescription": "에이전트 스킬은 AI 에이전트에게 전문 기능을 제공하는 멀티 파일 프롬프트입니다. Claude, Cursor, Windsurf 및 기타 AI 코딩 어시스턴트와 함께 사용할 수 있는 지침, 구성 및 지원 파일이 포함되어 있습니다.", "createInfo": "이 플랫폼은 프롬프트를 실행하지 않습니다 — AI 프롬프트를 공유하고 발견하는 커뮤니티 라이브러리입니다. 여기서 프롬프트를 만들면 다른 사용자들이 ChatGPT, Claude, Gemini 등 선호하는 AI 도구에서 복사하여 사용할 수 있습니다. 커뮤니티는 프롬프트에 댓글을 달고 변경 요청을 통해 개선 사항을 제안할 수도 있습니다.", "hfDataStudio": { "button": "HF 데이터 스튜디오", @@ -232,6 +235,28 @@ "downloadMarkdown": "MD 다운로드", "downloadYaml": "YAML 다운로드", "downloadSkillMd": "SKILL.md 다운로드", + "downloadSkill": ".skill 다운로드", + "skillFiles": "스킬 파일", + "copy": "복사", + "download": "다운로드", + "addFile": "파일 추가", + "deleteFile": "파일 삭제", + "file": "파일", + "files": "파일", + "addNewFile": "새 파일 추가", + "addNewFileDescription": "확장자가 포함된 파일명을 입력하세요. 디렉토리는 /를 사용하세요 (예: config.json, src/utils.ts)", + "deleteFileConfirm": "파일을 삭제하시겠습니까?", + "deleteFileDescription": "\"{filename}\"을(를) 삭제하시겠습니까? 이 작업은 취소할 수 없습니다.", + "validation": { + "filenameEmpty": "파일명은 비워둘 수 없습니다", + "filenameInvalidChars": "파일명에 잘못된 문자가 포함되어 있습니다", + "pathStartEndSlash": "경로는 /로 시작하거나 끝날 수 없습니다", + "pathConsecutiveSlashes": "경로에 연속된 슬래시를 포함할 수 없습니다", + "pathContainsDotDot": "경로에 ..을 포함할 수 없습니다", + "filenameReserved": "SKILL.md가 이미 존재합니다", + "filenameDuplicate": "이 이름의 파일이 이미 존재합니다", + "pathTooLong": "경로가 너무 깁니다 (최대 200자)" + }, "copyMarkdownUrl": "MD 링크 복사", "copyYamlUrl": "YAML 링크 복사", "downloadStarted": "다운로드 시작", @@ -366,6 +391,9 @@ "submit": "변경 요청 제출", "created": "변경 요청이 성공적으로 제출되었습니다", "status": "상태", + "pending": "대기 중", + "approved": "승인됨", + "rejected": "거절됨", "approve": "승인", "reject": "거부", "reviewNote": "검토 메모", diff --git a/messages/nl.json b/messages/nl.json index 9eaf727d..cece772c 100644 --- a/messages/nl.json +++ b/messages/nl.json @@ -38,6 +38,7 @@ "feed": "Feed", "promptmasters": "Promptmasters", "prompts": "Prompts", + "skills": "Vaardigheden", "categories": "Categorieën", "tags": "Tags", "settings": "Instellingen", @@ -102,6 +103,8 @@ "prompts": { "title": "Prompts", "create": "Prompt aanmaken", + "createSkill": "Vaardigheid 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.", "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", @@ -231,7 +234,29 @@ "run": "Uitvoeren", "downloadMarkdown": "MD downloaden", "downloadYaml": "YAML downloaden", - "downloadSkillMd": "SKILL.md downloaden", + "downloadSkillMd": "Download SKILL.md", + "downloadSkill": "Download .skill", + "skillFiles": "Vaardigheidsbestanden", + "copy": "Kopiëren", + "download": "Downloaden", + "addFile": "Bestand toevoegen", + "deleteFile": "Bestand verwijderen", + "file": "bestand", + "files": "bestanden", + "addNewFile": "Nieuw bestand toevoegen", + "addNewFileDescription": "Voer een bestandsnaam met extensie in. Gebruik / voor mappen (bijv. config.json, src/utils.ts)", + "deleteFileConfirm": "Bestand verwijderen?", + "deleteFileDescription": "Weet je zeker dat je \"{filename}\" wilt verwijderen? Deze actie kan niet ongedaan worden gemaakt.", + "validation": { + "filenameEmpty": "Bestandsnaam mag niet leeg zijn", + "filenameInvalidChars": "Bestandsnaam bevat ongeldige tekens", + "pathStartEndSlash": "Pad mag niet beginnen of eindigen met /", + "pathConsecutiveSlashes": "Pad mag geen opeenvolgende schuine strepen bevatten", + "pathContainsDotDot": "Pad mag geen .. bevatten", + "filenameReserved": "SKILL.md bestaat al", + "filenameDuplicate": "Een bestand met deze naam bestaat al", + "pathTooLong": "Pad is te lang (max 200 tekens)" + }, "copyMarkdownUrl": "MD-link kopiëren", "copyYamlUrl": "YAML-link kopiëren", "downloadStarted": "Download gestart", @@ -366,6 +391,9 @@ "submit": "Wijzigingsverzoek indienen", "created": "Wijzigingsverzoek succesvol ingediend", "status": "Status", + "pending": "In afwachting", + "approved": "Goedgekeurd", + "rejected": "Afgewezen", "approve": "Goedkeuren", "reject": "Afwijzen", "reviewNote": "Beoordelingsnotitie", diff --git a/messages/pt.json b/messages/pt.json index de3314ca..0c263b6d 100644 --- a/messages/pt.json +++ b/messages/pt.json @@ -38,6 +38,7 @@ "feed": "Feed", "promptmasters": "Promptmasters", "prompts": "Prompts", + "skills": "Habilidades", "categories": "Categorias", "tags": "Tags", "settings": "Configurações", @@ -102,6 +103,8 @@ "prompts": { "title": "Prompts", "create": "Criar Prompt", + "createSkill": "Criar Habilidade", + "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.", "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", @@ -232,6 +235,28 @@ "downloadMarkdown": "Baixar MD", "downloadYaml": "Baixar YAML", "downloadSkillMd": "Baixar SKILL.md", + "downloadSkill": "Baixar .skill", + "skillFiles": "Arquivos de Habilidade", + "copy": "Copiar", + "download": "Baixar", + "addFile": "Adicionar Arquivo", + "deleteFile": "Excluir Arquivo", + "file": "arquivo", + "files": "arquivos", + "addNewFile": "Adicionar Novo Arquivo", + "addNewFileDescription": "Digite um nome de arquivo com extensão. Use / para diretórios (ex., config.json, src/utils.ts)", + "deleteFileConfirm": "Excluir Arquivo?", + "deleteFileDescription": "Tem certeza de que deseja excluir \"{filename}\"? Esta ação não pode ser desfeita.", + "validation": { + "filenameEmpty": "O nome do arquivo não pode estar vazio", + "filenameInvalidChars": "O nome do arquivo contém caracteres inválidos", + "pathStartEndSlash": "O caminho não pode começar ou terminar com /", + "pathConsecutiveSlashes": "O caminho não pode conter barras consecutivas", + "pathContainsDotDot": "O caminho não pode conter ..", + "filenameReserved": "SKILL.md já existe", + "filenameDuplicate": "Um arquivo com este nome já existe", + "pathTooLong": "O caminho é muito longo (máx. 200 caracteres)" + }, "copyMarkdownUrl": "Copiar link MD", "copyYamlUrl": "Copiar link YAML", "downloadStarted": "Download iniciado", @@ -366,6 +391,9 @@ "submit": "Enviar Solicitação de Alteração", "created": "Solicitação de alteração enviada com sucesso", "status": "Status", + "pending": "Pendente", + "approved": "Aprovado", + "rejected": "Rejeitado", "approve": "Aprovar", "reject": "Rejeitar", "reviewNote": "Nota de Revisão", diff --git a/messages/ru.json b/messages/ru.json index d64990da..6f0eddbf 100644 --- a/messages/ru.json +++ b/messages/ru.json @@ -38,6 +38,7 @@ "feed": "Лента", "promptmasters": "Мастера промптов", "prompts": "Промпты", + "skills": "Навыки", "categories": "Категории", "tags": "Теги", "settings": "Настройки", @@ -102,6 +103,8 @@ "prompts": { "title": "Промпты", "create": "Создать промпт", + "createSkill": "Создать навык", + "skillsDescription": "Навыки агента — это многофайловые промпты, которые дают AI-агентам специализированные возможности. Они включают инструкции, конфигурации и вспомогательные файлы, которые можно использовать с Claude, Cursor, Windsurf и другими AI-помощниками для программирования.", "createInfo": "Эта платформа не выполняет промпты — это библиотека сообщества для обмена и поиска AI-промптов. Создайте свой промпт здесь, и другие смогут скопировать и использовать его в своих любимых AI-инструментах, таких как ChatGPT, Claude, Gemini или любой другой LLM. Сообщество также может комментировать ваши промпты и предлагать улучшения через запросы на изменение.", "hfDataStudio": { "button": "HF Data Studio", @@ -232,6 +235,28 @@ "downloadMarkdown": "Скачать MD", "downloadYaml": "Скачать YAML", "downloadSkillMd": "Скачать SKILL.md", + "downloadSkill": "Скачать .skill", + "skillFiles": "Файлы навыков", + "copy": "Копировать", + "download": "Скачать", + "addFile": "Добавить файл", + "deleteFile": "Удалить файл", + "file": "файл", + "files": "файлы", + "addNewFile": "Добавить новый файл", + "addNewFileDescription": "Введите имя файла с расширением. Используйте / для директорий (например, config.json, src/utils.ts)", + "deleteFileConfirm": "Удалить файл?", + "deleteFileDescription": "Вы уверены, что хотите удалить \"{filename}\"? Это действие нельзя отменить.", + "validation": { + "filenameEmpty": "Имя файла не может быть пустым", + "filenameInvalidChars": "Имя файла содержит недопустимые символы", + "pathStartEndSlash": "Путь не может начинаться или заканчиваться на /", + "pathConsecutiveSlashes": "Путь не может содержать последовательные косые черты", + "pathContainsDotDot": "Путь не может содержать ..", + "filenameReserved": "SKILL.md уже существует", + "filenameDuplicate": "Файл с таким именем уже существует", + "pathTooLong": "Путь слишком длинный (макс. 200 символов)" + }, "copyMarkdownUrl": "Копировать ссылку MD", "copyYamlUrl": "Копировать ссылку YAML", "downloadStarted": "Загрузка началась", @@ -366,6 +391,9 @@ "submit": "Отправить запрос на изменение", "created": "Запрос на изменение успешно отправлен", "status": "Статус", + "pending": "На рассмотрении", + "approved": "Одобрено", + "rejected": "Отклонено", "approve": "Одобрить", "reject": "Отклонить", "reviewNote": "Заметка к рассмотрению", diff --git a/messages/tr.json b/messages/tr.json index a0c2ca25..d3255cce 100644 --- a/messages/tr.json +++ b/messages/tr.json @@ -38,6 +38,7 @@ "feed": "Akış", "promptmasters": "Promptmasters", "prompts": "Promptlar", + "skills": "Yetenekler", "categories": "Kategoriler", "tags": "Etiketler", "settings": "Ayarlar", @@ -102,6 +103,8 @@ "prompts": { "title": "Promptlar", "create": "Prompt Oluştur", + "createSkill": "Yetenek 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.", "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", @@ -232,6 +235,28 @@ "downloadMarkdown": "MD İndir", "downloadYaml": "YAML İndir", "downloadSkillMd": "SKILL.md İndir", + "downloadSkill": ".skill İndir", + "skillFiles": "Yetenek Dosyaları", + "copy": "Kopyala", + "download": "İndir", + "addFile": "Dosya Ekle", + "deleteFile": "Dosyayı Sil", + "file": "dosya", + "files": "dosya", + "addNewFile": "Yeni Dosya Ekle", + "addNewFileDescription": "Uzantılı bir dosya adı girin. Dizinler için / kullanın (örn., config.json, src/utils.ts)", + "deleteFileConfirm": "Dosya Silinsin mi?", + "deleteFileDescription": "\"{filename}\" dosyasını silmek istediğinizden emin misiniz? Bu işlem geri alınamaz.", + "validation": { + "filenameEmpty": "Dosya adı boş olamaz", + "filenameInvalidChars": "Dosya adı geçersiz karakterler içeriyor", + "pathStartEndSlash": "Yol / ile başlayamaz veya bitemez", + "pathConsecutiveSlashes": "Yol ardışık eğik çizgi içeremez", + "pathContainsDotDot": "Yol .. içeremez", + "filenameReserved": "SKILL.md zaten mevcut", + "filenameDuplicate": "Bu isimde bir dosya zaten mevcut", + "pathTooLong": "Yol çok uzun (maks. 200 karakter)" + }, "copyMarkdownUrl": "MD Linkini Kopyala", "copyYamlUrl": "YAML Linkini Kopyala", "downloadStarted": "İndirme başladı", @@ -366,6 +391,9 @@ "submit": "Değişiklik İsteği Gönder", "created": "Değişiklik isteği başarıyla gönderildi", "status": "Durum", + "pending": "Beklemede", + "approved": "Onaylandı", + "rejected": "Reddedildi", "approve": "Onayla", "reject": "Reddet", "reviewNote": "İnceleme Notu", diff --git a/messages/zh.json b/messages/zh.json index b189d2da..beaefaa7 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -38,6 +38,7 @@ "feed": "动态", "promptmasters": "Promptmasters", "prompts": "提示词", + "skills": "技能", "categories": "分类", "tags": "标签", "settings": "设置", @@ -102,6 +103,8 @@ "prompts": { "title": "提示词", "create": "创建提示词", + "createSkill": "创建技能", + "skillsDescription": "智能体技能是多文件提示词,可为AI智能体提供专业能力。它们包含指令、配置和支持文件,可与Claude、Cursor、Windsurf及其他AI编程助手配合使用。", "createInfo": "本平台不运行或执行提示词——这是一个社区驱动的AI提示词分享和发现库。在这里创建您的提示词,其他人可以复制并在他们喜欢的AI工具中使用,如ChatGPT、Claude、Gemini或任何其他LLM。社区还可以评论您的提示词,并通过变更请求提出改进建议。", "hfDataStudio": { "button": "HF 数据工作室", @@ -232,6 +235,28 @@ "downloadMarkdown": "下载 MD", "downloadYaml": "下载 YAML", "downloadSkillMd": "下载 SKILL.md", + "downloadSkill": "下载 .skill", + "skillFiles": "技能文件", + "copy": "复制", + "download": "下载", + "addFile": "添加文件", + "deleteFile": "删除文件", + "file": "文件", + "files": "文件", + "addNewFile": "添加新文件", + "addNewFileDescription": "输入带扩展名的文件名。使用 / 表示目录(例如,config.json、src/utils.ts)", + "deleteFileConfirm": "删除文件?", + "deleteFileDescription": "确定要删除 \"{filename}\" 吗?此操作无法撤销。", + "validation": { + "filenameEmpty": "文件名不能为空", + "filenameInvalidChars": "文件名包含无效字符", + "pathStartEndSlash": "路径不能以 / 开头或结尾", + "pathConsecutiveSlashes": "路径不能包含连续的斜杠", + "pathContainsDotDot": "路径不能包含 ..", + "filenameReserved": "SKILL.md 已存在", + "filenameDuplicate": "此名称的文件已存在", + "pathTooLong": "路径太长(最多200个字符)" + }, "copyMarkdownUrl": "复制 MD 链接", "copyYamlUrl": "复制 YAML 链接", "downloadStarted": "开始下载", @@ -366,6 +391,9 @@ "submit": "提交变更请求", "created": "变更请求提交成功", "status": "状态", + "pending": "待处理", + "approved": "已批准", + "rejected": "已拒绝", "approve": "批准", "reject": "拒绝", "reviewNote": "审核备注", diff --git a/package-lock.json b/package-lock.json index 552ff034..4b766c1a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,6 +43,7 @@ "cmdk": "^1.1.1", "d3": "^7.9.0", "date-fns": "^4.1.0", + "jszip": "^3.10.1", "lucide-react": "^0.556.0", "next": "^16.0.10", "next-auth": "^5.0.0-beta.30", @@ -10224,6 +10225,12 @@ "node": ">=6.6.0" } }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "license": "MIT" + }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -12942,6 +12949,12 @@ "node": ">= 4" } }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", + "license": "MIT" + }, "node_modules/import-fresh": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", @@ -13847,6 +13860,18 @@ "node": ">=4.0" } }, + "node_modules/jszip": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", + "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", + "license": "(MIT OR GPL-3.0-or-later)", + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "setimmediate": "^1.0.5" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -13891,6 +13916,15 @@ "node": ">= 0.8.0" } }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/lightningcss": { "version": "1.30.2", "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.30.2.tgz", @@ -16574,6 +16608,12 @@ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", "license": "BlueOak-1.0.0" }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "license": "(MIT AND Zlib)" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -17011,6 +17051,12 @@ } } }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "license": "MIT" + }, "node_modules/process-warning": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", @@ -17349,6 +17395,33 @@ } } }, + "node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "license": "MIT" + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -18030,6 +18103,12 @@ "node": ">= 0.4" } }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "license": "MIT" + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -18360,6 +18439,21 @@ "node": ">= 0.4" } }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "license": "MIT" + }, "node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", diff --git a/package.json b/package.json index 59f40d68..c0b98c39 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "cmdk": "^1.1.1", "d3": "^7.9.0", "date-fns": "^4.1.0", + "jszip": "^3.10.1", "lucide-react": "^0.556.0", "next": "^16.0.10", "next-auth": "^5.0.0-beta.30", diff --git a/scripts/seed-skills.ts b/scripts/seed-skills.ts new file mode 100644 index 00000000..3046ee00 --- /dev/null +++ b/scripts/seed-skills.ts @@ -0,0 +1,270 @@ +/** + * Seed script to import skills from Anthropic's skills repository + * + * Usage: + * npx tsx scripts/seed-skills.ts [skill-name] + * + * Examples: + * npx tsx scripts/seed-skills.ts pdf + * npx tsx scripts/seed-skills.ts --all + */ + +import { PrismaClient } from "@prisma/client"; +import * as fs from "fs"; +import * as path from "path"; + +const prisma = new PrismaClient(); + +// File separator uses ASCII control characters (injection-proof): +// \x1F (Unit Separator, ASCII 31) marks start +// \x1E (Record Separator, ASCII 30) marks end +const FILE_SEPARATOR = (filename: string) => `\x1FFILE:${filename}\x1E`; + +interface SkillMetadata { + name: string; + description: string; + license?: string; +} + +/** + * Parse YAML frontmatter from SKILL.md + */ +function parseFrontmatter(content: string): { metadata: SkillMetadata; body: string } { + const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/); + + if (!frontmatterMatch) { + return { + metadata: { name: "Unknown", description: "" }, + body: content, + }; + } + + const [, frontmatter, body] = frontmatterMatch; + const metadata: SkillMetadata = { name: "Unknown", description: "" }; + + // Simple YAML parsing for frontmatter + frontmatter.split("\n").forEach((line) => { + const match = line.match(/^(\w+):\s*(.+)$/); + if (match) { + const [, key, value] = match; + if (key === "name") metadata.name = value.trim(); + if (key === "description") metadata.description = value.trim(); + if (key === "license") metadata.license = value.trim(); + } + }); + + return { metadata, body }; +} + +/** + * Recursively read all files from a directory + */ +function readSkillFiles(skillDir: string, basePath: string = ""): Array<{ path: string; content: string }> { + const files: Array<{ path: string; content: string }> = []; + const entries = fs.readdirSync(skillDir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(skillDir, entry.name); + const relativePath = basePath ? `${basePath}/${entry.name}` : entry.name; + + if (entry.isDirectory()) { + files.push(...readSkillFiles(fullPath, relativePath)); + } else if (entry.isFile()) { + // Skip binary files and hidden files + if (entry.name.startsWith(".")) continue; + + try { + const content = fs.readFileSync(fullPath, "utf-8"); + files.push({ path: relativePath, content }); + } catch (e) { + console.warn(` Skipping binary file: ${relativePath}`); + } + } + } + + return files; +} + +/** + * Serialize skill files into multi-file format + */ +function serializeSkillFiles(files: Array<{ path: string; content: string }>): string { + // SKILL.md should be first + const skillMd = files.find((f) => f.path === "SKILL.md"); + const otherFiles = files.filter((f) => f.path !== "SKILL.md"); + + if (!skillMd) { + throw new Error("SKILL.md not found"); + } + + let result = skillMd.content; + + for (const file of otherFiles) { + result += `\n${FILE_SEPARATOR(file.path)}\n${file.content}`; + } + + return result; +} + +/** + * Import a single skill into the database + */ +async function importSkill(skillDir: string, authorId: string): Promise { + const skillName = path.basename(skillDir); + console.log(`\nImporting skill: ${skillName}`); + + // Read all files + const files = readSkillFiles(skillDir); + console.log(` Found ${files.length} files`); + + // Find and parse SKILL.md + const skillMdFile = files.find((f) => f.path === "SKILL.md"); + if (!skillMdFile) { + console.error(` ERROR: SKILL.md not found in ${skillDir}`); + return; + } + + const { metadata } = parseFrontmatter(skillMdFile.content); + console.log(` Name: ${metadata.name}`); + console.log(` Description: ${metadata.description.substring(0, 80)}...`); + + // Serialize all files + const content = serializeSkillFiles(files); + + // Check if skill already exists + const existing = await prisma.prompt.findFirst({ + where: { + title: metadata.name, + type: "SKILL", + authorId, + }, + }); + + if (existing) { + console.log(` Skill "${metadata.name}" already exists, updating...`); + await prisma.prompt.update({ + where: { id: existing.id }, + data: { + content, + description: metadata.description, + }, + }); + } else { + // Create new skill + await prisma.prompt.create({ + data: { + title: metadata.name, + description: metadata.description, + content, + type: "SKILL", + authorId, + isPrivate: false, + }, + }); + console.log(` Created skill: ${metadata.name}`); + } +} + +/** + * Main function + */ +async function main() { + const args = process.argv.slice(2); + + if (args.length === 0) { + console.log("Usage:"); + console.log(" npx tsx scripts/seed-skills.ts - Import a specific skill"); + console.log(" npx tsx scripts/seed-skills.ts --all - Import all skills"); + console.log(" npx tsx scripts/seed-skills.ts --list - List available skills"); + console.log("\nAvailable skills:"); + + const skillsDir = "/tmp/anthropic-skills/skills"; + if (fs.existsSync(skillsDir)) { + const skills = fs.readdirSync(skillsDir, { withFileTypes: true }) + .filter((d) => d.isDirectory()) + .map((d) => d.name); + skills.forEach((s) => console.log(` - ${s}`)); + } else { + console.log(" (Skills repo not found. Clone it first with: git clone https://github.com/anthropics/skills.git /tmp/anthropic-skills)"); + } + return; + } + + // Find or create admin user for importing + let author = await prisma.user.findFirst({ + where: { role: "ADMIN" }, + }); + + if (!author) { + console.log("No admin user found. Creating system user..."); + author = await prisma.user.create({ + data: { + email: "system@prompts.chat", + username: "system", + name: "System", + role: "ADMIN", + }, + }); + } + + console.log(`Using author: ${author.username} (${author.id})`); + + const skillsBaseDir = "/tmp/anthropic-skills/skills"; + + if (!fs.existsSync(skillsBaseDir)) { + console.error("Skills directory not found. Please clone the repo first:"); + console.error(" git clone https://github.com/anthropics/skills.git /tmp/anthropic-skills"); + return; + } + + if (args[0] === "--all") { + // Import all skills + const skillDirs = fs.readdirSync(skillsBaseDir, { withFileTypes: true }) + .filter((d) => d.isDirectory()) + .map((d) => path.join(skillsBaseDir, d.name)); + + console.log(`Found ${skillDirs.length} skills to import`); + + for (const skillDir of skillDirs) { + try { + await importSkill(skillDir, author.id); + } catch (e) { + console.error(` ERROR importing ${path.basename(skillDir)}:`, e); + } + } + } else if (args[0] === "--list") { + // List available skills + const skills = fs.readdirSync(skillsBaseDir, { withFileTypes: true }) + .filter((d) => d.isDirectory()) + .map((d) => d.name); + + console.log("Available skills:"); + skills.forEach((s) => console.log(` - ${s}`)); + } else { + // Import specific skill + const skillDir = path.join(skillsBaseDir, args[0]); + + if (!fs.existsSync(skillDir)) { + console.error(`Skill not found: ${args[0]}`); + console.log("\nAvailable skills:"); + const skills = fs.readdirSync(skillsBaseDir, { withFileTypes: true }) + .filter((d) => d.isDirectory()) + .map((d) => d.name); + skills.forEach((s) => console.log(` - ${s}`)); + return; + } + + await importSkill(skillDir, author.id); + } + + console.log("\nDone!"); +} + +main() + .catch((e) => { + console.error(e); + process.exit(1); + }) + .finally(async () => { + await prisma.$disconnect(); + }); diff --git a/src/app/api/prompts/[id]/skill/route.ts b/src/app/api/prompts/[id]/skill/route.ts new file mode 100644 index 00000000..211ede60 --- /dev/null +++ b/src/app/api/prompts/[id]/skill/route.ts @@ -0,0 +1,78 @@ +import { NextRequest, NextResponse } from "next/server"; +import { db } from "@/lib/db"; +import { parseSkillFiles } from "@/lib/skill-files"; +import JSZip from "jszip"; + +/** + * Extracts the prompt ID from a URL parameter + * Supports formats: "abc123", "abc123_some-slug" + */ +function parseIdParam(idParam: string): string { + let param = idParam; + + // Remove .skill extension if present + if (param.endsWith(".skill")) { + param = param.slice(0, -".skill".length); + } + + // If the param contains an underscore, extract the ID (everything before first underscore) + const underscoreIndex = param.indexOf("_"); + if (underscoreIndex !== -1) { + param = param.substring(0, underscoreIndex); + } + + return param; +} + +export async function GET( + request: NextRequest, + { params }: { params: Promise<{ id: string }> } +) { + const { id: idParam } = await params; + const id = parseIdParam(idParam); + + // Fetch the skill + const prompt = await db.prompt.findFirst({ + where: { id, deletedAt: null, isPrivate: false, type: "SKILL" }, + select: { + id: true, + slug: true, + title: true, + description: true, + content: true, + }, + }); + + if (!prompt) { + return new NextResponse("Skill not found", { status: 404 }); + } + + // Parse the skill files + const files = parseSkillFiles(prompt.content); + + // Create a zip file + const zip = new JSZip(); + + // Add each file to the zip + for (const file of files) { + zip.file(file.filename, file.content); + } + + // Generate the zip content + const zipContent = await zip.generateAsync({ + type: "nodebuffer", + compression: "DEFLATE", + compressionOptions: { level: 9 }, + }); + + // Generate filename + const slug = prompt.slug || prompt.title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, ""); + const filename = `${slug}.skill`; + + return new NextResponse(zipContent, { + headers: { + "Content-Type": "application/zip", + "Content-Disposition": `attachment; filename="${filename}"`, + }, + }); +} diff --git a/src/app/docs/api/page.tsx b/src/app/docs/api/page.tsx index 69e8348b..f4cdd09b 100644 --- a/src/app/docs/api/page.tsx +++ b/src/app/docs/api/page.tsx @@ -1,6 +1,6 @@ import Link from "next/link"; import { headers } from "next/headers"; -import { Code, Zap, Terminal, Search, Box, Key, Save, Sparkles } from "lucide-react"; +import { Code, Zap, Terminal, Search, Box, Key, Save, Sparkles, Cpu, FilePlus, FileX } from "lucide-react"; import { ImprovePromptDemo } from "@/components/api/improve-prompt-demo"; import { Table, @@ -479,6 +479,234 @@ curl -X POST ${baseUrl}/api/mcp \\ "outputFormat": "text" } } + }'`} + + + + {/* save_skill Tool */} +
+

+ + save_skill + Requires Auth +

+

+ Save a new Agent Skill to your account. Skills are multi-file prompts that can include SKILL.md (required), + reference docs, scripts, and configuration files. Perfect for creating comprehensive coding agent skills. +

+ +
+ + + + Parameter + Type + Required + Description + + + + + title + string + Yes + Title of the skill (max 200 chars) + + + files + array + Yes + + Array of {`{filename, content}`}. Must include SKILL.md + + + + description + string + No + Optional description (max 500 chars) + + + tags + string[] + No + Array of tag names (max 10) + + + category + string + No + Category slug + + + isPrivate + boolean + No + Override default privacy setting + + +
+
+ +
+
{`# Save a skill via MCP
+curl -X POST ${baseUrl}/api/mcp \\
+  -H "Content-Type: application/json" \\
+  -H "PROMPTS_API_KEY: pchat_your_api_key_here" \\
+  -d '{
+    "jsonrpc": "2.0",
+    "id": 1,
+    "method": "tools/call",
+    "params": {
+      "name": "save_skill",
+      "arguments": {
+        "title": "PDF Processing Skill",
+        "description": "Comprehensive PDF manipulation toolkit",
+        "files": [
+          {"filename": "SKILL.md", "content": "# PDF Processing\\n\\nThis skill helps with PDF manipulation..."},
+          {"filename": "reference.md", "content": "# API Reference\\n\\n..."},
+          {"filename": "scripts/extract.py", "content": "import pypdf\\n..."}
+        ],
+        "tags": ["pdf", "documents"]
+      }
+    }
+  }'`}
+
+
+ + {/* add_file_to_skill Tool */} +
+

+ + add_file_to_skill + Requires Auth +

+

+ Add a new file to an existing Agent Skill. Use this to add reference docs, scripts, or configuration files. +

+ +
+ + + + Parameter + Type + Required + Description + + + + + skillId + string + Yes + ID of the skill to add the file to + + + filename + string + Yes + + File path (e.g., reference.md, scripts/helper.py) + + + + content + string + Yes + File content + + +
+
+
+ + {/* remove_file_from_skill Tool */} +
+

+ + remove_file_from_skill + Requires Auth +

+

+ Remove a file from an existing Agent Skill. Cannot remove SKILL.md as it is required. +

+ +
+ + + + Parameter + Type + Required + Description + + + + + skillId + string + Yes + ID of the skill to remove the file from + + + filename + string + Yes + File path to remove (cannot be SKILL.md) + + +
+
+
+ + {/* get_skill Tool */} +
+

+ + get_skill +

+

+ Get an Agent Skill by ID, including all its files (SKILL.md, reference docs, scripts, etc.). + Returns skill metadata and file contents. Public skills are accessible without authentication; + private skills require API key authentication. +

+ +
+ + + + Parameter + Type + Required + Description + + + + + id + string + Yes + The ID of the skill to retrieve + + +
+
+ +
+
{`# Get a skill via MCP
+curl -X POST ${baseUrl}/api/mcp \\
+  -H "Content-Type: application/json" \\
+  -d '{
+    "jsonrpc": "2.0",
+    "id": 1,
+    "method": "tools/call",
+    "params": {
+      "name": "get_skill",
+      "arguments": {
+        "id": "skill_id_here"
+      }
+    }
   }'`}
diff --git a/src/app/prompts/[id]/changes/[changeId]/page.tsx b/src/app/prompts/[id]/changes/[changeId]/page.tsx index 5b00017f..5cb88357 100644 --- a/src/app/prompts/[id]/changes/[changeId]/page.tsx +++ b/src/app/prompts/[id]/changes/[changeId]/page.tsx @@ -9,6 +9,7 @@ import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { DiffView } from "@/components/ui/diff-view"; +import { SkillDiffViewer } from "@/components/prompts/skill-diff-viewer"; import { ChangeRequestActions } from "@/components/prompts/change-request-actions"; import { ReopenChangeRequestButton } from "@/components/prompts/reopen-change-request-button"; import { DismissChangeRequestButton } from "@/components/prompts/dismiss-change-request-button"; @@ -52,6 +53,7 @@ export default async function ChangeRequestPage({ params }: ChangeRequestPagePro title: true, content: true, authorId: true, + type: true, }, }, }, @@ -151,10 +153,17 @@ export default async function ChangeRequestPage({ params }: ChangeRequestPagePro {/* Content diff */}

{t("contentChanges")}

- + {changeRequest.prompt.type === "SKILL" ? ( + + ) : ( + + )}
{/* Review note (if exists) */} diff --git a/src/app/prompts/[id]/page.tsx b/src/app/prompts/[id]/page.tsx index 08fa3037..30e5cce1 100644 --- a/src/app/prompts/[id]/page.tsx +++ b/src/app/prompts/[id]/page.tsx @@ -14,6 +14,7 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip"; import { InteractivePromptContent } from "@/components/prompts/interactive-prompt-content"; +import { SkillViewer } from "@/components/prompts/skill-viewer"; import { UpvoteButton } from "@/components/prompts/upvote-button"; import { AddVersionForm } from "@/components/prompts/add-version-form"; import { DeleteVersionButton } from "@/components/prompts/delete-version-button"; @@ -548,7 +549,13 @@ export default async function PromptPage({ params }: PromptPageProps) { )} - {prompt.structuredFormat ? ( + {prompt.type === "SKILL" ? ( + + ) : prompt.structuredFormat ? ( )} - {/* Report & Prompt Flow */} - + {/* Report & Prompt Flow - hide for SKILL type */} + {prompt.type !== "SKILL" && ( + + )} {/* Related Prompts */} {relatedPrompts.length > 0 && ( diff --git a/src/app/skills/page.tsx b/src/app/skills/page.tsx new file mode 100644 index 00000000..b17fceb0 --- /dev/null +++ b/src/app/skills/page.tsx @@ -0,0 +1,159 @@ +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: "Skills", + description: "Browse and discover AI agent skills", +}; + +// Query for skills list (cached) +function getCachedSkills( + // 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: "SKILL", + 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 [skillsRaw, 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 }, + }, + }, + }), + db.prompt.count({ where }), + ]); + + return { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + skills: skillsRaw.map((p: any) => ({ + ...p, + voteCount: p._count.votes, + contributorCount: p._count.contributors, + contributors: p.contributors, + })), + total: totalCount, + }; + }, + ["skills", cacheKey], + { tags: ["prompts"] } + )(); +} + +interface SkillsPageProps { + searchParams: Promise<{ + q?: string; + sort?: string; + }>; +} + +export default async function SkillsPage({ searchParams }: SkillsPageProps) { + 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 getCachedSkills(orderBy, perPage, params.q); + const skills = result.skills; + const total = result.total; + + return ( +
+
+
+

{tNav("skills")}

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

+ {t("skillsDescription")} +

+ + +
+ ); +} diff --git a/src/components/layout/header.tsx b/src/components/layout/header.tsx index e296b9fb..ed706bff 100644 --- a/src/components/layout/header.tsx +++ b/src/components/layout/header.tsx @@ -199,6 +199,13 @@ export function Header({ authProvider = "credentials", allowRegistration = true > {t("nav.prompts")} + 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.skills")} + setMobileMenuOpen(false)} @@ -347,6 +354,12 @@ export function Header({ authProvider = "credentials", allowRegistration = true > {t("nav.prompts")} + + {t("nav.skills")} + -
- - {isStructured ? ( - - ) : ( -