diff --git a/messages/ar.json b/messages/ar.json index 6e3a2115..1497bae2 100644 --- a/messages/ar.json +++ b/messages/ar.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "إضافة", + "workflowLink": "رابط تشغيل سير العمل", + "workflowLinkDescription": "رابط URL حيث يمكن للمستخدمين اختبار أو تجربة سير العمل هذا (يظهر عندما يكون للأمر خطوات سابقة/تالية)", + "workflowLinkCreateNote": "احفظ الأمر أولاً، ثم أضف أوامر متصلة (الخطوات السابقة/التالية) لتفعيل هذا الحقل.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "خيارات متقدمة", "searchContributors": "البحث بواسطة اسم المستخدم...", "noUsersFound": "لم يتم العثور على مستخدمين", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "تدفق الأوامر", - "description": "بعض الأوامر تعمل كسير عمل متعدد الخطوات. قم بربط أوامرك لإنشاء تسلسل.", "addPromptFlow": "هذا الأمر له خطوة تالية", + "testWorkflow": "تشغيل سير العمل", "addPrevious": "إضافة سابق", "addNext": "إضافة تالي", "addPreviousTitle": "إضافة أمر سابق", diff --git a/messages/az.json b/messages/az.json index 148b2a57..14430328 100644 --- a/messages/az.json +++ b/messages/az.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Əlavə et", + "workflowLink": "İş Axını Linki", + "workflowLinkDescription": "İstifadəçilərin bu iş axınını sınaya biləcəyi URL (əvvəlki/sonrakı addımları olan promptlar üçün göstərilir)", + "workflowLinkCreateNote": "Əvvəlcə promptu saxlayın, sonra bu sahəni aktivləşdirmək üçün əlaqəli promptlar əlavə edin.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "Təkmılləşdirilmiş Seçimlər", "searchContributors": "İstifadəçi adına görə axtar...", "noUsersFound": "İstifadəçi tapılmadı", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Prompt Axını", - "description": "Bəzi promptlar çox addımlı iş axınları kimi işləyir. Ardıcıllıq yaratmaq üçün promptlarınızı birləşdirin.", "addPromptFlow": "Bu promptun növbəti addımı var", + "testWorkflow": "İş Axınını Çalışdır", "addPrevious": "Əvvəlkini Əlavə et", "addNext": "Növbətini Əlavə et", "addPreviousTitle": "Əvvəlki Promptu Əlavə et", diff --git a/messages/de.json b/messages/de.json index c6218c9e..6bdd9ec7 100644 --- a/messages/de.json +++ b/messages/de.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Hinzufügen", + "workflowLink": "Workflow-Link", + "workflowLinkDescription": "Eine URL, wo Benutzer diesen Workflow testen oder demonstrieren können (wird angezeigt, wenn der Prompt vorherige/nächste Schritte hat)", + "workflowLinkCreateNote": "Speichern Sie zuerst den Prompt, dann fügen Sie verbundene Prompts (vorherige/nächste Schritte) hinzu, um dieses Feld zu aktivieren.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "Erweiterte Optionen", "searchContributors": "Nach Benutzernamen suchen...", "noUsersFound": "Keine Benutzer gefunden", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Prompt-Ablauf", - "description": "Einige Prompts funktionieren als mehrstufige Workflows. Verbinden Sie Ihre Prompts, um eine Sequenz zu erstellen.", "addPromptFlow": "Dieser Prompt hat einen nächsten Schritt", + "testWorkflow": "Workflow ausführen", "addPrevious": "Vorherigen hinzufügen", "addNext": "Nächsten hinzufügen", "addPreviousTitle": "Vorherigen Prompt hinzufügen", diff --git a/messages/el.json b/messages/el.json index ffab5bd7..44109f2a 100644 --- a/messages/el.json +++ b/messages/el.json @@ -144,7 +144,11 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Προσθήκη", - "advancedOptions": "Προχωρημένες Επιλογές", + "workflowLink": "Σύνδεσμος Ροής Εργασίας", + "workflowLinkDescription": "URL όπου οι χρήστες μπορούν να δοκιμάσουν αυτή τη ροή εργασίας", + "workflowLinkCreateNote": "Αποθηκεύστε πρώτα το prompt, μετά προσθέστε συνδεδεμένα prompts για να ενεργοποιήσετε αυτό το πεδίο.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", + "advancedOptions": "Σύνθετες Επιλογές", "searchContributors": "Αναζήτηση με όνομα χρήστη...", "noUsersFound": "Δεν βρέθηκαν χρήστες", "worksBestWith": "Λειτουργεί καλύτερα με", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Ροή Prompts", - "description": "Ορισμένα prompts λειτουργούν ως ροές εργασίας πολλαπλών βημάτων. Συνδέστε τα prompts σας για να δημιουργήσετε μια ακολουθία.", "addPromptFlow": "Αυτό το prompt έχει επόμενο βήμα", + "testWorkflow": "Εκτέλεση Ροής Εργασίας", "addPrevious": "Προσθήκη Προηγούμενου", "addNext": "Προσθήκη Επόμενου", "addPreviousTitle": "Προσθήκη Προηγούμενου Prompt", diff --git a/messages/en.json b/messages/en.json index 43cc1281..c905d028 100644 --- a/messages/en.json +++ b/messages/en.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Add", + "workflowLink": "Test Workflow Link", + "workflowLinkDescription": "A URL where users can test or demo this workflow (shown when prompt has previous/next steps)", + "workflowLinkCreateNote": "Save the prompt first, then add connected prompts (previous/next steps) to enable this field.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "Advanced Options", "worksBestWith": "Works best with", "mcpTools": "MCP Tools", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Prompt Flow", - "description": "Some prompts work as multi-step workflows. Connect your prompts to create a sequence.", "addPromptFlow": "This prompt has a next step", + "testWorkflow": "Run Workflow", "addPrevious": "Add Previous", "addNext": "Add Next", "addPreviousTitle": "Add Previous Prompt", diff --git a/messages/es.json b/messages/es.json index b88bdc16..2d5ee990 100644 --- a/messages/es.json +++ b/messages/es.json @@ -141,6 +141,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Añadir", + "workflowLink": "Enlace del Flujo de Trabajo", + "workflowLinkDescription": "Una URL donde los usuarios pueden probar este flujo de trabajo", + "workflowLinkCreateNote": "Guarda el prompt primero, luego añade prompts conectados para habilitar este campo.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "Opciones Avanzadas", "searchContributors": "Buscar por nombre de usuario...", "noUsersFound": "No se encontraron usuarios", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Flujo de Prompts", - "description": "Algunos prompts funcionan como flujos de trabajo de varios pasos. Conecta tus prompts para crear una secuencia.", "addPromptFlow": "Este prompt tiene un paso siguiente", + "testWorkflow": "Ejecutar Flujo", "addPrevious": "Añadir Anterior", "addNext": "Añadir Siguiente", "addPreviousTitle": "Añadir Prompt Anterior", diff --git a/messages/fa.json b/messages/fa.json index cb618861..0f45fa8e 100644 --- a/messages/fa.json +++ b/messages/fa.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "اضافه", + "workflowLink": "لینک گردش کار", + "workflowLinkDescription": "لینکی که کاربران می‌توانند این گردش کار را آزمایش کنند", + "workflowLinkCreateNote": "ابتدا پرامپت را ذخیره کنید، سپس پرامپت‌های متصل اضافه کنید.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "گزینه‌های پیشرفته", "searchContributors": "جستجو بر اساس نام کاربری...", "noUsersFound": "کاربری یافت نشد", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "جریان پرامپت", - "description": "برخی پرامپت‌ها به صورت جریان‌های کاری چند مرحله‌ای عمل می‌کنند. پرامپت‌هایتان را متصل کنید تا یک دنباله بسازید.", "addPromptFlow": "این پرامپت مرحله بعدی دارد", + "testWorkflow": "اجرای گردش کار", "addPrevious": "افزودن قبلی", "addNext": "افزودن بعدی", "addPreviousTitle": "افزودن پرامپت قبلی", diff --git a/messages/fr.json b/messages/fr.json index 5d32184c..91b4f288 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Ajouter", + "workflowLink": "Lien du Workflow", + "workflowLinkDescription": "URL où les utilisateurs peuvent tester ce workflow", + "workflowLinkCreateNote": "Enregistrez d'abord le prompt, puis ajoutez des prompts connectés pour activer ce champ.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "Options Avancées", "searchContributors": "Rechercher par nom d'utilisateur...", "noUsersFound": "Aucun utilisateur trouvé", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Flux de Prompts", - "description": "Certains prompts fonctionnent comme des workflows multi-étapes. Connectez vos prompts pour créer une séquence.", "addPromptFlow": "Ce prompt a une étape suivante", + "testWorkflow": "Exécuter le Workflow", "addPrevious": "Ajouter Précédent", "addNext": "Ajouter Suivant", "addPreviousTitle": "Ajouter Prompt Précédent", diff --git a/messages/he.json b/messages/he.json index 489b3355..3859da59 100644 --- a/messages/he.json +++ b/messages/he.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "הוסף", + "workflowLink": "קישור לתהליך עבודה", + "workflowLinkDescription": "כתובת URL שבה משתמשים יכולים לבדוק את תהליך העבודה הזה", + "workflowLinkCreateNote": "שמור קודם את הפרומפט, ואז הוסף פרומפטים מקושרים כדי להפעיל שדה זה.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "אפשרויות מתקדמות", "searchContributors": "חפש לפי שם משתמש...", "noUsersFound": "לא נמצאו משתמשים", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "זרימת פרומפטים", - "description": "חלק מהפרומפטים עובדים כתהליכי עבודה מרובי שלבים. חבר את הפרומפטים שלך ליצירת רצף.", "addPromptFlow": "לפרומפט הזה יש שלב הבא", + "testWorkflow": "הפעל תהליך עבודה", "addPrevious": "הוסף קודם", "addNext": "הוסף הבא", "addPreviousTitle": "הוסף פרומפט קודם", diff --git a/messages/it.json b/messages/it.json index 8a588d0d..cab03b3d 100644 --- a/messages/it.json +++ b/messages/it.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Aggiungi", + "workflowLink": "Link del Workflow", + "workflowLinkDescription": "URL dove gli utenti possono testare questo workflow", + "workflowLinkCreateNote": "Salva prima il prompt, poi aggiungi prompt collegati per abilitare questo campo.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "Opzioni Avanzate", "searchContributors": "Cerca per nome utente...", "noUsersFound": "Nessun utente trovato", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Flusso Prompt", - "description": "Alcuni prompt funzionano come workflow a più passaggi. Collega i tuoi prompt per creare una sequenza.", "addPromptFlow": "Questo prompt ha un passo successivo", + "testWorkflow": "Esegui Workflow", "addPrevious": "Aggiungi Precedente", "addNext": "Aggiungi Successivo", "addPreviousTitle": "Aggiungi Prompt Precedente", diff --git a/messages/ja.json b/messages/ja.json index 69bdbfa7..c248580f 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -141,6 +141,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "追加", + "workflowLink": "ワークフローリンク", + "workflowLinkDescription": "ユーザーがこのワークフローをテストできるURL", + "workflowLinkCreateNote": "まずプロンプトを保存し、次に接続されたプロンプトを追加してこのフィールドを有効にしてください。", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "詳細オプション", "searchContributors": "ユーザー名で検索...", "noUsersFound": "ユーザーが見つかりません", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "プロンプトフロー", - "description": "一部のプロンプトは複数ステップのワークフローとして機能します。プロンプトを接続してシーケンスを作成しましょう。", "addPromptFlow": "このプロンプトには次のステップがあります", + "testWorkflow": "ワークフローを実行", "addPrevious": "前を追加", "addNext": "次を追加", "addPreviousTitle": "前のプロンプトを追加", diff --git a/messages/ko.json b/messages/ko.json index 7fe556e5..84915700 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "추가", + "workflowLink": "워크플로 링크", + "workflowLinkDescription": "사용자가 이 워크플로를 테스트할 수 있는 URL", + "workflowLinkCreateNote": "먼저 프롬프트를 저장한 다음 연결된 프롬프트를 추가하여 이 필드를 활성화하세요.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "고급 옵션", "searchContributors": "사용자명으로 검색...", "noUsersFound": "사용자를 찾을 수 없습니다", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "프롬프트 흐름", - "description": "일부 프롬프트는 다단계 워크플로로 작동합니다. 프롬프트를 연결하여 시퀀스를 만드세요.", "addPromptFlow": "이 프롬프트에는 다음 단계가 있습니다", + "testWorkflow": "워크플로 실행", "addPrevious": "이전 추가", "addNext": "다음 추가", "addPreviousTitle": "이전 프롬프트 추가", diff --git a/messages/nl.json b/messages/nl.json index bd77024c..1dd516d4 100644 --- a/messages/nl.json +++ b/messages/nl.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Toevoegen", + "workflowLink": "Workflow Link", + "workflowLinkDescription": "URL waar gebruikers deze workflow kunnen testen", + "workflowLinkCreateNote": "Sla eerst de prompt op en voeg daarna verbonden prompts toe om dit veld in te schakelen.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "Geavanceerde opties", "worksBestWith": "Werkt het beste met", "mcpTools": "MCP-tools", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Promptstroom", - "description": "Sommige prompts werken als meerstaps-workflows. Verbind je prompts om een reeks te maken.", "addPromptFlow": "Deze prompt heeft een volgende stap", + "testWorkflow": "Workflow Uitvoeren", "addPrevious": "Vorige toevoegen", "addNext": "Volgende toevoegen", "addPreviousTitle": "Vorige prompt toevoegen", diff --git a/messages/pt.json b/messages/pt.json index 00048a5c..4a38951a 100644 --- a/messages/pt.json +++ b/messages/pt.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Adicionar", + "workflowLink": "Link do Workflow", + "workflowLinkDescription": "URL onde usuários podem testar este workflow", + "workflowLinkCreateNote": "Salve o prompt primeiro, depois adicione prompts conectados para habilitar este campo.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "Opções Avançadas", "searchContributors": "Buscar por nome de usuário...", "noUsersFound": "Nenhum usuário encontrado", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Fluxo de Prompts", - "description": "Alguns prompts funcionam como fluxos de trabalho de várias etapas. Conecte seus prompts para criar uma sequência.", "addPromptFlow": "Este prompt tem um próximo passo", + "testWorkflow": "Executar Workflow", "addPrevious": "Adicionar Anterior", "addNext": "Adicionar Próximo", "addPreviousTitle": "Adicionar Prompt Anterior", diff --git a/messages/ru.json b/messages/ru.json index ada0f311..4de3818c 100644 --- a/messages/ru.json +++ b/messages/ru.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Добавить", + "workflowLink": "Ссылка на рабочий процесс", + "workflowLinkDescription": "URL, где пользователи могут протестировать этот рабочий процесс", + "workflowLinkCreateNote": "Сначала сохраните промпт, затем добавьте связанные промпты, чтобы активировать это поле.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "Расширенные настройки", "searchContributors": "Поиск по имени пользователя...", "noUsersFound": "Пользователи не найдены", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Поток промптов", - "description": "Некоторые промпты работают как многоэтапные рабочие процессы. Соедините свои промпты для создания последовательности.", "addPromptFlow": "У этого промпта есть следующий шаг", + "testWorkflow": "Запустить рабочий процесс", "addPrevious": "Добавить предыдущий", "addNext": "Добавить следующий", "addPreviousTitle": "Добавить предыдущий промпт", diff --git a/messages/tr.json b/messages/tr.json index 97b9bfbf..a4e2257b 100644 --- a/messages/tr.json +++ b/messages/tr.json @@ -144,6 +144,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "Ekle", + "workflowLink": "İş Akışı Bağlantısı", + "workflowLinkDescription": "Kullanıcıların bu iş akışını test edebileceği URL", + "workflowLinkCreateNote": "Önce promptu kaydedin, ardından bu alanı etkinleştirmek için bağlı promptlar ekleyin.", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "Gelişmiş Seçenekler", "searchContributors": "Kullanıcı adına göre ara...", "noUsersFound": "Kullanıcı bulunamadı", @@ -1230,8 +1234,8 @@ }, "connectedPrompts": { "title": "Prompt Akışı", - "description": "Bazı promptlar çok adımlı iş akışları olarak çalışır. Bir sıra oluşturmak için promptlarınızı bağlayın.", - "addPromptFlow": "Bu promptun sonraki adımı var", + "addPromptFlow": "Bu promptun bir sonraki adımı var", + "testWorkflow": "İş Akışını Çalıştır", "addPrevious": "Önceki Ekle", "addNext": "Sonraki Ekle", "addPreviousTitle": "Önceki Prompt Ekle", diff --git a/messages/zh.json b/messages/zh.json index 9befa9f9..0696b6e8 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -141,6 +141,10 @@ "mcpCommandPlaceholder": "npx -y @mcp/server-name", "mcpToolsPlaceholder": "tool1, tool2", "add": "添加", + "workflowLink": "工作流链接", + "workflowLinkDescription": "用户可以测试此工作流的URL", + "workflowLinkCreateNote": "先保存提示词,然后添加连接的提示词以启用此字段。", + "workflowLinkPlaceholder": "https://example.com/workflow-demo", "advancedOptions": "高级选项", "searchContributors": "按用户名搜索...", "noUsersFound": "未找到用户", @@ -1225,13 +1229,13 @@ "keyRegenerated": "API 密钥重新生成成功", "keyRevoked": "API 密钥已撤销", "publicByDefault": "默认公开提示词", - "publicByDefaultDescription": "通过 MCP 保存提示词时,默认设为公开而非私有。", + "publicByDefaultDescription": "通过MCP保存提示词时,默认设为公开而非私有。", "settingUpdated": "设置已更新" }, "connectedPrompts": { "title": "提示词流程", - "description": "某些提示词作为多步骤工作流运行。连接您的提示词以创建序列。", "addPromptFlow": "此提示词有下一步", + "testWorkflow": "运行工作流", "addPrevious": "添加上一个", "addNext": "添加下一个", "addPreviousTitle": "添加上一个提示词", diff --git a/prisma/migrations/20260128100000_add_workflow_link/migration.sql b/prisma/migrations/20260128100000_add_workflow_link/migration.sql new file mode 100644 index 00000000..4c50165e --- /dev/null +++ b/prisma/migrations/20260128100000_add_workflow_link/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "prompts" ADD COLUMN "workflowLink" TEXT; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 1c1ab567..2aebf1f3 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -129,6 +129,7 @@ model Prompt { collectedBy Collection[] bestWithModels String[] // Model slugs this prompt works best with (max 3), e.g. ["gpt-4o", "claude-3-5-sonnet"] bestWithMCP Json? // MCP configs array, e.g. [{command: "npx -y @mcp/server", tools: ["tool1"]}] + workflowLink String? // URL to test/demo the workflow when prompt has previous/next connections @@index([authorId]) @@index([categoryId]) diff --git a/prompts.config.ts b/prompts.config.ts index 5c5f227b..1a06770c 100644 --- a/prompts.config.ts +++ b/prompts.config.ts @@ -83,6 +83,7 @@ export default defineConfig({ { name: "CodeRabbit", className: 'py-1', logo: '/sponsors/coderabbit.svg', darkLogo: '/sponsors/coderabbit-dark.svg', url: "https://coderabbit.link/fatih" }, { 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" }, ], }, diff --git a/public/sponsors/eachlabs-dark.png b/public/sponsors/eachlabs-dark.png new file mode 100644 index 00000000..172b7605 Binary files /dev/null and b/public/sponsors/eachlabs-dark.png differ diff --git a/public/sponsors/eachlabs.png b/public/sponsors/eachlabs.png new file mode 100644 index 00000000..eb709922 Binary files /dev/null and b/public/sponsors/eachlabs.png differ diff --git a/src/app/api/prompts/[id]/route.ts b/src/app/api/prompts/[id]/route.ts index 655588d2..ef84025d 100644 --- a/src/app/api/prompts/[id]/route.ts +++ b/src/app/api/prompts/[id]/route.ts @@ -26,6 +26,7 @@ const updatePromptSchema = z.object({ command: z.string(), tools: z.array(z.string()).optional(), })).optional(), + workflowLink: z.string().url().optional().or(z.literal("")).nullable(), }); // Get single prompt @@ -161,7 +162,7 @@ export async function PATCH( ); } - const { tagIds, contributorIds, categoryId, mediaUrl, title, bestWithModels, bestWithMCP, ...data } = parsed.data; + const { tagIds, contributorIds, categoryId, mediaUrl, title, bestWithModels, bestWithMCP, workflowLink, ...data } = parsed.data; // Regenerate slug if title changed let newSlug: string | undefined; @@ -178,6 +179,7 @@ export async function PATCH( ...(mediaUrl !== undefined && { mediaUrl: mediaUrl || null }), ...(bestWithModels !== undefined && { bestWithModels }), ...(bestWithMCP !== undefined && { bestWithMCP }), + ...(workflowLink !== undefined && { workflowLink: workflowLink || null }), }; // Update prompt @@ -275,6 +277,64 @@ export async function PATCH( }); } + // Propagate workflow link to all prompts in the same workflow chain (not "related" ones) + if (workflowLink !== undefined) { + const newWorkflowLink = workflowLink || null; + + // Get all flow connections (excluding "related") + const allFlowConnections = await db.promptConnection.findMany({ + where: { + label: { not: "related" }, + }, + select: { + sourceId: true, + targetId: true, + }, + }); + + // Build adjacency list for the workflow graph + const adjacency = new Map>(); + allFlowConnections.forEach((conn) => { + if (!adjacency.has(conn.sourceId)) adjacency.set(conn.sourceId, new Set()); + if (!adjacency.has(conn.targetId)) adjacency.set(conn.targetId, new Set()); + adjacency.get(conn.sourceId)!.add(conn.targetId); + adjacency.get(conn.targetId)!.add(conn.sourceId); + }); + + // BFS to find all prompts in the same workflow chain + const workflowPromptIds = new Set(); + const queue = [id]; + workflowPromptIds.add(id); + + while (queue.length > 0) { + const current = queue.shift()!; + const neighbors = adjacency.get(current); + if (neighbors) { + neighbors.forEach((neighborId) => { + if (!workflowPromptIds.has(neighborId)) { + workflowPromptIds.add(neighborId); + queue.push(neighborId); + } + }); + } + } + + // Remove current prompt from update set (already updated above) + workflowPromptIds.delete(id); + + // Update all prompts in the workflow with the same workflow link + if (workflowPromptIds.size > 0) { + await db.prompt.updateMany({ + where: { + id: { in: Array.from(workflowPromptIds) }, + }, + data: { + workflowLink: newWorkflowLink, + }, + }); + } + } + // Revalidate prompts cache revalidateTag("prompts", "max"); diff --git a/src/app/api/prompts/route.ts b/src/app/api/prompts/route.ts index aeb7d7e1..274d6aa6 100644 --- a/src/app/api/prompts/route.ts +++ b/src/app/api/prompts/route.ts @@ -28,6 +28,7 @@ const promptSchema = z.object({ command: z.string(), tools: z.array(z.string()).optional(), })).optional(), + workflowLink: z.string().url().optional().or(z.literal("")), }); // Create prompt @@ -51,7 +52,7 @@ export async function POST(request: Request) { ); } - const { title, description, content, type, structuredFormat, categoryId, tagIds, contributorIds, isPrivate, mediaUrl, requiresMediaUpload, requiredMediaType, requiredMediaCount, bestWithModels, bestWithMCP } = parsed.data; + const { title, description, content, type, structuredFormat, categoryId, tagIds, contributorIds, isPrivate, mediaUrl, requiresMediaUpload, requiredMediaType, requiredMediaCount, bestWithModels, bestWithMCP, workflowLink } = parsed.data; // Check if user is flagged (for auto-delisting and daily limit) const currentUser = await db.user.findUnique({ @@ -183,6 +184,7 @@ export async function POST(request: Request) { requiredMediaCount: requiresMediaUpload ? requiredMediaCount : null, bestWithModels: bestWithModels || [], bestWithMCP: bestWithMCP || [], + workflowLink: workflowLink || null, authorId: session.user.id, categoryId: categoryId || null, // Auto-delist prompts from flagged users diff --git a/src/app/prompts/[id]/edit/page.tsx b/src/app/prompts/[id]/edit/page.tsx index f5e8a929..77f80d55 100644 --- a/src/app/prompts/[id]/edit/page.tsx +++ b/src/app/prompts/[id]/edit/page.tsx @@ -98,6 +98,7 @@ export default async function EditPromptPage({ params }: EditPromptPageProps) { requiredMediaCount: prompt.requiredMediaCount || 1, bestWithModels: (prompt as unknown as { bestWithModels?: string[] }).bestWithModels || [], bestWithMCP: (prompt as unknown as { bestWithMCP?: { command: string; tools?: string[] }[] }).bestWithMCP || [], + workflowLink: (prompt as unknown as { workflowLink?: string }).workflowLink || "", }; // Check if AI generation is enabled diff --git a/src/app/prompts/[id]/page.tsx b/src/app/prompts/[id]/page.tsx index 0b68d63f..b8edc7ff 100644 --- a/src/app/prompts/[id]/page.tsx +++ b/src/app/prompts/[id]/page.tsx @@ -207,6 +207,17 @@ export default async function PromptPage({ params }: PromptPageProps) { .map((conn) => conn.target) .filter((p) => !p.isPrivate && !p.isUnlisted && !p.deletedAt); + // Check if prompt has flow connections (previous/next, not "related") + const flowConnectionCount = await db.promptConnection.count({ + where: { + OR: [ + { sourceId: id, label: { not: "related" } }, + { targetId: id, label: { not: "related" } }, + ], + }, + }); + const hasFlowConnections = flowConnectionCount > 0; + if (!prompt) { notFound(); } @@ -654,6 +665,8 @@ export default async function PromptPage({ params }: PromptPageProps) { isLoggedIn={!!session?.user} currentUserId={session?.user?.id} isAdmin={isAdmin} + workflowLink={(prompt as unknown as { workflowLink?: string | null }).workflowLink} + hasFlowConnections={hasFlowConnections} /> )} diff --git a/src/components/prompts/prompt-connections.tsx b/src/components/prompts/prompt-connections.tsx index 3eb0dda0..e52f35f6 100644 --- a/src/components/prompts/prompt-connections.tsx +++ b/src/components/prompts/prompt-connections.tsx @@ -5,7 +5,7 @@ import { useTranslations } from "next-intl"; import { toast } from "sonner"; import { useRouter } from "next/navigation"; import * as d3 from "d3"; -import { Link2, ArrowUp, ArrowDown, ChevronRight, Trash2 } from "lucide-react"; +import { Link2, ArrowUp, ArrowDown, ChevronRight, Trash2, FastForward, ExternalLink } from "lucide-react"; import { Button } from "@/components/ui/button"; import { AddConnectionDialog } from "./add-connection-dialog"; import { getPromptUrl } from "@/lib/urls"; @@ -44,6 +44,7 @@ interface PromptConnectionsProps { sectionOnly?: boolean; // Only render the expanded section expanded?: boolean; // Controlled expanded state onExpandChange?: (expanded: boolean) => void; // Callback when expanded state changes + workflowLink?: string | null; // URL to test the workflow } interface GraphNode { @@ -453,6 +454,7 @@ export function PromptConnections({ sectionOnly = false, expanded: controlledExpanded, onExpandChange, + workflowLink, }: PromptConnectionsProps) { const t = useTranslations("connectedPrompts"); const router = useRouter(); @@ -1066,43 +1068,58 @@ export function PromptConnections({ if (canEdit && !showExpanded) return null; return ( -
-
-
+
+ {/* Header row - above the container */} +
+

{t("title")}

-

{t("description")}

-
- {canEdit && (
+ {canEdit && ( + <> + + + + )} + {hasConnections && workflowLink && ( - + )}
- )} +
+ {/* Content container */} +
{!hasConnections ? (

{t("noConnections")}

) : hasFullFlow ? ( @@ -1133,6 +1150,7 @@ export function PromptConnections({ )}
)} +
{canEdit && ( string) => z.object({ command: z.string(), tools: z.array(z.string()).optional(), })).optional(), + workflowLink: z.string().url().optional().or(z.literal("")), }).superRefine((data, ctx) => { if (data.type === "SKILL") { const frontmatterError = validateSkillFrontmatter(data.content); @@ -459,6 +460,7 @@ export function PromptForm({ categories, tags, initialData, initialContributors requiredMediaCount: initialData?.requiredMediaCount || 1, bestWithModels: initialData?.bestWithModels || [], bestWithMCP: initialData?.bestWithMCP || [], + workflowLink: initialData?.workflowLink || "", }, }); @@ -1083,6 +1085,7 @@ export function PromptForm({ categories, tags, initialData, initialContributors
+ )} @@ -1433,6 +1436,34 @@ export function PromptForm({ categories, tags, initialData, initialContributors )} + {/* ===== WORKFLOW LINK SECTION ===== */} +
+ ( + + {t("workflowLink")} + + {mode === "create" + ? t("workflowLinkCreateNote") + : t("workflowLinkDescription") + } + + + + + + + )} + /> +
+