Perplexity AI Assistant - Prompt Optimizer & Workflow Orchestrator

Transform prompts with AI-powered optimization, multi-platform workflow integration, and intelligent creative assistance for Perplexity, Gemini, Bolt.new, and more

Size

56.1 KB

Version

1.0.1

Created

Jan 7, 2026

Updated

28 days ago

1// ==UserScript==
2// @name		Perplexity AI Assistant - Prompt Optimizer & Workflow Orchestrator
3// @description		Transform prompts with AI-powered optimization, multi-platform workflow integration, and intelligent creative assistance for Perplexity, Gemini, Bolt.new, and more
4// @version		1.0.1
5// @match		https://*.perplexity.ai/*
6// @icon		https://www.perplexity.ai/favicon.ico
7// ==/UserScript==
8(function() {
9    'use strict';
10
11    // ============================================================================
12    // PERPLEXITY AI ASSISTANT - CORE ENGINE
13    // ============================================================================
14
15    console.log('🚀 Perplexity AI Assistant initializing...');
16
17    // Configuration
18    const CONFIG = {
19        platforms: {
20            perplexity: { name: 'Perplexity', modes: ['Search', 'Research', 'Labs', 'Playground'] },
21            gemini: { name: 'Google Gemini Pro', url: 'https://gemini.google.com' },
22            aiStudio: { name: 'Google AI Studio', url: 'https://aistudio.google.com' },
23            bolt: { name: 'Bolt.new', url: 'https://bolt.new' },
24            lovable: { name: 'Lovable', url: 'https://lovable.dev' },
25            framer: { name: 'Framer', url: 'https://framer.com' }
26        },
27        promptStyles: [
28            'Concise Answer',
29            'Creative Output',
30            'Technical Explanation',
31            'Innovative Project',
32            'Research Deep-Dive',
33            'Multi-Step Reasoning',
34            'Visual-Ready Output',
35            'Role-Based Prompt'
36        ],
37        storageKeys: {
38            history: 'ai_assistant_history',
39            preferences: 'ai_assistant_preferences',
40            templates: 'ai_assistant_templates',
41            workflows: 'ai_assistant_workflows'
42        }
43    };
44
45    // ============================================================================
46    // UTILITY FUNCTIONS
47    // ============================================================================
48
49    function debounce(func, wait) {
50        let timeout;
51        return function executedFunction(...args) {
52            const later = () => {
53                clearTimeout(timeout);
54                func(...args);
55            };
56            clearTimeout(timeout);
57            timeout = setTimeout(later, wait);
58        };
59    }
60
61    function generateId() {
62        return Date.now().toString(36) + Math.random().toString(36).substr(2);
63    }
64
65    // ============================================================================
66    // STORAGE MANAGER
67    // ============================================================================
68
69    class StorageManager {
70        static async get(key, defaultValue = null) {
71            try {
72                const value = await GM.getValue(key, defaultValue);
73                return value ? JSON.parse(value) : defaultValue;
74            } catch (error) {
75                console.error('Storage get error:', error);
76                return defaultValue;
77            }
78        }
79
80        static async set(key, value) {
81            try {
82                await GM.setValue(key, JSON.stringify(value));
83                return true;
84            } catch (error) {
85                console.error('Storage set error:', error);
86                return false;
87            }
88        }
89
90        static async append(key, item) {
91            const items = await this.get(key, []);
92            items.unshift(item);
93            if (items.length > 100) items.pop(); // Keep last 100 items
94            await this.set(key, items);
95        }
96    }
97
98    // ============================================================================
99    // PROMPT ANALYZER & OPTIMIZER
100    // ============================================================================
101
102    class PromptOptimizer {
103        static async analyzePrompt(prompt) {
104            console.log('🔍 Analyzing prompt:', prompt);
105            
106            try {
107                const analysis = await RM.aiCall(
108                    `Analyze this user prompt for clarity, completeness, and effectiveness. Identify any vagueness, ambiguity, or missing context that could improve the response quality.
109
110Prompt: "${prompt}"
111
112Provide a detailed analysis including:
1131. Clarity score (0-10)
1142. Completeness score (0-10)
1153. Identified issues
1164. Missing context or elements
1175. Suggested improvements`,
118                    {
119                        type: "json_schema",
120                        json_schema: {
121                            name: "prompt_analysis",
122                            schema: {
123                                type: "object",
124                                properties: {
125                                    clarityScore: { type: "number", minimum: 0, maximum: 10 },
126                                    completenessScore: { type: "number", minimum: 0, maximum: 10 },
127                                    issues: { type: "array", items: { type: "string" } },
128                                    missingElements: { type: "array", items: { type: "string" } },
129                                    suggestions: { type: "array", items: { type: "string" } }
130                                },
131                                required: ["clarityScore", "completenessScore", "issues", "suggestions"]
132                            }
133                        }
134                    }
135                );
136
137                console.log('✅ Analysis complete:', analysis);
138                return analysis;
139            } catch (error) {
140                console.error('❌ Analysis error:', error);
141                return {
142                    clarityScore: 5,
143                    completenessScore: 5,
144                    issues: ['Unable to analyze prompt'],
145                    missingElements: [],
146                    suggestions: ['Try rephrasing your prompt with more specific details']
147                };
148            }
149        }
150
151        static async generateVariations(prompt, styles = CONFIG.promptStyles) {
152            console.log('🎨 Generating prompt variations for:', prompt);
153            
154            try {
155                const variations = await RM.aiCall(
156                    `Rewrite the following prompt in multiple variations optimized for different purposes and platforms (Perplexity, Gemini, Bolt.new, etc.).
157
158Original Prompt: "${prompt}"
159
160Generate variations for these styles:
161${styles.map((style, i) => `${i + 1}. ${style}`).join('\n')}
162
163Each variation should be optimized for its specific purpose while maintaining the core intent.`,
164                    {
165                        type: "json_schema",
166                        json_schema: {
167                            name: "prompt_variations",
168                            schema: {
169                                type: "object",
170                                properties: {
171                                    variations: {
172                                        type: "array",
173                                        items: {
174                                            type: "object",
175                                            properties: {
176                                                style: { type: "string" },
177                                                prompt: { type: "string" },
178                                                platform: { type: "string" },
179                                                reasoning: { type: "string" }
180                                            },
181                                            required: ["style", "prompt", "platform"]
182                                        }
183                                    }
184                                },
185                                required: ["variations"]
186                            }
187                        }
188                    }
189                );
190
191                console.log('✅ Generated variations:', variations);
192                return variations.variations;
193            } catch (error) {
194                console.error('❌ Variation generation error:', error);
195                return [];
196            }
197        }
198
199        static async generateClarifyingQuestions(prompt, analysis) {
200            console.log('❓ Generating clarifying questions...');
201            
202            try {
203                const questions = await RM.aiCall(
204                    `Based on this prompt and its analysis, generate 3-5 clarifying questions that would help refine the user's intent and improve the output quality.
205
206Prompt: "${prompt}"
207Issues: ${analysis.issues.join(', ')}
208Missing Elements: ${analysis.missingElements.join(', ')}
209
210Generate questions that are:
211- Specific and actionable
212- Help gather missing context
213- Guide the user to better articulate their needs`,
214                    {
215                        type: "json_schema",
216                        json_schema: {
217                            name: "clarifying_questions",
218                            schema: {
219                                type: "object",
220                                properties: {
221                                    questions: {
222                                        type: "array",
223                                        items: {
224                                            type: "object",
225                                            properties: {
226                                                question: { type: "string" },
227                                                purpose: { type: "string" }
228                                            },
229                                            required: ["question", "purpose"]
230                                        }
231                                    }
232                                },
233                                required: ["questions"]
234                            }
235                        }
236                    }
237                );
238
239                return questions.questions;
240            } catch (error) {
241                console.error('❌ Question generation error:', error);
242                return [];
243            }
244        }
245    }
246
247    // ============================================================================
248    // WORKFLOW ORCHESTRATOR
249    // ============================================================================
250
251    class WorkflowOrchestrator {
252        static async generateWorkflow(goal, platforms = []) {
253            console.log('🔄 Generating workflow for goal:', goal);
254            
255            try {
256                const workflow = await RM.aiCall(
257                    `Create a comprehensive multi-platform workflow to achieve this goal: "${goal}"
258
259Available platforms: ${Object.values(CONFIG.platforms).map(p => p.name).join(', ')}
260${platforms.length > 0 ? `Preferred platforms: ${platforms.join(', ')}` : ''}
261
262Generate a step-by-step workflow that:
2631. Breaks down the goal into actionable steps
2642. Assigns each step to the most appropriate platform
2653. Defines inputs, outputs, and handoffs between steps
2664. Includes research, creation, and production phases
2675. Provides specific prompts or actions for each step`,
268                    {
269                        type: "json_schema",
270                        json_schema: {
271                            name: "workflow_generation",
272                            schema: {
273                                type: "object",
274                                properties: {
275                                    workflowName: { type: "string" },
276                                    description: { type: "string" },
277                                    estimatedTime: { type: "string" },
278                                    steps: {
279                                        type: "array",
280                                        items: {
281                                            type: "object",
282                                            properties: {
283                                                stepNumber: { type: "number" },
284                                                title: { type: "string" },
285                                                platform: { type: "string" },
286                                                action: { type: "string" },
287                                                prompt: { type: "string" },
288                                                expectedOutput: { type: "string" },
289                                                nextStep: { type: "string" }
290                                            },
291                                            required: ["stepNumber", "title", "platform", "action"]
292                                        }
293                                    }
294                                },
295                                required: ["workflowName", "steps"]
296                            }
297                        }
298                    }
299                );
300
301                // Save workflow
302                await StorageManager.append(CONFIG.storageKeys.workflows, {
303                    id: generateId(),
304                    goal,
305                    workflow,
306                    createdAt: new Date().toISOString()
307                });
308
309                return workflow;
310            } catch (error) {
311                console.error('❌ Workflow generation error:', error);
312                return null;
313            }
314        }
315
316        static async suggestNextSteps(currentContext) {
317            console.log('🎯 Suggesting next steps...');
318            
319            try {
320                const suggestions = await RM.aiCall(
321                    `Based on the current context, suggest logical next steps for research or creative exploration.
322
323Context: ${JSON.stringify(currentContext)}
324
325Provide 3-5 actionable next steps with specific prompts or actions.`,
326                    {
327                        type: "json_schema",
328                        json_schema: {
329                            name: "next_steps",
330                            schema: {
331                                type: "object",
332                                properties: {
333                                    suggestions: {
334                                        type: "array",
335                                        items: {
336                                            type: "object",
337                                            properties: {
338                                                title: { type: "string" },
339                                                description: { type: "string" },
340                                                platform: { type: "string" },
341                                                prompt: { type: "string" }
342                                            },
343                                            required: ["title", "description", "platform"]
344                                        }
345                                    }
346                                },
347                                required: ["suggestions"]
348                            }
349                        }
350                    }
351                );
352
353                return suggestions.suggestions;
354            } catch (error) {
355                console.error('❌ Next steps error:', error);
356                return [];
357            }
358        }
359    }
360
361    // ============================================================================
362    // USE CASE GENERATOR
363    // ============================================================================
364
365    class UseCaseGenerator {
366        static async generateUseCases(topic, count = 5) {
367            console.log('💡 Generating use cases for:', topic);
368            
369            try {
370                const useCases = await RM.aiCall(
371                    `Generate ${count} innovative and practical use cases for: "${topic}"
372
373Each use case should:
374- Be unique and creative
375- Leverage AI capabilities effectively
376- Include specific implementation ideas
377- Span different domains (research, creative, technical, business)
378- Be actionable with current AI tools`,
379                    {
380                        type: "json_schema",
381                        json_schema: {
382                            name: "use_cases",
383                            schema: {
384                                type: "object",
385                                properties: {
386                                    useCases: {
387                                        type: "array",
388                                        items: {
389                                            type: "object",
390                                            properties: {
391                                                title: { type: "string" },
392                                                description: { type: "string" },
393                                                domain: { type: "string" },
394                                                implementation: { type: "string" },
395                                                platforms: { type: "array", items: { type: "string" } },
396                                                difficulty: { type: "string", enum: ["Beginner", "Intermediate", "Advanced"] }
397                                            },
398                                            required: ["title", "description", "domain", "implementation"]
399                                        }
400                                    }
401                                },
402                                required: ["useCases"]
403                            }
404                        }
405                    }
406                );
407
408                return useCases.useCases;
409            } catch (error) {
410                console.error('❌ Use case generation error:', error);
411                return [];
412            }
413        }
414    }
415
416    // ============================================================================
417    // UI MANAGER
418    // ============================================================================
419
420    class UIManager {
421        static injectStyles() {
422            const styles = `
423                .ai-assistant-container {
424                    position: fixed;
425                    bottom: 20px;
426                    right: 20px;
427                    z-index: 999999;
428                    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
429                }
430
431                .ai-assistant-button {
432                    width: 60px;
433                    height: 60px;
434                    border-radius: 50%;
435                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
436                    border: none;
437                    color: white;
438                    font-size: 24px;
439                    cursor: pointer;
440                    box-shadow: 0 4px 20px rgba(102, 126, 234, 0.4);
441                    transition: all 0.3s ease;
442                    display: flex;
443                    align-items: center;
444                    justify-content: center;
445                }
446
447                .ai-assistant-button:hover {
448                    transform: scale(1.1);
449                    box-shadow: 0 6px 30px rgba(102, 126, 234, 0.6);
450                }
451
452                .ai-assistant-panel {
453                    position: fixed;
454                    bottom: 90px;
455                    right: 20px;
456                    width: 450px;
457                    max-height: 600px;
458                    background: white;
459                    border-radius: 16px;
460                    box-shadow: 0 10px 50px rgba(0, 0, 0, 0.2);
461                    display: none;
462                    flex-direction: column;
463                    overflow: hidden;
464                    z-index: 999998;
465                }
466
467                .ai-assistant-panel.active {
468                    display: flex;
469                    animation: slideUp 0.3s ease;
470                }
471
472                @keyframes slideUp {
473                    from {
474                        opacity: 0;
475                        transform: translateY(20px);
476                    }
477                    to {
478                        opacity: 1;
479                        transform: translateY(0);
480                    }
481                }
482
483                .ai-assistant-header {
484                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
485                    color: white;
486                    padding: 20px;
487                    font-weight: 600;
488                    font-size: 16px;
489                    display: flex;
490                    align-items: center;
491                    justify-content: space-between;
492                }
493
494                .ai-assistant-close {
495                    background: none;
496                    border: none;
497                    color: white;
498                    font-size: 24px;
499                    cursor: pointer;
500                    padding: 0;
501                    width: 30px;
502                    height: 30px;
503                    display: flex;
504                    align-items: center;
505                    justify-content: center;
506                    border-radius: 50%;
507                    transition: background 0.2s;
508                }
509
510                .ai-assistant-close:hover {
511                    background: rgba(255, 255, 255, 0.2);
512                }
513
514                .ai-assistant-tabs {
515                    display: flex;
516                    background: #f8f9fa;
517                    border-bottom: 1px solid #e9ecef;
518                    overflow-x: auto;
519                }
520
521                .ai-assistant-tab {
522                    padding: 12px 16px;
523                    background: none;
524                    border: none;
525                    cursor: pointer;
526                    font-size: 13px;
527                    font-weight: 500;
528                    color: #6c757d;
529                    border-bottom: 2px solid transparent;
530                    transition: all 0.2s;
531                    white-space: nowrap;
532                }
533
534                .ai-assistant-tab:hover {
535                    color: #667eea;
536                }
537
538                .ai-assistant-tab.active {
539                    color: #667eea;
540                    border-bottom-color: #667eea;
541                }
542
543                .ai-assistant-content {
544                    flex: 1;
545                    overflow-y: auto;
546                    padding: 20px;
547                }
548
549                .ai-assistant-input-group {
550                    margin-bottom: 16px;
551                }
552
553                .ai-assistant-label {
554                    display: block;
555                    font-size: 13px;
556                    font-weight: 600;
557                    color: #495057;
558                    margin-bottom: 8px;
559                }
560
561                .ai-assistant-textarea {
562                    width: 100%;
563                    min-height: 100px;
564                    padding: 12px;
565                    border: 2px solid #e9ecef;
566                    border-radius: 8px;
567                    font-size: 14px;
568                    font-family: inherit;
569                    resize: vertical;
570                    transition: border-color 0.2s;
571                }
572
573                .ai-assistant-textarea:focus {
574                    outline: none;
575                    border-color: #667eea;
576                }
577
578                .ai-assistant-button-primary {
579                    width: 100%;
580                    padding: 12px;
581                    background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
582                    color: white;
583                    border: none;
584                    border-radius: 8px;
585                    font-size: 14px;
586                    font-weight: 600;
587                    cursor: pointer;
588                    transition: transform 0.2s, box-shadow 0.2s;
589                }
590
591                .ai-assistant-button-primary:hover {
592                    transform: translateY(-2px);
593                    box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
594                }
595
596                .ai-assistant-button-primary:disabled {
597                    opacity: 0.6;
598                    cursor: not-allowed;
599                    transform: none;
600                }
601
602                .ai-assistant-loading {
603                    text-align: center;
604                    padding: 40px 20px;
605                    color: #6c757d;
606                }
607
608                .ai-assistant-spinner {
609                    width: 40px;
610                    height: 40px;
611                    border: 4px solid #f3f3f3;
612                    border-top: 4px solid #667eea;
613                    border-radius: 50%;
614                    animation: spin 1s linear infinite;
615                    margin: 0 auto 16px;
616                }
617
618                @keyframes spin {
619                    0% { transform: rotate(0deg); }
620                    100% { transform: rotate(360deg); }
621                }
622
623                .ai-assistant-result {
624                    background: #f8f9fa;
625                    border-radius: 8px;
626                    padding: 16px;
627                    margin-bottom: 16px;
628                }
629
630                .ai-assistant-result-title {
631                    font-weight: 600;
632                    color: #212529;
633                    margin-bottom: 8px;
634                    font-size: 14px;
635                }
636
637                .ai-assistant-result-content {
638                    font-size: 13px;
639                    color: #495057;
640                    line-height: 1.6;
641                }
642
643                .ai-assistant-score {
644                    display: inline-flex;
645                    align-items: center;
646                    gap: 8px;
647                    padding: 6px 12px;
648                    background: white;
649                    border-radius: 20px;
650                    font-size: 13px;
651                    font-weight: 600;
652                    margin-bottom: 12px;
653                }
654
655                .ai-assistant-score-bar {
656                    width: 60px;
657                    height: 6px;
658                    background: #e9ecef;
659                    border-radius: 3px;
660                    overflow: hidden;
661                }
662
663                .ai-assistant-score-fill {
664                    height: 100%;
665                    background: linear-gradient(90deg, #667eea 0%, #764ba2 100%);
666                    transition: width 0.3s ease;
667                }
668
669                .ai-assistant-list {
670                    list-style: none;
671                    padding: 0;
672                    margin: 0;
673                }
674
675                .ai-assistant-list-item {
676                    padding: 12px;
677                    background: white;
678                    border-radius: 8px;
679                    margin-bottom: 8px;
680                    border: 1px solid #e9ecef;
681                    font-size: 13px;
682                    line-height: 1.5;
683                }
684
685                .ai-assistant-variation {
686                    background: white;
687                    border: 2px solid #e9ecef;
688                    border-radius: 8px;
689                    padding: 16px;
690                    margin-bottom: 12px;
691                    transition: border-color 0.2s;
692                    cursor: pointer;
693                }
694
695                .ai-assistant-variation:hover {
696                    border-color: #667eea;
697                }
698
699                .ai-assistant-variation-header {
700                    display: flex;
701                    justify-content: space-between;
702                    align-items: center;
703                    margin-bottom: 8px;
704                }
705
706                .ai-assistant-variation-style {
707                    font-weight: 600;
708                    color: #667eea;
709                    font-size: 13px;
710                }
711
712                .ai-assistant-variation-platform {
713                    font-size: 11px;
714                    color: #6c757d;
715                    background: #f8f9fa;
716                    padding: 4px 8px;
717                    border-radius: 4px;
718                }
719
720                .ai-assistant-variation-prompt {
721                    font-size: 13px;
722                    color: #495057;
723                    line-height: 1.6;
724                    margin-bottom: 8px;
725                }
726
727                .ai-assistant-variation-actions {
728                    display: flex;
729                    gap: 8px;
730                }
731
732                .ai-assistant-button-small {
733                    padding: 6px 12px;
734                    background: #667eea;
735                    color: white;
736                    border: none;
737                    border-radius: 6px;
738                    font-size: 12px;
739                    cursor: pointer;
740                    transition: background 0.2s;
741                }
742
743                .ai-assistant-button-small:hover {
744                    background: #5568d3;
745                }
746
747                .ai-assistant-button-secondary {
748                    background: #6c757d;
749                }
750
751                .ai-assistant-button-secondary:hover {
752                    background: #5a6268;
753                }
754
755                .ai-assistant-workflow-step {
756                    background: white;
757                    border-left: 4px solid #667eea;
758                    padding: 16px;
759                    margin-bottom: 12px;
760                    border-radius: 8px;
761                    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05);
762                }
763
764                .ai-assistant-workflow-step-number {
765                    display: inline-block;
766                    width: 28px;
767                    height: 28px;
768                    background: #667eea;
769                    color: white;
770                    border-radius: 50%;
771                    text-align: center;
772                    line-height: 28px;
773                    font-weight: 600;
774                    font-size: 13px;
775                    margin-right: 12px;
776                }
777
778                .ai-assistant-workflow-step-title {
779                    font-weight: 600;
780                    color: #212529;
781                    font-size: 14px;
782                    margin-bottom: 8px;
783                }
784
785                .ai-assistant-workflow-step-platform {
786                    display: inline-block;
787                    background: #f8f9fa;
788                    color: #667eea;
789                    padding: 4px 10px;
790                    border-radius: 12px;
791                    font-size: 11px;
792                    font-weight: 600;
793                    margin-bottom: 8px;
794                }
795
796                .ai-assistant-workflow-step-action {
797                    font-size: 13px;
798                    color: #495057;
799                    line-height: 1.6;
800                }
801
802                .ai-assistant-empty {
803                    text-align: center;
804                    padding: 40px 20px;
805                    color: #6c757d;
806                    font-size: 14px;
807                }
808
809                .ai-assistant-history-item {
810                    background: white;
811                    border: 1px solid #e9ecef;
812                    border-radius: 8px;
813                    padding: 12px;
814                    margin-bottom: 12px;
815                    cursor: pointer;
816                    transition: border-color 0.2s, box-shadow 0.2s;
817                }
818
819                .ai-assistant-history-item:hover {
820                    border-color: #667eea;
821                    box-shadow: 0 2px 8px rgba(102, 126, 234, 0.1);
822                }
823
824                .ai-assistant-history-prompt {
825                    font-size: 13px;
826                    color: #212529;
827                    font-weight: 500;
828                    margin-bottom: 6px;
829                    display: -webkit-box;
830                    -webkit-line-clamp: 2;
831                    -webkit-box-orient: vertical;
832                    overflow: hidden;
833                }
834
835                .ai-assistant-history-date {
836                    font-size: 11px;
837                    color: #6c757d;
838                }
839
840                .ai-assistant-badge {
841                    display: inline-block;
842                    padding: 4px 8px;
843                    background: #667eea;
844                    color: white;
845                    border-radius: 12px;
846                    font-size: 11px;
847                    font-weight: 600;
848                    margin-left: 8px;
849                }
850            `;
851
852            TM_addStyle(styles);
853        }
854
855        static createMainUI() {
856            const container = document.createElement('div');
857            container.className = 'ai-assistant-container';
858            container.innerHTML = `
859                <button class="ai-assistant-button" id="ai-assistant-toggle" title="AI Assistant">
860861                </button>
862                <div class="ai-assistant-panel" id="ai-assistant-panel">
863                    <div class="ai-assistant-header">
864                        <span>🚀 AI Assistant</span>
865                        <button class="ai-assistant-close" id="ai-assistant-close">×</button>
866                    </div>
867                    <div class="ai-assistant-tabs">
868                        <button class="ai-assistant-tab active" data-tab="optimize">Optimize</button>
869                        <button class="ai-assistant-tab" data-tab="variations">Variations</button>
870                        <button class="ai-assistant-tab" data-tab="workflow">Workflow</button>
871                        <button class="ai-assistant-tab" data-tab="use-cases">Use Cases</button>
872                        <button class="ai-assistant-tab" data-tab="history">History</button>
873                    </div>
874                    <div class="ai-assistant-content" id="ai-assistant-content">
875                        ${this.getOptimizeTabContent()}
876                    </div>
877                </div>
878            `;
879
880            document.body.appendChild(container);
881            this.attachEventListeners();
882        }
883
884        static getOptimizeTabContent() {
885            return `
886                <div class="ai-assistant-input-group">
887                    <label class="ai-assistant-label">Enter your prompt to analyze and optimize:</label>
888                    <textarea 
889                        class="ai-assistant-textarea" 
890                        id="ai-assistant-prompt-input" 
891                        placeholder="Example: Write a blog post about AI..."
892                    ></textarea>
893                </div>
894                <button class="ai-assistant-button-primary" id="ai-assistant-analyze">
895                    🔍 Analyze & Optimize
896                </button>
897                <div id="ai-assistant-results"></div>
898            `;
899        }
900
901        static getVariationsTabContent() {
902            return `
903                <div class="ai-assistant-input-group">
904                    <label class="ai-assistant-label">Enter your prompt to generate variations:</label>
905                    <textarea 
906                        class="ai-assistant-textarea" 
907                        id="ai-assistant-variations-input" 
908                        placeholder="Example: Explain quantum computing..."
909                    ></textarea>
910                </div>
911                <button class="ai-assistant-button-primary" id="ai-assistant-generate-variations">
912                    🎨 Generate Variations
913                </button>
914                <div id="ai-assistant-variations-results"></div>
915            `;
916        }
917
918        static getWorkflowTabContent() {
919            return `
920                <div class="ai-assistant-input-group">
921                    <label class="ai-assistant-label">Describe your goal or project:</label>
922                    <textarea 
923                        class="ai-assistant-textarea" 
924                        id="ai-assistant-workflow-input" 
925                        placeholder="Example: Create a landing page for a SaaS product..."
926                    ></textarea>
927                </div>
928                <button class="ai-assistant-button-primary" id="ai-assistant-generate-workflow">
929                    🔄 Generate Workflow
930                </button>
931                <div id="ai-assistant-workflow-results"></div>
932            `;
933        }
934
935        static getUseCasesTabContent() {
936            return `
937                <div class="ai-assistant-input-group">
938                    <label class="ai-assistant-label">Enter a topic or technology:</label>
939                    <textarea 
940                        class="ai-assistant-textarea" 
941                        id="ai-assistant-usecase-input" 
942                        placeholder="Example: AI in healthcare, blockchain, etc..."
943                    ></textarea>
944                </div>
945                <button class="ai-assistant-button-primary" id="ai-assistant-generate-usecases">
946                    💡 Generate Use Cases
947                </button>
948                <div id="ai-assistant-usecases-results"></div>
949            `;
950        }
951
952        static async getHistoryTabContent() {
953            const history = await StorageManager.get(CONFIG.storageKeys.history, []);
954            
955            if (history.length === 0) {
956                return `
957                    <div class="ai-assistant-empty">
958                        📝 No history yet. Start analyzing prompts to build your history!
959                    </div>
960                `;
961            }
962
963            return `
964                <div class="ai-assistant-list">
965                    ${history.map(item => `
966                        <div class="ai-assistant-history-item" data-prompt="${this.escapeHtml(item.prompt)}">
967                            <div class="ai-assistant-history-prompt">${this.escapeHtml(item.prompt)}</div>
968                            <div class="ai-assistant-history-date">${new Date(item.timestamp).toLocaleString()}</div>
969                        </div>
970                    `).join('')}
971                </div>
972            `;
973        }
974
975        static escapeHtml(text) {
976            const div = document.createElement('div');
977            div.textContent = text;
978            return div.innerHTML;
979        }
980
981        static attachEventListeners() {
982            // Toggle panel
983            document.getElementById('ai-assistant-toggle').addEventListener('click', () => {
984                document.getElementById('ai-assistant-panel').classList.toggle('active');
985            });
986
987            document.getElementById('ai-assistant-close').addEventListener('click', () => {
988                document.getElementById('ai-assistant-panel').classList.remove('active');
989            });
990
991            // Tab switching
992            document.querySelectorAll('.ai-assistant-tab').forEach(tab => {
993                tab.addEventListener('click', async (e) => {
994                    document.querySelectorAll('.ai-assistant-tab').forEach(t => t.classList.remove('active'));
995                    e.target.classList.add('active');
996                    
997                    const tabName = e.target.dataset.tab;
998                    const content = document.getElementById('ai-assistant-content');
999                    
1000                    switch(tabName) {
1001                        case 'optimize':
1002                            content.innerHTML = this.getOptimizeTabContent();
1003                            this.attachOptimizeListeners();
1004                            break;
1005                        case 'variations':
1006                            content.innerHTML = this.getVariationsTabContent();
1007                            this.attachVariationsListeners();
1008                            break;
1009                        case 'workflow':
1010                            content.innerHTML = this.getWorkflowTabContent();
1011                            this.attachWorkflowListeners();
1012                            break;
1013                        case 'use-cases':
1014                            content.innerHTML = this.getUseCasesTabContent();
1015                            this.attachUseCasesListeners();
1016                            break;
1017                        case 'history':
1018                            content.innerHTML = await this.getHistoryTabContent();
1019                            this.attachHistoryListeners();
1020                            break;
1021                    }
1022                });
1023            });
1024
1025            // Initial listeners
1026            this.attachOptimizeListeners();
1027        }
1028
1029        static attachOptimizeListeners() {
1030            const analyzeBtn = document.getElementById('ai-assistant-analyze');
1031            if (analyzeBtn) {
1032                analyzeBtn.addEventListener('click', async () => {
1033                    const prompt = document.getElementById('ai-assistant-prompt-input').value.trim();
1034                    if (!prompt) {
1035                        alert('Please enter a prompt to analyze');
1036                        return;
1037                    }
1038
1039                    analyzeBtn.disabled = true;
1040                    analyzeBtn.textContent = '⏳ Analyzing...';
1041                    
1042                    const resultsDiv = document.getElementById('ai-assistant-results');
1043                    resultsDiv.innerHTML = `
1044                        <div class="ai-assistant-loading">
1045                            <div class="ai-assistant-spinner"></div>
1046                            <div>Analyzing your prompt with AI...</div>
1047                        </div>
1048                    `;
1049
1050                    try {
1051                        const analysis = await PromptOptimizer.analyzePrompt(prompt);
1052                        const questions = await PromptOptimizer.generateClarifyingQuestions(prompt, analysis);
1053                        
1054                        // Save to history
1055                        await StorageManager.append(CONFIG.storageKeys.history, {
1056                            prompt,
1057                            analysis,
1058                            timestamp: new Date().toISOString()
1059                        });
1060
1061                        resultsDiv.innerHTML = this.renderAnalysisResults(analysis, questions);
1062                    } catch (error) {
1063                        resultsDiv.innerHTML = `
1064                            <div class="ai-assistant-result">
1065                                <div class="ai-assistant-result-title">❌ Error</div>
1066                                <div class="ai-assistant-result-content">${error.message}</div>
1067                            </div>
1068                        `;
1069                    } finally {
1070                        analyzeBtn.disabled = false;
1071                        analyzeBtn.textContent = '🔍 Analyze & Optimize';
1072                    }
1073                });
1074            }
1075        }
1076
1077        static attachVariationsListeners() {
1078            const generateBtn = document.getElementById('ai-assistant-generate-variations');
1079            if (generateBtn) {
1080                generateBtn.addEventListener('click', async () => {
1081                    const prompt = document.getElementById('ai-assistant-variations-input').value.trim();
1082                    if (!prompt) {
1083                        alert('Please enter a prompt to generate variations');
1084                        return;
1085                    }
1086
1087                    generateBtn.disabled = true;
1088                    generateBtn.textContent = '⏳ Generating...';
1089                    
1090                    const resultsDiv = document.getElementById('ai-assistant-variations-results');
1091                    resultsDiv.innerHTML = `
1092                        <div class="ai-assistant-loading">
1093                            <div class="ai-assistant-spinner"></div>
1094                            <div>Generating prompt variations...</div>
1095                        </div>
1096                    `;
1097
1098                    try {
1099                        const variations = await PromptOptimizer.generateVariations(prompt);
1100                        resultsDiv.innerHTML = this.renderVariations(variations);
1101                    } catch (error) {
1102                        resultsDiv.innerHTML = `
1103                            <div class="ai-assistant-result">
1104                                <div class="ai-assistant-result-title">❌ Error</div>
1105                                <div class="ai-assistant-result-content">${error.message}</div>
1106                            </div>
1107                        `;
1108                    } finally {
1109                        generateBtn.disabled = false;
1110                        generateBtn.textContent = '🎨 Generate Variations';
1111                    }
1112                });
1113            }
1114        }
1115
1116        static attachWorkflowListeners() {
1117            const generateBtn = document.getElementById('ai-assistant-generate-workflow');
1118            if (generateBtn) {
1119                generateBtn.addEventListener('click', async () => {
1120                    const goal = document.getElementById('ai-assistant-workflow-input').value.trim();
1121                    if (!goal) {
1122                        alert('Please describe your goal or project');
1123                        return;
1124                    }
1125
1126                    generateBtn.disabled = true;
1127                    generateBtn.textContent = '⏳ Generating...';
1128                    
1129                    const resultsDiv = document.getElementById('ai-assistant-workflow-results');
1130                    resultsDiv.innerHTML = `
1131                        <div class="ai-assistant-loading">
1132                            <div class="ai-assistant-spinner"></div>
1133                            <div>Creating your workflow...</div>
1134                        </div>
1135                    `;
1136
1137                    try {
1138                        const workflow = await WorkflowOrchestrator.generateWorkflow(goal);
1139                        resultsDiv.innerHTML = this.renderWorkflow(workflow);
1140                    } catch (error) {
1141                        resultsDiv.innerHTML = `
1142                            <div class="ai-assistant-result">
1143                                <div class="ai-assistant-result-title">❌ Error</div>
1144                                <div class="ai-assistant-result-content">${error.message}</div>
1145                            </div>
1146                        `;
1147                    } finally {
1148                        generateBtn.disabled = false;
1149                        generateBtn.textContent = '🔄 Generate Workflow';
1150                    }
1151                });
1152            }
1153        }
1154
1155        static attachUseCasesListeners() {
1156            const generateBtn = document.getElementById('ai-assistant-generate-usecases');
1157            if (generateBtn) {
1158                generateBtn.addEventListener('click', async () => {
1159                    const topic = document.getElementById('ai-assistant-usecase-input').value.trim();
1160                    if (!topic) {
1161                        alert('Please enter a topic or technology');
1162                        return;
1163                    }
1164
1165                    generateBtn.disabled = true;
1166                    generateBtn.textContent = '⏳ Generating...';
1167                    
1168                    const resultsDiv = document.getElementById('ai-assistant-usecases-results');
1169                    resultsDiv.innerHTML = `
1170                        <div class="ai-assistant-loading">
1171                            <div class="ai-assistant-spinner"></div>
1172                            <div>Generating innovative use cases...</div>
1173                        </div>
1174                    `;
1175
1176                    try {
1177                        const useCases = await UseCaseGenerator.generateUseCases(topic);
1178                        resultsDiv.innerHTML = this.renderUseCases(useCases);
1179                    } catch (error) {
1180                        resultsDiv.innerHTML = `
1181                            <div class="ai-assistant-result">
1182                                <div class="ai-assistant-result-title">❌ Error</div>
1183                                <div class="ai-assistant-result-content">${error.message}</div>
1184                            </div>
1185                        `;
1186                    } finally {
1187                        generateBtn.disabled = false;
1188                        generateBtn.textContent = '💡 Generate Use Cases';
1189                    }
1190                });
1191            }
1192        }
1193
1194        static attachHistoryListeners() {
1195            document.querySelectorAll('.ai-assistant-history-item').forEach(item => {
1196                item.addEventListener('click', () => {
1197                    const prompt = item.dataset.prompt;
1198                    document.querySelector('.ai-assistant-tab[data-tab="optimize"]').click();
1199                    setTimeout(() => {
1200                        document.getElementById('ai-assistant-prompt-input').value = prompt;
1201                    }, 100);
1202                });
1203            });
1204        }
1205
1206        static renderAnalysisResults(analysis, questions) {
1207            return `
1208                <div class="ai-assistant-result">
1209                    <div class="ai-assistant-result-title">📊 Analysis Results</div>
1210                    <div class="ai-assistant-score">
1211                        Clarity: ${analysis.clarityScore}/10
1212                        <div class="ai-assistant-score-bar">
1213                            <div class="ai-assistant-score-fill" style="width: ${analysis.clarityScore * 10}%"></div>
1214                        </div>
1215                    </div>
1216                    <div class="ai-assistant-score">
1217                        Completeness: ${analysis.completenessScore}/10
1218                        <div class="ai-assistant-score-bar">
1219                            <div class="ai-assistant-score-fill" style="width: ${analysis.completenessScore * 10}%"></div>
1220                        </div>
1221                    </div>
1222                </div>
1223
1224                ${analysis.issues.length > 0 ? `
1225                    <div class="ai-assistant-result">
1226                        <div class="ai-assistant-result-title">⚠️ Issues Identified</div>
1227                        <ul class="ai-assistant-list">
1228                            ${analysis.issues.map(issue => `
1229                                <li class="ai-assistant-list-item">${this.escapeHtml(issue)}</li>
1230                            `).join('')}
1231                        </ul>
1232                    </div>
1233                ` : ''}
1234
1235                ${analysis.suggestions.length > 0 ? `
1236                    <div class="ai-assistant-result">
1237                        <div class="ai-assistant-result-title">💡 Suggestions</div>
1238                        <ul class="ai-assistant-list">
1239                            ${analysis.suggestions.map(suggestion => `
1240                                <li class="ai-assistant-list-item">${this.escapeHtml(suggestion)}</li>
1241                            `).join('')}
1242                        </ul>
1243                    </div>
1244                ` : ''}
1245
1246                ${questions.length > 0 ? `
1247                    <div class="ai-assistant-result">
1248                        <div class="ai-assistant-result-title">❓ Clarifying Questions</div>
1249                        <ul class="ai-assistant-list">
1250                            ${questions.map(q => `
1251                                <li class="ai-assistant-list-item">
1252                                    <strong>${this.escapeHtml(q.question)}</strong><br>
1253                                    <small style="color: #6c757d;">${this.escapeHtml(q.purpose)}</small>
1254                                </li>
1255                            `).join('')}
1256                        </ul>
1257                    </div>
1258                ` : ''}
1259            `;
1260        }
1261
1262        static renderVariations(variations) {
1263            if (!variations || variations.length === 0) {
1264                return '<div class="ai-assistant-empty">No variations generated</div>';
1265            }
1266
1267            return variations.map(v => `
1268                <div class="ai-assistant-variation">
1269                    <div class="ai-assistant-variation-header">
1270                        <span class="ai-assistant-variation-style">${this.escapeHtml(v.style)}</span>
1271                        <span class="ai-assistant-variation-platform">${this.escapeHtml(v.platform)}</span>
1272                    </div>
1273                    <div class="ai-assistant-variation-prompt">${this.escapeHtml(v.prompt)}</div>
1274                    ${v.reasoning ? `<div class="ai-assistant-result-content" style="font-size: 12px; color: #6c757d; margin-bottom: 8px;">${this.escapeHtml(v.reasoning)}</div>` : ''}
1275                    <div class="ai-assistant-variation-actions">
1276                        <button class="ai-assistant-button-small" onclick="navigator.clipboard.writeText('${this.escapeHtml(v.prompt).replace(/'/g, "\\'")}'); this.textContent='✓ Copied!'">
1277                            📋 Copy
1278                        </button>
1279                        <button class="ai-assistant-button-small ai-assistant-button-secondary" onclick="window.open('${this.getPlatformUrl(v.platform)}', '_blank')">
1280                            🚀 Open ${this.escapeHtml(v.platform)}
1281                        </button>
1282                    </div>
1283                </div>
1284            `).join('');
1285        }
1286
1287        static renderWorkflow(workflow) {
1288            if (!workflow || !workflow.steps) {
1289                return '<div class="ai-assistant-empty">No workflow generated</div>';
1290            }
1291
1292            return `
1293                <div class="ai-assistant-result">
1294                    <div class="ai-assistant-result-title">🔄 ${this.escapeHtml(workflow.workflowName)}</div>
1295                    ${workflow.description ? `<div class="ai-assistant-result-content">${this.escapeHtml(workflow.description)}</div>` : ''}
1296                    ${workflow.estimatedTime ? `<div class="ai-assistant-badge">⏱️ ${this.escapeHtml(workflow.estimatedTime)}</div>` : ''}
1297                </div>
1298
1299                ${workflow.steps.map(step => `
1300                    <div class="ai-assistant-workflow-step">
1301                        <div>
1302                            <span class="ai-assistant-workflow-step-number">${step.stepNumber}</span>
1303                            <span class="ai-assistant-workflow-step-title">${this.escapeHtml(step.title)}</span>
1304                        </div>
1305                        <div class="ai-assistant-workflow-step-platform">${this.escapeHtml(step.platform)}</div>
1306                        <div class="ai-assistant-workflow-step-action">${this.escapeHtml(step.action)}</div>
1307                        ${step.prompt ? `
1308                            <div style="margin-top: 8px;">
1309                                <button class="ai-assistant-button-small" onclick="navigator.clipboard.writeText('${this.escapeHtml(step.prompt).replace(/'/g, "\\'")}'); this.textContent='✓ Copied!'">
1310                                    📋 Copy Prompt
1311                                </button>
1312                            </div>
1313                        ` : ''}
1314                    </div>
1315                `).join('')}
1316            `;
1317        }
1318
1319        static renderUseCases(useCases) {
1320            if (!useCases || useCases.length === 0) {
1321                return '<div class="ai-assistant-empty">No use cases generated</div>';
1322            }
1323
1324            return useCases.map(uc => `
1325                <div class="ai-assistant-result">
1326                    <div class="ai-assistant-result-title">
1327                        ${this.escapeHtml(uc.title)}
1328                        ${uc.difficulty ? `<span class="ai-assistant-badge">${this.escapeHtml(uc.difficulty)}</span>` : ''}
1329                    </div>
1330                    ${uc.domain ? `<div style="font-size: 12px; color: #667eea; font-weight: 600; margin-bottom: 8px;">📁 ${this.escapeHtml(uc.domain)}</div>` : ''}
1331                    <div class="ai-assistant-result-content">${this.escapeHtml(uc.description)}</div>
1332                    ${uc.implementation ? `
1333                        <div style="margin-top: 12px; padding-top: 12px; border-top: 1px solid #e9ecef;">
1334                            <div style="font-weight: 600; font-size: 12px; color: #495057; margin-bottom: 6px;">Implementation:</div>
1335                            <div class="ai-assistant-result-content">${this.escapeHtml(uc.implementation)}</div>
1336                        </div>
1337                    ` : ''}
1338                    ${uc.platforms && uc.platforms.length > 0 ? `
1339                        <div style="margin-top: 8px;">
1340                            ${uc.platforms.map(p => `<span class="ai-assistant-badge" style="background: #6c757d;">${this.escapeHtml(p)}</span>`).join(' ')}
1341                        </div>
1342                    ` : ''}
1343                </div>
1344            `).join('');
1345        }
1346
1347        static getPlatformUrl(platformName) {
1348            const platform = Object.values(CONFIG.platforms).find(p => 
1349                p.name.toLowerCase().includes(platformName.toLowerCase())
1350            );
1351            return platform?.url || 'https://perplexity.ai';
1352        }
1353    }
1354
1355    // ============================================================================
1356    // INITIALIZATION
1357    // ============================================================================
1358
1359    async function init() {
1360        console.log('🎯 Initializing Perplexity AI Assistant...');
1361        
1362        // Wait for page to be ready
1363        if (document.readyState === 'loading') {
1364            document.addEventListener('DOMContentLoaded', init);
1365            return;
1366        }
1367
1368        // Inject styles and create UI
1369        UIManager.injectStyles();
1370        
1371        // Wait a bit for page to fully load
1372        setTimeout(() => {
1373            UIManager.createMainUI();
1374            console.log('✅ Perplexity AI Assistant ready!');
1375        }, 1000);
1376    }
1377
1378    // Start the extension
1379    init();
1380
1381})();
Perplexity AI Assistant - Prompt Optimizer & Workflow Orchestrator | Robomonkey