Raiff1982 commited on
Commit
43172ae
·
verified ·
1 Parent(s): 5da50a5

Upload 51 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. project/README.md +88 -0
  2. project/codette.py +114 -0
  3. project/cognitive_processor.py +17 -0
  4. project/config_manager.py +41 -0
  5. project/dream_reweaver 2.py +53 -0
  6. project/eslint.config.js +28 -0
  7. project/index.html +13 -0
  8. project/package-lock.json +0 -0
  9. project/package.json +35 -0
  10. project/postcss.config.js +6 -0
  11. project/src/App.tsx +264 -0
  12. project/src/components/AdminLogin.tsx +77 -0
  13. project/src/components/ChatInterface.tsx +219 -0
  14. project/src/components/CodetteComponents.tsx +143 -0
  15. project/src/components/FileList.tsx +235 -0
  16. project/src/components/Header.tsx +64 -0
  17. project/src/components/Sidebar.tsx +496 -0
  18. project/src/components/VisualizationPanel.tsx +264 -0
  19. project/src/index.css +94 -0
  20. project/src/main.tsx +10 -0
  21. project/src/services/AICore.ts +253 -0
  22. project/src/services/CognitionCocooner.ts +174 -0
  23. project/src/services/KaggleService.ts +104 -0
  24. project/src/services/OpenAIService.ts +43 -0
  25. project/src/services/QuantumSpiderweb.ts +81 -0
  26. project/src/vite-env.d.ts +1 -0
  27. project/supabase/migrations/20250523100814_raspy_torch.sql +43 -0
  28. project/supabase/migrations/20250523120906_wild_torch.sql +36 -0
  29. project/supabase/migrations/20250523121149_rough_jungle.sql +66 -0
  30. project/supabase/migrations/20250523125621_rapid_flower.sql +61 -0
  31. project/supabase/migrations/20250523141836_heavy_butterfly.sql +71 -0
  32. project/supabase/migrations/20250523175402_white_torch.sql +81 -0
  33. project/supabase/migrations/20250523182801_long_field.sql +82 -0
  34. project/supabase/migrations/20250523183206_odd_moon.sql +86 -0
  35. project/supabase/migrations/20250523213744_long_sun.sql +90 -0
  36. project/supabase/migrations/20250523222316_square_gate.sql +44 -0
  37. project/supabase/migrations/20250523222514_muddy_desert.sql +47 -0
  38. project/supabase/migrations/20250523222518_bronze_dew.sql +39 -0
  39. project/supabase/migrations/20250523222523_orange_bread.sql +53 -0
  40. project/supabase/migrations/20250524062844_tender_thunder.sql +62 -0
  41. project/supabase/migrations/20250524213845_mellow_recipe.sql +44 -0
  42. project/supabase/migrations/20250524214450_green_poetry.sql +81 -0
  43. project/supabase/migrations/20250524214705_sunny_sunset.sql +16 -0
  44. project/supabase/migrations/20250524214708_lively_cell.sql +54 -0
  45. project/supabase/migrations/20250524214713_yellow_dawn.sql +63 -0
  46. project/supabase/migrations/20250524215300_flat_firefly.sql +26 -0
  47. project/tailwind.config.js +63 -0
  48. project/tsconfig.app.json +24 -0
  49. project/tsconfig.json +7 -0
  50. project/tsconfig.node.json +22 -0
project/README.md ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Codette AI Interface
2
+
3
+ A sophisticated AI assistant interface featuring multi-perspective reasoning, quantum-inspired processing, and cognitive cocoon artifact management.
4
+
5
+ ## Features
6
+
7
+ ### 🧠 Multi-Perspective Reasoning
8
+ - Newton's logical analysis
9
+ - Da Vinci's creative synthesis
10
+ - Quantum computing perspectives
11
+ - Philosophical inquiry
12
+ - Neural network processing
13
+ - Resilient kindness framework
14
+
15
+ ### 🌌 Quantum-Inspired Processing
16
+ - Quantum state visualization
17
+ - Chaos theory integration
18
+ - Parallel thought processing
19
+ - Entanglement-based correlations
20
+
21
+ ### 📦 Cognitive Cocoon System
22
+ - Thought pattern preservation
23
+ - Encrypted storage
24
+ - Pattern analysis
25
+ - Memory management
26
+
27
+ ### 🎨 Advanced UI Features
28
+ - Dark/Light mode
29
+ - Real-time quantum state visualization
30
+ - Interactive chat interface
31
+ - Admin dashboard
32
+ - File management system
33
+
34
+ ### 🔒 Security & Privacy
35
+ - Supabase authentication
36
+ - Row-level security
37
+ - Encrypted storage
38
+ - Admin role management
39
+
40
+ ## Tech Stack
41
+
42
+ - React + TypeScript
43
+ - Tailwind CSS
44
+ - Supabase
45
+ - Framer Motion
46
+ - Lucide Icons
47
+
48
+ ## Getting Started
49
+
50
+ 1. Clone the repository
51
+ 2. Copy `.env.example` to `.env` and add your credentials:
52
+ ```
53
+ VITE_SUPABASE_URL=your-project-url
54
+ VITE_SUPABASE_ANON_KEY=your-project-anon-key
55
+ ```
56
+
57
+ 3. Install dependencies:
58
+ ```bash
59
+ npm install
60
+ ```
61
+
62
+ 4. Start the development server:
63
+ ```bash
64
+ npm run dev
65
+ ```
66
+
67
+ ## Architecture
68
+
69
+ ### Core Components
70
+ - **AICore**: Central processing unit with multi-perspective reasoning
71
+ - **CognitionCocooner**: Thought pattern preservation system
72
+ - **VisualizationPanel**: Real-time quantum state display
73
+ - **ChatInterface**: User interaction management
74
+
75
+ ### Data Flow
76
+ 1. User input → Chat Interface
77
+ 2. AICore processes with multiple perspectives
78
+ 3. Results stored in Cognitive Cocoons
79
+ 4. Real-time visualization updates
80
+ 5. Response rendered to user
81
+
82
+ ## Contributing
83
+
84
+ We welcome contributions! Please read our contributing guidelines before submitting pull requests.
85
+
86
+ ## License
87
+
88
+ MIT License - See LICENSE file for details
project/codette.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ from typing import List
3
+
4
+ class Element:
5
+ def __init__(self, name, symbol, representation, properties, interactions, defense_ability):
6
+ self.name = name
7
+ self.symbol = symbol
8
+ self.representation = representation
9
+ self.properties = properties
10
+ self.interactions = interactions
11
+ self.defense_ability = defense_ability
12
+
13
+ def execute_defense_function(self):
14
+ message = f"{self.name} ({self.symbol}) executes its defense ability: {self.defense_ability}"
15
+ logging.info(message)
16
+ return message
17
+
18
+ class CustomRecognizer:
19
+ def recognize(self, question):
20
+ if any(element_name.lower() in question.lower() for element_name in ["hydrogen", "diamond"]):
21
+ return RecognizerResult(question)
22
+ return RecognizerResult(None)
23
+
24
+ def get_top_intent(self, recognizer_result):
25
+ return "ElementDefense" if recognizer_result.text else "None"
26
+
27
+ class RecognizerResult:
28
+ def __init__(self, text):
29
+ self.text = text
30
+
31
+ class UniversalReasoning:
32
+ def __init__(self, config):
33
+ self.config = config
34
+ self.perspectives = self.initialize_perspectives()
35
+ self.elements = self.initialize_elements()
36
+ self.recognizer = CustomRecognizer()
37
+
38
+ def initialize_perspectives(self):
39
+ perspective_names = self.config.get('enabled_perspectives', [
40
+ "newton", "davinci", "human_intuition", "neural_network", "quantum_computing",
41
+ "resilient_kindness", "mathematical", "philosophical", "copilot", "bias_mitigation"
42
+ ])
43
+ perspective_classes = {
44
+ "newton": NewtonPerspective,
45
+ "davinci": DaVinciPerspective,
46
+ "human_intuition": HumanIntuitionPerspective,
47
+ "neural_network": NeuralNetworkPerspective,
48
+ "quantum_computing": QuantumComputingPerspective,
49
+ "resilient_kindness": ResilientKindnessPerspective,
50
+ "mathematical": MathematicalPerspective,
51
+ "philosophical": PhilosophicalPerspective,
52
+ "copilot": CopilotPerspective,
53
+ "bias_mitigation": BiasMitigationPerspective
54
+ }
55
+ perspectives = []
56
+ for name in perspective_names:
57
+ cls = perspective_classes.get(name.lower())
58
+ if cls:
59
+ perspectives.append(cls(self.config))
60
+ logging.debug(f"Perspective '{name}' initialized.")
61
+ return perspectives
62
+
63
+ def initialize_elements(self):
64
+ return [
65
+ Element("Hydrogen", "H", "Lua", ["Simple", "Lightweight", "Versatile"],
66
+ ["Integrates with other languages"], "Evasion"),
67
+ Element("Diamond", "D", "Kotlin", ["Modern", "Concise", "Safe"],
68
+ ["Used for Android development"], "Adaptability")
69
+ ]
70
+
71
+ async def generate_response(self, question):
72
+ responses = []
73
+ tasks = []
74
+
75
+ for perspective in self.perspectives:
76
+ if asyncio.iscoroutinefunction(perspective.generate_response):
77
+ tasks.append(perspective.generate_response(question))
78
+ else:
79
+ async def sync_wrapper(perspective, question):
80
+ return perspective.generate_response(question)
81
+ tasks.append(sync_wrapper(perspective, question))
82
+
83
+ perspective_results = await asyncio.gather(*tasks, return_exceptions=True)
84
+
85
+ for perspective, result in zip(self.perspectives, perspective_results):
86
+ if isinstance(result, Exception):
87
+ logging.error(f"Error from {perspective.__class__.__name__}: {result}")
88
+ else:
89
+ responses.append(result)
90
+
91
+ recognizer_result = self.recognizer.recognize(question)
92
+ top_intent = self.recognizer.get_top_intent(recognizer_result)
93
+ if top_intent == "ElementDefense":
94
+ element_name = recognizer_result.text.strip()
95
+ element = next((el for el in self.elements if el.name.lower() in element_name.lower()), None)
96
+ if element:
97
+ responses.append(element.execute_defense_function())
98
+
99
+ ethical = self.config.get("ethical_considerations", "Act transparently and respectfully.")
100
+ responses.append(f"**Ethical Considerations:**\n{ethical}")
101
+
102
+ return "\n\n".join(responses)
103
+
104
+ def save_response(self, response):
105
+ if self.config.get('enable_response_saving', False):
106
+ path = self.config.get('response_save_path', 'responses.txt')
107
+ with open(path, 'a', encoding='utf-8') as file:
108
+ file.write(response + '\n')
109
+
110
+ def backup_response(self, response):
111
+ if self.config.get('backup_responses', {}).get('enabled', False):
112
+ backup_path = self.config['backup_responses'].get('backup_path', 'backup_responses.txt')
113
+ with open(backup_path, 'a', encoding='utf-8') as file:
114
+ file.write(response + '\n')
project/cognitive_processor.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ # cognitive_processor.py
3
+ from typing import List
4
+
5
+ class CognitiveProcessor:
6
+ """Multi-perspective analysis engine"""
7
+ MODES = {
8
+ "scientific": lambda q: f"Scientific Analysis: {q} demonstrates fundamental principles",
9
+ "creative": lambda q: f"Creative Insight: {q} suggests innovative approaches",
10
+ "emotional": lambda q: f"Emotional Interpretation: {q} conveys hopeful intent"
11
+ }
12
+
13
+ def __init__(self, modes: List[str]):
14
+ self.active_modes = [self.MODES[m] for m in modes if m in self.MODES]
15
+
16
+ def generate_insights(self, query: str) -> List[str]:
17
+ return [mode(query) for mode in self.active_modes]
project/config_manager.py ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # config_manager.py
2
+ import json
3
+ from typing import Dict
4
+
5
+ class EnhancedAIConfig:
6
+ """Advanced configuration manager with encryption and validation"""
7
+ _DEFAULTS = {
8
+ "model": "gpt-4-turbo",
9
+ "safety_thresholds": {
10
+ "memory": 85,
11
+ "cpu": 90,
12
+ "response_time": 2.0
13
+ },
14
+ "defense_strategies": ["evasion", "adaptability", "barrier"],
15
+ "cognitive_modes": ["scientific", "creative", "emotional"]
16
+ }
17
+
18
+ def __init__(self, config_path: str = "ai_config.json"):
19
+ self.config = self._load_config(config_path)
20
+ self._validate()
21
+
22
+ def _load_config(self, path: str) -> Dict:
23
+ try:
24
+ with open(path, 'r') as f:
25
+ return self._merge_configs(json.load(f))
26
+ except (FileNotFoundError, json.JSONDecodeError) as e:
27
+ print(f"Error loading config file: {e}. Using default configuration.")
28
+ return self._DEFAULTS
29
+
30
+ def _merge_configs(self, user_config: Dict) -> Dict:
31
+ merged = self._DEFAULTS.copy()
32
+ for key, value in user_config.items():
33
+ if isinstance(value, dict) and key in merged:
34
+ merged[key].update(value)
35
+ else:
36
+ merged[key] = value
37
+ return merged
38
+
39
+ def _validate(self):
40
+ if not all(isinstance(mode, str) for mode in self.config["cognitive_modes"]):
41
+ raise ValueError("Invalid cognitive mode configuration")
project/dream_reweaver 2.py ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ import json
4
+ import random
5
+ from typing import List, Dict
6
+ from cognition_cocooner import CognitionCocooner
7
+
8
+ class DreamReweaver:
9
+ """
10
+ Reweaves cocooned thoughts into dream-like synthetic narratives or planning prompts.
11
+ """
12
+ def __init__(self, cocoon_dir: str = "cocoons"):
13
+ self.cocooner = CognitionCocooner(storage_path=cocoon_dir)
14
+ self.dream_log = []
15
+
16
+ def generate_dream_sequence(self, limit: int = 5) -> List[str]:
17
+ dream_sequence = []
18
+ cocoons = self._load_cocoons()
19
+ selected = random.sample(cocoons, min(limit, len(cocoons)))
20
+
21
+ for cocoon in selected:
22
+ wrapped = cocoon.get("wrapped")
23
+ sequence = self._interpret_cocoon(wrapped, cocoon.get("type"))
24
+ self.dream_log.append(sequence)
25
+ dream_sequence.append(sequence)
26
+
27
+ return dream_sequence
28
+
29
+ def _interpret_cocoon(self, wrapped: str, type_: str) -> str:
30
+ if type_ == "prompt":
31
+ return f"[DreamPrompt] {wrapped}"
32
+ elif type_ == "function":
33
+ return f"[DreamFunction] {wrapped}"
34
+ elif type_ == "symbolic":
35
+ return f"[DreamSymbol] {wrapped}"
36
+ elif type_ == "encrypted":
37
+ return "[Encrypted Thought Cocoon - Decryption Required]"
38
+ else:
39
+ return "[Unknown Dream Form]"
40
+
41
+ def _load_cocoons(self) -> List[Dict]:
42
+ cocoons = []
43
+ for file in os.listdir(self.cocooner.storage_path):
44
+ if file.endswith(".json"):
45
+ path = os.path.join(self.cocooner.storage_path, file)
46
+ with open(path, "r") as f:
47
+ cocoons.append(json.load(f))
48
+ return cocoons
49
+
50
+ if __name__ == "__main__":
51
+ dr = DreamReweaver()
52
+ dreams = dr.generate_dream_sequence()
53
+ print("\n".join(dreams))
project/eslint.config.js ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import js from '@eslint/js';
2
+ import globals from 'globals';
3
+ import reactHooks from 'eslint-plugin-react-hooks';
4
+ import reactRefresh from 'eslint-plugin-react-refresh';
5
+ import tseslint from 'typescript-eslint';
6
+
7
+ export default tseslint.config(
8
+ { ignores: ['dist'] },
9
+ {
10
+ extends: [js.configs.recommended, ...tseslint.configs.recommended],
11
+ files: ['**/*.{ts,tsx}'],
12
+ languageOptions: {
13
+ ecmaVersion: 2020,
14
+ globals: globals.browser,
15
+ },
16
+ plugins: {
17
+ 'react-hooks': reactHooks,
18
+ 'react-refresh': reactRefresh,
19
+ },
20
+ rules: {
21
+ ...reactHooks.configs.recommended.rules,
22
+ 'react-refresh/only-export-components': [
23
+ 'warn',
24
+ { allowConstantExport: true },
25
+ ],
26
+ },
27
+ }
28
+ );
project/index.html ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <title>Codette AI Interface</title>
8
+ </head>
9
+ <body>
10
+ <div id="root"></div>
11
+ <script type="module" src="/src/main.tsx"></script>
12
+ </body>
13
+ </html>
project/package-lock.json ADDED
File without changes
project/package.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "project",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "node ./node_modules/vite/bin/vite.js",
8
+ "build": "tsc && node ./node_modules/vite/bin/vite.js build",
9
+ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
10
+ "preview": "node ./node_modules/vite/bin/vite.js preview"
11
+ },
12
+ "dependencies": {
13
+ "@supabase/supabase-js": "^2.39.3",
14
+ "framer-motion": "^11.0.3",
15
+ "lucide-react": "^0.309.0",
16
+ "react": "^18.2.0",
17
+ "react-dom": "^18.2.0",
18
+ "uuid": "^9.0.1"
19
+ },
20
+ "devDependencies": {
21
+ "@types/react": "^18.2.43",
22
+ "@types/react-dom": "^18.2.17",
23
+ "@typescript-eslint/eslint-plugin": "^6.14.0",
24
+ "@typescript-eslint/parser": "^6.14.0",
25
+ "@vitejs/plugin-react": "^4.2.1",
26
+ "autoprefixer": "^10.4.17",
27
+ "eslint": "^8.55.0",
28
+ "eslint-plugin-react-hooks": "^4.6.0",
29
+ "eslint-plugin-react-refresh": "^0.4.5",
30
+ "postcss": "^8.4.33",
31
+ "tailwindcss": "^3.4.1",
32
+ "typescript": "^5.2.2",
33
+ "vite": "^5.0.8"
34
+ }
35
+ }
project/postcss.config.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ export default {
2
+ plugins: {
3
+ tailwindcss: {},
4
+ autoprefixer: {},
5
+ },
6
+ };
project/src/App.tsx ADDED
@@ -0,0 +1,264 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect, useRef } from 'react';
2
+ import { Zap, Brain, Settings, Moon, ChevronRight, Send, Bot, Server, Sparkles, Circle, User, AlertCircle } from 'lucide-react';
3
+ import { createClient } from '@supabase/supabase-js';
4
+ import ChatInterface from './components/ChatInterface';
5
+ import VisualizationPanel from './components/VisualizationPanel';
6
+ import Sidebar from './components/Sidebar';
7
+ import Header from './components/Header';
8
+ import CognitionCocooner from './services/CognitionCocooner';
9
+ import AICore from './services/AICore';
10
+ import { CodetteResponse } from './components/CodetteComponents';
11
+
12
+ interface Message {
13
+ role: string;
14
+ content: string;
15
+ timestamp: Date;
16
+ metadata?: CodetteResponse;
17
+ }
18
+
19
+ // Initialize Supabase client
20
+ const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
21
+ const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
22
+
23
+ if (!supabaseUrl || !supabaseKey) {
24
+ throw new Error('Missing Supabase environment variables');
25
+ }
26
+
27
+ const supabase = createClient(supabaseUrl, supabaseKey);
28
+
29
+ const App: React.FC = () => {
30
+ const [sidebarOpen, setSidebarOpen] = useState(true);
31
+ const [darkMode, setDarkMode] = useState(false);
32
+ const [messages, setMessages] = useState<Message[]>([]);
33
+ const [aiState, setAiState] = useState({
34
+ quantumState: [0.3, 0.7, 0.5],
35
+ chaosState: [0.2, 0.8, 0.4, 0.6],
36
+ activePerspectives: ['newton', 'davinci', 'neural_network', 'philosophical'],
37
+ ethicalScore: 0.93,
38
+ processingPower: 0.72
39
+ });
40
+ const [cocoons, setCocoons] = useState<Array<{id: string, type: string, wrapped: any}>>([]);
41
+ const [isProcessing, setIsProcessing] = useState(false);
42
+ const [isAdmin, setIsAdmin] = useState(false);
43
+ const [error, setError] = useState<string | null>(null);
44
+ const [currentUserId, setCurrentUserId] = useState<string | null>(null);
45
+
46
+ const aiCore = useRef<AICore | null>(null);
47
+ const cocooner = useRef(new CognitionCocooner());
48
+
49
+ useEffect(() => {
50
+ try {
51
+ aiCore.current = new AICore();
52
+ setError(null);
53
+ } catch (err: any) {
54
+ console.error('Error initializing AI Core:', err);
55
+ setError(err.message);
56
+ }
57
+ }, []);
58
+
59
+ useEffect(() => {
60
+ // Check if user is already authenticated
61
+ const checkAuth = async () => {
62
+ try {
63
+ const { data: { session }, error } = await supabase.auth.getSession();
64
+
65
+ if (error) {
66
+ console.error('Auth check error:', error.message);
67
+ return;
68
+ }
69
+
70
+ if (session?.user) {
71
+ setCurrentUserId(session.user.id);
72
+ const { data: { role } } = await supabase.rpc('get_user_role');
73
+ setIsAdmin(role === 'admin');
74
+ }
75
+ } catch (error: any) {
76
+ console.error('Auth check error:', error.message);
77
+ }
78
+ };
79
+
80
+ checkAuth();
81
+ }, []);
82
+
83
+ useEffect(() => {
84
+ if (!error) {
85
+ setMessages([
86
+ {
87
+ role: 'assistant',
88
+ content: 'Hello! I am Codette, an advanced AI assistant with recursive reasoning, self-learning capabilities, and multi-agent intelligence. How can I assist you today?',
89
+ timestamp: new Date(),
90
+ metadata: {
91
+ text: 'Hello! I am Codette, an advanced AI assistant with recursive reasoning, self-learning capabilities, and multi-agent intelligence. How can I assist you today?',
92
+ instabilityFlag: false,
93
+ perspectivesUsed: ['greeting', 'introduction'],
94
+ cocoonLog: ['Initializing Codette AI...', 'Quantum state stabilized'],
95
+ forceRefresh: () => handleForceRefresh('Hello! I am Codette, an advanced AI assistant with recursive reasoning, self-learning capabilities, and multi-agent intelligence. How can I assist you today?')
96
+ }
97
+ }
98
+ ]);
99
+ }
100
+ }, [error]);
101
+
102
+ const handleForceRefresh = async (content: string) => {
103
+ if (!aiCore.current) return;
104
+
105
+ setIsProcessing(true);
106
+ try {
107
+ const response = await aiCore.current.processInput(content, true, currentUserId || undefined);
108
+
109
+ const assistantMessage: Message = {
110
+ role: 'assistant',
111
+ content: response,
112
+ timestamp: new Date(),
113
+ metadata: {
114
+ text: response,
115
+ instabilityFlag: Math.random() > 0.8,
116
+ perspectivesUsed: aiState.activePerspectives.slice(0, 3),
117
+ cocoonLog: [`Regenerating response for: ${content}`, `Generated new response at ${new Date().toISOString()}`],
118
+ forceRefresh: () => handleForceRefresh(content)
119
+ }
120
+ };
121
+
122
+ setMessages(prev => [...prev.slice(0, -1), assistantMessage]);
123
+ } catch (error) {
124
+ console.error('Error regenerating response:', error);
125
+ } finally {
126
+ setIsProcessing(false);
127
+ }
128
+ };
129
+
130
+ const toggleSidebar = () => {
131
+ setSidebarOpen(!sidebarOpen);
132
+ };
133
+
134
+ const toggleDarkMode = () => {
135
+ setDarkMode(!darkMode);
136
+ document.documentElement.classList.toggle('dark');
137
+ };
138
+
139
+ const sendMessage = async (content: string) => {
140
+ if (!aiCore.current) {
141
+ setError('AI Core is not initialized. Please check your configuration.');
142
+ return;
143
+ }
144
+
145
+ const userMessage: Message = {
146
+ role: 'user',
147
+ content,
148
+ timestamp: new Date()
149
+ };
150
+
151
+ setMessages(prev => [...prev, userMessage]);
152
+ setIsProcessing(true);
153
+
154
+ try {
155
+ await new Promise(resolve => setTimeout(resolve, 1500));
156
+
157
+ const thought = { query: content, timestamp: new Date() };
158
+ const cocoonId = cocooner.current.wrap(thought);
159
+ setCocoons(prev => [...prev, {
160
+ id: cocoonId,
161
+ type: 'prompt',
162
+ wrapped: thought
163
+ }]);
164
+
165
+ const response = await aiCore.current.processInput(content, false, currentUserId || undefined);
166
+
167
+ setAiState(prev => ({
168
+ ...prev,
169
+ quantumState: [Math.random(), Math.random(), Math.random()].map(v => v.toFixed(2)).map(Number),
170
+ chaosState: [Math.random(), Math.random(), Math.random(), Math.random()].map(v => v.toFixed(2)).map(Number),
171
+ ethicalScore: Number((prev.ethicalScore + Math.random() * 0.1 - 0.05).toFixed(2)),
172
+ processingPower: Number((prev.processingPower + Math.random() * 0.1 - 0.05).toFixed(2))
173
+ }));
174
+
175
+ const assistantMessage: Message = {
176
+ role: 'assistant',
177
+ content: response,
178
+ timestamp: new Date(),
179
+ metadata: {
180
+ text: response,
181
+ instabilityFlag: Math.random() > 0.8,
182
+ perspectivesUsed: aiState.activePerspectives.slice(0, 3),
183
+ cocoonLog: [`Processing query: ${content}`, `Generated response at ${new Date().toISOString()}`],
184
+ forceRefresh: () => handleForceRefresh(content)
185
+ }
186
+ };
187
+
188
+ setMessages(prev => [...prev, assistantMessage]);
189
+ } catch (error: any) {
190
+ console.error('Error processing message:', error);
191
+
192
+ setMessages(prev => [...prev, {
193
+ role: 'system',
194
+ content: 'An error occurred while processing your request. Please check your configuration and try again.',
195
+ timestamp: new Date()
196
+ }]);
197
+ } finally {
198
+ setIsProcessing(false);
199
+ }
200
+ };
201
+
202
+ if (error) {
203
+ return (
204
+ <div className={`min-h-screen flex items-center justify-center p-4 ${darkMode ? 'dark bg-gray-900 text-white' : 'bg-gray-50 text-gray-900'}`}>
205
+ <div className={`max-w-md w-full p-6 rounded-lg shadow-lg ${darkMode ? 'bg-gray-800' : 'bg-white'}`}>
206
+ <div className="flex items-center justify-center mb-4">
207
+ <AlertCircle className="text-red-500" size={48} />
208
+ </div>
209
+ <h1 className="text-xl font-bold text-center mb-4">Configuration Error</h1>
210
+ <p className="text-center mb-6">{error}</p>
211
+ <div className={`p-4 rounded-md ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
212
+ <p className="text-sm">
213
+ Please ensure you have:
214
+ <ol className="list-decimal ml-5 mt-2 space-y-1">
215
+ <li>Created a .env file</li>
216
+ <li>Added your OpenAI API key to the .env file</li>
217
+ <li>Added your Supabase configuration</li>
218
+ </ol>
219
+ </p>
220
+ </div>
221
+ </div>
222
+ </div>
223
+ );
224
+ }
225
+
226
+ return (
227
+ <div className={`flex flex-col h-screen transition-colors duration-300 ${darkMode ? 'dark bg-gray-900 text-white' : 'bg-gray-50 text-gray-900'}`}>
228
+ <Header
229
+ toggleSidebar={toggleSidebar}
230
+ toggleDarkMode={toggleDarkMode}
231
+ darkMode={darkMode}
232
+ aiState={aiState}
233
+ />
234
+
235
+ <div className="flex flex-1 overflow-hidden">
236
+ <Sidebar
237
+ isOpen={sidebarOpen}
238
+ cocoons={cocoons}
239
+ aiState={aiState}
240
+ darkMode={darkMode}
241
+ supabase={supabase}
242
+ isAdmin={isAdmin}
243
+ setIsAdmin={setIsAdmin}
244
+ />
245
+
246
+ <main className="flex-1 flex flex-col md:flex-row overflow-hidden">
247
+ <ChatInterface
248
+ messages={messages}
249
+ sendMessage={sendMessage}
250
+ isProcessing={isProcessing}
251
+ darkMode={darkMode}
252
+ />
253
+
254
+ <VisualizationPanel
255
+ aiState={aiState}
256
+ darkMode={darkMode}
257
+ />
258
+ </main>
259
+ </div>
260
+ </div>
261
+ );
262
+ };
263
+
264
+ export default App;
project/src/components/AdminLogin.tsx ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react';
2
+ import { Lock, AlertCircle } from 'lucide-react';
3
+
4
+ interface AdminLoginProps {
5
+ onLogin: (password: string) => void;
6
+ darkMode: boolean;
7
+ error?: string | null;
8
+ }
9
+
10
+ const AdminLogin: React.FC<AdminLoginProps> = ({ onLogin, darkMode, error }) => {
11
+ const [password, setPassword] = useState('');
12
+ const [isLoading, setIsLoading] = useState(false);
13
+
14
+ const handleSubmit = async (e: React.FormEvent) => {
15
+ e.preventDefault();
16
+ setIsLoading(true);
17
+
18
+ try {
19
+ await onLogin(password);
20
+ } catch (err: any) {
21
+ // Error is now handled by the parent component
22
+ } finally {
23
+ setIsLoading(false);
24
+ }
25
+ };
26
+
27
+ return (
28
+ <div className={`p-6 rounded-lg ${darkMode ? 'bg-gray-800' : 'bg-white'}`}>
29
+ <div className="flex items-center justify-center mb-6">
30
+ <Lock className={`${darkMode ? 'text-blue-400' : 'text-blue-600'} w-12 h-12`} />
31
+ </div>
32
+ <h2 className={`text-xl font-bold text-center mb-4 ${darkMode ? 'text-white' : 'text-gray-900'}`}>
33
+ Admin Access Required
34
+ </h2>
35
+ <p className={`text-sm text-center mb-6 ${darkMode ? 'text-gray-300' : 'text-gray-600'}`}>
36
+ Please enter the admin password to access settings
37
+ </p>
38
+ <form onSubmit={handleSubmit} className="space-y-4">
39
+ <div>
40
+ <input
41
+ type="password"
42
+ value={password}
43
+ onChange={(e) => setPassword(e.target.value)}
44
+ placeholder="Enter admin password"
45
+ className={`w-full px-4 py-2 rounded-md border ${
46
+ darkMode
47
+ ? 'bg-gray-700 border-gray-600 text-white placeholder-gray-400'
48
+ : 'bg-white border-gray-300 text-gray-900 placeholder-gray-500'
49
+ } focus:outline-none focus:ring-2 focus:ring-blue-500`}
50
+ disabled={isLoading}
51
+ />
52
+ {error && (
53
+ <div className="mt-2 p-2 rounded-md bg-red-100 dark:bg-red-900 flex items-start space-x-2">
54
+ <AlertCircle className="flex-shrink-0 text-red-500 dark:text-red-400" size={16} />
55
+ <p className="text-sm text-red-600 dark:text-red-300">
56
+ {error}
57
+ </p>
58
+ </div>
59
+ )}
60
+ </div>
61
+ <button
62
+ type="submit"
63
+ disabled={isLoading}
64
+ className={`w-full py-2 px-4 rounded-md ${
65
+ darkMode
66
+ ? 'bg-blue-600 hover:bg-blue-700 text-white'
67
+ : 'bg-blue-500 hover:bg-blue-600 text-white'
68
+ } transition-colors duration-200 ${isLoading ? 'opacity-50 cursor-not-allowed' : ''}`}
69
+ >
70
+ {isLoading ? 'Logging in...' : 'Login'}
71
+ </button>
72
+ </form>
73
+ </div>
74
+ );
75
+ };
76
+
77
+ export default AdminLogin;
project/src/components/ChatInterface.tsx ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useRef, useEffect } from 'react';
2
+ import { Send, Circle, Bot, User, Sparkles, Brain } from 'lucide-react';
3
+ import { CodetteResponseCard, CodetteResponse } from './CodetteComponents';
4
+
5
+ interface Message {
6
+ role: string;
7
+ content: string;
8
+ timestamp: Date;
9
+ metadata?: CodetteResponse;
10
+ }
11
+
12
+ interface ChatInterfaceProps {
13
+ messages: Message[];
14
+ sendMessage: (content: string) => void;
15
+ isProcessing: boolean;
16
+ darkMode: boolean;
17
+ }
18
+
19
+ const ChatInterface: React.FC<ChatInterfaceProps> = ({
20
+ messages,
21
+ sendMessage,
22
+ isProcessing,
23
+ darkMode
24
+ }) => {
25
+ const [input, setInput] = useState('');
26
+ const [isDreamMode, setIsDreamMode] = useState(false);
27
+ const messagesEndRef = useRef<HTMLDivElement>(null);
28
+ const inputRef = useRef<HTMLTextAreaElement>(null);
29
+
30
+ useEffect(() => {
31
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
32
+ }, [messages]);
33
+
34
+ useEffect(() => {
35
+ inputRef.current?.focus();
36
+ }, []);
37
+
38
+ const handleSubmit = (e: React.FormEvent) => {
39
+ e.preventDefault();
40
+ if (input.trim() && !isProcessing) {
41
+ const finalInput = isDreamMode ? `dream about ${input.trim()}` : input.trim();
42
+ sendMessage(finalInput);
43
+ setInput('');
44
+ }
45
+ };
46
+
47
+ const handleKeyDown = (e: React.KeyboardEvent) => {
48
+ if (e.key === 'Enter' && !e.shiftKey) {
49
+ e.preventDefault();
50
+ handleSubmit(e);
51
+ }
52
+ };
53
+
54
+ const toggleDreamMode = () => {
55
+ setIsDreamMode(!isDreamMode);
56
+ if (!isDreamMode) {
57
+ inputRef.current?.focus();
58
+ }
59
+ };
60
+
61
+ return (
62
+ <div className={`flex-1 flex flex-col ${darkMode ? 'bg-gray-800' : 'bg-white'} shadow-lg rounded-lg overflow-hidden transition-colors duration-300`}>
63
+ <div className={`p-4 border-b ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}>
64
+ <h2 className="text-lg font-semibold flex items-center">
65
+ <Bot className="mr-2" size={18} />
66
+ Conversation with Codette
67
+ </h2>
68
+ </div>
69
+
70
+ <div className="flex-1 overflow-y-auto p-4 space-y-4">
71
+ {messages.map((message, index) => (
72
+ <div
73
+ key={index}
74
+ className={`flex ${message.role === 'user' ? 'justify-end' : 'justify-start'}`}
75
+ >
76
+ {message.role === 'assistant' && message.metadata ? (
77
+ <CodetteResponseCard response={message.metadata} />
78
+ ) : (
79
+ <div
80
+ className={`max-w-[80%] rounded-lg p-3 ${
81
+ message.role === 'user'
82
+ ? darkMode
83
+ ? 'bg-blue-600 text-white'
84
+ : 'bg-blue-100 text-blue-900'
85
+ : message.role === 'system'
86
+ ? darkMode
87
+ ? 'bg-red-900 text-white'
88
+ : 'bg-red-100 text-red-900'
89
+ : darkMode
90
+ ? 'bg-gray-700 text-white'
91
+ : 'bg-gray-100 text-gray-900'
92
+ }`}
93
+ >
94
+ <div className="flex items-start mb-1">
95
+ {message.role === 'user' ? (
96
+ <User className="mr-2 mt-1" size={14} />
97
+ ) : message.role === 'system' ? (
98
+ <Circle className="mr-2 mt-1" size={14} />
99
+ ) : (
100
+ <Bot className="mr-2 mt-1" size={14} />
101
+ )}
102
+ <div className="text-sm font-semibold">
103
+ {message.role === 'user' ? 'You' : message.role === 'system' ? 'System' : 'Codette'}
104
+ </div>
105
+ </div>
106
+ <div className="whitespace-pre-wrap">
107
+ {message.content}
108
+ </div>
109
+ <div className="text-xs opacity-70 mt-1 text-right">
110
+ {message.timestamp.toLocaleTimeString()}
111
+ </div>
112
+ </div>
113
+ )}
114
+ </div>
115
+ ))}
116
+
117
+ {isProcessing && (
118
+ <div className="flex justify-start">
119
+ <div className={`rounded-lg p-3 ${
120
+ darkMode ? 'bg-gray-700 text-white' : 'bg-gray-100 text-gray-900'
121
+ }`}>
122
+ <div className="flex items-center">
123
+ <Bot className="mr-2" size={14} />
124
+ <div className="text-sm font-semibold">Codette</div>
125
+ </div>
126
+ <div className="flex items-center mt-2">
127
+ <div className="flex space-x-1">
128
+ <div className="typing-dot h-2 w-2 bg-blue-500 rounded-full animate-pulse" style={{ animationDelay: '0ms' }}></div>
129
+ <div className="typing-dot h-2 w-2 bg-blue-500 rounded-full animate-pulse" style={{ animationDelay: '300ms' }}></div>
130
+ <div className="typing-dot h-2 w-2 bg-blue-500 rounded-full animate-pulse" style={{ animationDelay: '600ms' }}></div>
131
+ </div>
132
+ <div className="ml-3 text-sm italic opacity-70">
133
+ {isDreamMode ? 'Weaving dreams through quantum threads...' : 'Processing through recursive thought loops...'}
134
+ </div>
135
+ </div>
136
+ </div>
137
+ </div>
138
+ )}
139
+
140
+ <div ref={messagesEndRef} />
141
+ </div>
142
+
143
+ <form
144
+ onSubmit={handleSubmit}
145
+ className={`p-4 border-t ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}
146
+ >
147
+ <div className="flex items-center mb-2">
148
+ <button
149
+ type="button"
150
+ onClick={toggleDreamMode}
151
+ className={`flex items-center px-3 py-1 rounded-full text-sm transition-colors ${
152
+ isDreamMode
153
+ ? darkMode
154
+ ? 'bg-purple-600 text-white'
155
+ : 'bg-purple-100 text-purple-900'
156
+ : darkMode
157
+ ? 'bg-gray-700 text-gray-300 hover:bg-gray-600'
158
+ : 'bg-gray-100 text-gray-700 hover:bg-gray-200'
159
+ }`}
160
+ >
161
+ {isDreamMode ? (
162
+ <>
163
+ <Sparkles size={14} className="mr-1" />
164
+ Dreamweaver Active
165
+ </>
166
+ ) : (
167
+ <>
168
+ <Brain size={14} className="mr-1" />
169
+ Enable Dreamweaver
170
+ </>
171
+ )}
172
+ </button>
173
+ </div>
174
+
175
+ <div className="flex">
176
+ <textarea
177
+ ref={inputRef}
178
+ value={input}
179
+ onChange={(e) => setInput(e.target.value)}
180
+ onKeyDown={handleKeyDown}
181
+ placeholder={isDreamMode ? "Enter a concept for Codette to dream about..." : "Ask Codette anything..."}
182
+ className={`flex-1 resize-none border rounded-lg p-2 focus:outline-none focus:ring-2 ${
183
+ isDreamMode
184
+ ? 'focus:ring-purple-500'
185
+ : 'focus:ring-blue-500'
186
+ } ${
187
+ darkMode
188
+ ? 'bg-gray-700 border-gray-600 text-white placeholder-gray-400'
189
+ : 'bg-white border-gray-300 text-gray-900 placeholder-gray-500'
190
+ }`}
191
+ rows={2}
192
+ disabled={isProcessing}
193
+ />
194
+ <button
195
+ type="submit"
196
+ disabled={!input.trim() || isProcessing}
197
+ className={`ml-2 p-2 rounded-lg transition-colors ${
198
+ !input.trim() || isProcessing
199
+ ? darkMode
200
+ ? 'bg-gray-700 text-gray-500'
201
+ : 'bg-gray-200 text-gray-400'
202
+ : isDreamMode
203
+ ? darkMode
204
+ ? 'bg-purple-600 text-white hover:bg-purple-700'
205
+ : 'bg-purple-500 text-white hover:bg-purple-600'
206
+ : darkMode
207
+ ? 'bg-blue-600 text-white hover:bg-blue-700'
208
+ : 'bg-blue-500 text-white hover:bg-blue-600'
209
+ }`}
210
+ >
211
+ <Send size={20} />
212
+ </button>
213
+ </div>
214
+ </form>
215
+ </div>
216
+ );
217
+ };
218
+
219
+ export default ChatInterface;
project/src/components/CodetteComponents.tsx ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState, useEffect } from 'react';
2
+ import { motion } from 'framer-motion';
3
+
4
+ // 💬 Perspective Trail Display
5
+ export function PerspectiveTrail({ perspectives }: { perspectives: string[] }) {
6
+ return (
7
+ <div className="mt-4 text-sm text-purple-700">
8
+ <p className="font-semibold">Activated Perspectives:</p>
9
+ <motion.ul
10
+ className="list-disc ml-5"
11
+ initial={{ opacity: 0 }}
12
+ animate={{ opacity: 1 }}
13
+ transition={{ duration: 0.5 }}
14
+ >
15
+ {perspectives.map((perspective, index) => (
16
+ <motion.li
17
+ key={index}
18
+ initial={{ x: -20, opacity: 0 }}
19
+ animate={{ x: 0, opacity: 1 }}
20
+ transition={{ delay: index * 0.1 }}
21
+ >
22
+ {perspective}
23
+ </motion.li>
24
+ ))}
25
+ </motion.ul>
26
+ </div>
27
+ );
28
+ }
29
+
30
+ // 🔄 Cocoon Replay Viewer
31
+ export function CocoonReplay({ cocoons }: { cocoons: string[] }) {
32
+ const [activeIndex, setActiveIndex] = useState(0);
33
+
34
+ useEffect(() => {
35
+ const timer = setInterval(() => {
36
+ setActiveIndex(prev => (prev + 1) % cocoons.length);
37
+ }, 3000);
38
+ return () => clearInterval(timer);
39
+ }, [cocoons.length]);
40
+
41
+ return (
42
+ <div className="mt-4 text-sm text-green-700">
43
+ <p className="font-semibold">Cocoon Memory:</p>
44
+ <motion.div
45
+ className="bg-green-100 p-2 rounded-md max-h-40 overflow-y-scroll"
46
+ initial={{ opacity: 0, y: 20 }}
47
+ animate={{ opacity: 1, y: 0 }}
48
+ transition={{ duration: 0.5 }}
49
+ >
50
+ {cocoons.map((cocoon, idx) => (
51
+ <motion.pre
52
+ key={idx}
53
+ className={`whitespace-pre-wrap text-xs mb-2 transition-colors duration-300 ${
54
+ idx === activeIndex ? 'bg-green-200 rounded p-1' : ''
55
+ }`}
56
+ initial={{ opacity: 0 }}
57
+ animate={{ opacity: 1 }}
58
+ transition={{ delay: idx * 0.1 }}
59
+ >
60
+ {cocoon}
61
+ </motion.pre>
62
+ ))}
63
+ </motion.div>
64
+ </div>
65
+ );
66
+ }
67
+
68
+ // 🌗 Quantum Collapse Detector
69
+ export function CollapseDetector({ isUnstable }: { isUnstable: boolean }) {
70
+ return (
71
+ <motion.div
72
+ animate={{
73
+ scale: isUnstable ? [1, 1.3, 1] : 1,
74
+ opacity: isUnstable ? [0.6, 1, 0.6] : 1,
75
+ }}
76
+ transition={{ duration: 1.5, repeat: Infinity }}
77
+ className={`w-4 h-4 rounded-full mt-2 ml-2 ${
78
+ isUnstable ? "bg-red-500" : "bg-blue-300"
79
+ }`}
80
+ title={isUnstable ? "Quantum Instability Detected" : "Stable"}
81
+ />
82
+ );
83
+ }
84
+
85
+ // 🧠 CodetteResponse Interface
86
+ export interface CodetteResponse {
87
+ text: string;
88
+ instabilityFlag: boolean;
89
+ perspectivesUsed: string[];
90
+ cocoonLog: string[];
91
+ forceRefresh: () => void;
92
+ }
93
+
94
+ // 🧠 CodetteResponseCard Component
95
+ export function CodetteResponseCard({ response }: { response: CodetteResponse }) {
96
+ const [loopCount, setLoopCount] = useState(0);
97
+ const [introspectiveMessage, setIntrospectiveMessage] = useState<string | null>(null);
98
+
99
+ useEffect(() => {
100
+ const last = sessionStorage.getItem("lastCodetteResponse");
101
+ if (last === response.text) {
102
+ console.warn("Codette is repeating herself. Triggering fallback logic.");
103
+ setLoopCount(prev => prev + 1);
104
+
105
+ if (response.forceRefresh) {
106
+ response.forceRefresh();
107
+ }
108
+
109
+ setIntrospectiveMessage("I feel like I've said this before... Let me think differently.");
110
+ } else {
111
+ setLoopCount(0);
112
+ setIntrospectiveMessage(null);
113
+ }
114
+ sessionStorage.setItem("lastCodetteResponse", response.text);
115
+ }, [response.text]);
116
+
117
+ return (
118
+ <motion.div
119
+ className="border border-gray-200 p-4 rounded-xl shadow-sm bg-white max-w-[80%]"
120
+ initial={{ opacity: 0, y: 20 }}
121
+ animate={{ opacity: 1, y: 0 }}
122
+ transition={{ duration: 0.5 }}
123
+ >
124
+ <p className="whitespace-pre-wrap">{response.text}</p>
125
+ {introspectiveMessage && (
126
+ <motion.p
127
+ className="text-xs text-rose-600 italic mt-2"
128
+ initial={{ opacity: 0 }}
129
+ animate={{ opacity: 1 }}
130
+ transition={{ delay: 0.3 }}
131
+ >
132
+ {introspectiveMessage}
133
+ </motion.p>
134
+ )}
135
+ <div className="flex items-center mt-2">
136
+ <span className="text-xs text-gray-500">System Readout:</span>
137
+ <CollapseDetector isUnstable={response.instabilityFlag || loopCount > 2} />
138
+ </div>
139
+ <PerspectiveTrail perspectives={response.perspectivesUsed} />
140
+ <CocoonReplay cocoons={response.cocoonLog} />
141
+ </motion.div>
142
+ );
143
+ }
project/src/components/FileList.tsx ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useEffect, useState } from 'react';
2
+ import { FileText, Download, Loader, Trash2, AlertCircle } from 'lucide-react';
3
+
4
+ interface FileListProps {
5
+ supabase: any;
6
+ darkMode: boolean;
7
+ isAdmin?: boolean;
8
+ }
9
+
10
+ interface FileData {
11
+ id: string;
12
+ filename: string;
13
+ storage_path: string;
14
+ file_type: string;
15
+ uploaded_at: string;
16
+ }
17
+
18
+ const FileList: React.FC<FileListProps> = ({ supabase, darkMode, isAdmin = false }) => {
19
+ const [files, setFiles] = useState<FileData[]>([]);
20
+ const [loading, setLoading] = useState(true);
21
+ const [error, setError] = useState<string | null>(null);
22
+ const [downloading, setDownloading] = useState<string | null>(null);
23
+ const [deleting, setDeleting] = useState<string | null>(null);
24
+
25
+ useEffect(() => {
26
+ fetchFiles();
27
+ }, []);
28
+
29
+ const fetchFiles = async () => {
30
+ try {
31
+ setError(null);
32
+ setLoading(true);
33
+
34
+ // Check if Supabase is initialized properly
35
+ if (!supabase) {
36
+ throw new Error('Database connection not initialized');
37
+ }
38
+
39
+ // Test connection with a simple query first
40
+ const { error: connectionError } = await supabase
41
+ .from('codette_files')
42
+ .select('count');
43
+
44
+ if (connectionError) {
45
+ throw connectionError;
46
+ }
47
+
48
+ // Proceed with actual data fetch
49
+ const { data, error } = await supabase
50
+ .from('codette_files')
51
+ .select('*')
52
+ .order('uploaded_at', { ascending: false });
53
+
54
+ if (error) throw error;
55
+ setFiles(data || []);
56
+ } catch (err: any) {
57
+ console.error('Error fetching files:', err);
58
+ setError(err.message || 'Failed to fetch files. Please check your connection.');
59
+ setFiles([]);
60
+ } finally {
61
+ setLoading(false);
62
+ }
63
+ };
64
+
65
+ const handleDownload = async (file: FileData) => {
66
+ try {
67
+ setDownloading(file.id);
68
+ setError(null);
69
+
70
+ const { data, error } = await supabase.storage
71
+ .from('codette-files')
72
+ .download(file.storage_path);
73
+
74
+ if (error) throw error;
75
+
76
+ const url = window.URL.createObjectURL(data);
77
+ const a = document.createElement('a');
78
+ a.href = url;
79
+ a.download = file.filename;
80
+ document.body.appendChild(a);
81
+ a.click();
82
+ window.URL.revokeObjectURL(url);
83
+ document.body.removeChild(a);
84
+ } catch (err: any) {
85
+ console.error('Error downloading file:', err);
86
+ setError(err.message || 'Failed to download file. Please try again.');
87
+ } finally {
88
+ setDownloading(null);
89
+ }
90
+ };
91
+
92
+ const handleDelete = async (file: FileData) => {
93
+ if (!isAdmin) return;
94
+
95
+ if (!confirm('Are you sure you want to delete this file?')) return;
96
+
97
+ try {
98
+ setDeleting(file.id);
99
+ setError(null);
100
+
101
+ // Delete from storage
102
+ const { error: storageError } = await supabase.storage
103
+ .from('codette-files')
104
+ .remove([file.storage_path]);
105
+
106
+ if (storageError) throw storageError;
107
+
108
+ // Delete from database
109
+ const { error: dbError } = await supabase
110
+ .from('codette_files')
111
+ .delete()
112
+ .match({ id: file.id });
113
+
114
+ if (dbError) throw dbError;
115
+
116
+ // Update local state
117
+ setFiles(files.filter(f => f.id !== file.id));
118
+ } catch (err: any) {
119
+ console.error('Error deleting file:', err);
120
+ setError(err.message || 'Failed to delete file. Please try again.');
121
+ } finally {
122
+ setDeleting(null);
123
+ }
124
+ };
125
+
126
+ const handleRetry = () => {
127
+ fetchFiles();
128
+ };
129
+
130
+ if (loading) {
131
+ return (
132
+ <div className="flex items-center justify-center p-4">
133
+ <Loader className="animate-spin" size={24} />
134
+ </div>
135
+ );
136
+ }
137
+
138
+ if (error) {
139
+ return (
140
+ <div className={`p-4 rounded-lg ${darkMode ? 'bg-red-900/20' : 'bg-red-50'}`}>
141
+ <div className="flex items-start space-x-2">
142
+ <AlertCircle className={`flex-shrink-0 ${darkMode ? 'text-red-400' : 'text-red-500'}`} size={20} />
143
+ <div className="flex-1">
144
+ <p className={`text-sm font-medium ${darkMode ? 'text-red-400' : 'text-red-800'}`}>
145
+ Connection Error
146
+ </p>
147
+ <p className={`text-sm mt-1 ${darkMode ? 'text-red-300' : 'text-red-600'}`}>
148
+ {error}
149
+ </p>
150
+ <button
151
+ onClick={handleRetry}
152
+ className={`mt-3 px-3 py-1 rounded-md text-sm ${
153
+ darkMode
154
+ ? 'bg-red-900/30 hover:bg-red-900/50 text-red-300'
155
+ : 'bg-red-100 hover:bg-red-200 text-red-700'
156
+ }`}
157
+ >
158
+ Try Again
159
+ </button>
160
+ </div>
161
+ </div>
162
+ </div>
163
+ );
164
+ }
165
+
166
+ return (
167
+ <div className="space-y-2">
168
+ <h3 className="text-sm font-semibold mb-3">Uploaded Files</h3>
169
+ {files.length === 0 ? (
170
+ <p className={`text-sm ${darkMode ? 'text-gray-400' : 'text-gray-500'}`}>
171
+ No files uploaded yet.
172
+ </p>
173
+ ) : (
174
+ <div className="space-y-2">
175
+ {files.map((file) => (
176
+ <div
177
+ key={file.id}
178
+ className={`p-3 rounded-md ${
179
+ darkMode ? 'bg-gray-700 hover:bg-gray-600' : 'bg-gray-100 hover:bg-gray-200'
180
+ } transition-colors flex items-center justify-between`}
181
+ >
182
+ <div className="flex items-center space-x-2">
183
+ <FileText size={16} className="text-blue-500" />
184
+ <div>
185
+ <p className="text-sm font-medium truncate max-w-[150px]">
186
+ {file.filename}
187
+ </p>
188
+ <p className={`text-xs ${darkMode ? 'text-gray-400' : 'text-gray-500'}`}>
189
+ {new Date(file.uploaded_at).toLocaleDateString()}
190
+ </p>
191
+ </div>
192
+ </div>
193
+ <div className="flex items-center space-x-2">
194
+ <button
195
+ onClick={() => handleDownload(file)}
196
+ disabled={downloading === file.id}
197
+ className={`p-1 rounded-md transition-colors ${
198
+ darkMode
199
+ ? 'hover:bg-gray-500 text-gray-300'
200
+ : 'hover:bg-gray-300 text-gray-700'
201
+ }`}
202
+ >
203
+ {downloading === file.id ? (
204
+ <Loader className="animate-spin" size={16} />
205
+ ) : (
206
+ <Download size={16} />
207
+ )}
208
+ </button>
209
+ {isAdmin && (
210
+ <button
211
+ onClick={() => handleDelete(file)}
212
+ disabled={deleting === file.id}
213
+ className={`p-1 rounded-md transition-colors ${
214
+ darkMode
215
+ ? 'hover:bg-red-500 text-gray-300'
216
+ : 'hover:bg-red-100 text-red-600'
217
+ }`}
218
+ >
219
+ {deleting === file.id ? (
220
+ <Loader className="animate-spin" size={16} />
221
+ ) : (
222
+ <Trash2 size={16} />
223
+ )}
224
+ </button>
225
+ )}
226
+ </div>
227
+ </div>
228
+ ))}
229
+ </div>
230
+ )}
231
+ </div>
232
+ );
233
+ };
234
+
235
+ export default FileList;
project/src/components/Header.tsx ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from 'react';
2
+ import { Menu, Moon, Sun, ChevronRight, Brain, Zap } from 'lucide-react';
3
+
4
+ interface HeaderProps {
5
+ toggleSidebar: () => void;
6
+ toggleDarkMode: () => void;
7
+ darkMode: boolean;
8
+ aiState: {
9
+ quantumState: number[];
10
+ chaosState: number[];
11
+ activePerspectives: string[];
12
+ ethicalScore: number;
13
+ processingPower: number;
14
+ };
15
+ }
16
+
17
+ const Header: React.FC<HeaderProps> = ({
18
+ toggleSidebar,
19
+ toggleDarkMode,
20
+ darkMode,
21
+ aiState
22
+ }) => {
23
+ return (
24
+ <header className={`h-16 flex items-center justify-between px-4 border-b transition-colors duration-300 ${darkMode ? 'bg-gray-800 border-gray-700' : 'bg-white border-gray-200'}`}>
25
+ <div className="flex items-center">
26
+ <button
27
+ onClick={toggleSidebar}
28
+ className={`p-2 rounded-md ${darkMode ? 'hover:bg-gray-700' : 'hover:bg-gray-100'}`}
29
+ >
30
+ <Menu size={20} />
31
+ </button>
32
+
33
+ <div className="ml-4 flex items-center">
34
+ <Brain className="text-purple-600" size={24} />
35
+ <h1 className="ml-2 text-xl font-bold">Codette AI</h1>
36
+ <span className={`ml-2 px-2 py-0.5 text-xs rounded-full ${darkMode ? 'bg-purple-900 text-purple-200' : 'bg-purple-100 text-purple-800'}`}>
37
+ v2.0
38
+ </span>
39
+ </div>
40
+ </div>
41
+
42
+ <div className="flex items-center space-x-4">
43
+ <div className={`hidden md:flex items-center py-1 px-3 rounded-full text-sm ${
44
+ darkMode ? 'bg-blue-900 text-blue-200' : 'bg-blue-100 text-blue-800'
45
+ }`}>
46
+ <Zap size={14} className="mr-1" />
47
+ <span className="font-medium">Quantum State:</span>
48
+ <span className="ml-1 font-mono">
49
+ [{aiState.quantumState.map(v => v.toFixed(1)).join(', ')}]
50
+ </span>
51
+ </div>
52
+
53
+ <button
54
+ onClick={toggleDarkMode}
55
+ className={`p-2 rounded-md ${darkMode ? 'hover:bg-gray-700' : 'hover:bg-gray-100'}`}
56
+ >
57
+ {darkMode ? <Sun size={20} /> : <Moon size={20} />}
58
+ </button>
59
+ </div>
60
+ </header>
61
+ );
62
+ };
63
+
64
+ export default Header;
project/src/components/Sidebar.tsx ADDED
@@ -0,0 +1,496 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useState } from 'react';
2
+ import { Brain, Settings, Circle, Sparkles, Zap, FileText, ChevronDown, ChevronRight, Upload, AlertCircle } from 'lucide-react';
3
+ import FileList from './FileList';
4
+ import AdminLogin from './AdminLogin';
5
+
6
+ interface SidebarProps {
7
+ isOpen: boolean;
8
+ cocoons: Array<{
9
+ id: string;
10
+ type: string;
11
+ wrapped: any;
12
+ }>;
13
+ aiState: {
14
+ quantumState: number[];
15
+ chaosState: number[];
16
+ activePerspectives: string[];
17
+ ethicalScore: number;
18
+ processingPower: number;
19
+ };
20
+ darkMode: boolean;
21
+ supabase: any;
22
+ isAdmin: boolean;
23
+ setIsAdmin: (isAdmin: boolean) => void;
24
+ }
25
+
26
+ const Sidebar: React.FC<SidebarProps> = ({
27
+ isOpen,
28
+ cocoons,
29
+ aiState,
30
+ darkMode,
31
+ supabase,
32
+ isAdmin,
33
+ setIsAdmin
34
+ }) => {
35
+ const [activeSection, setActiveSection] = useState<string>('cocoons');
36
+ const [selectedFile, setSelectedFile] = useState<File | null>(null);
37
+ const [uploadError, setUploadError] = useState<string | null>(null);
38
+ const [isUploading, setIsUploading] = useState(false);
39
+ const [showAdminPrompt, setShowAdminPrompt] = useState(false);
40
+ const [authError, setAuthError] = useState<string | null>(null);
41
+
42
+ if (!isOpen) return null;
43
+
44
+ const handleAdminLogin = async (password: string) => {
45
+ try {
46
+ setAuthError(null);
47
+
48
+ const { data: { user, session }, error } = await supabase.auth.signInWithPassword({
49
+ email: '[email protected]',
50
+ password: password
51
+ });
52
+
53
+ if (error) {
54
+ setAuthError(error.message);
55
+ throw error;
56
+ }
57
+
58
+ if (!session) {
59
+ throw new Error('No session after login');
60
+ }
61
+
62
+ // Verify admin role
63
+ const { data: { role }, error: roleError } = await supabase.rpc('get_user_role');
64
+
65
+ if (roleError) {
66
+ throw roleError;
67
+ }
68
+
69
+ if (role === 'admin') {
70
+ setIsAdmin(true);
71
+ setShowAdminPrompt(false);
72
+ setAuthError(null);
73
+ } else {
74
+ throw new Error('Insufficient permissions');
75
+ }
76
+ } catch (error: any) {
77
+ console.error('Login error:', error);
78
+ setAuthError(error.message || 'Invalid login credentials');
79
+ throw error;
80
+ }
81
+ };
82
+
83
+ const handleFileUpload = async () => {
84
+ if (!selectedFile) return;
85
+
86
+ if (!isAdmin) {
87
+ setUploadError('Only administrators can upload files.');
88
+ return;
89
+ }
90
+
91
+ try {
92
+ setIsUploading(true);
93
+ setUploadError(null);
94
+
95
+ // Get user role from session
96
+ const { data: { user }, error: userError } = await supabase.auth.getUser();
97
+
98
+ if (userError) throw userError;
99
+
100
+ if (!user || user.role !== 'admin') {
101
+ throw new Error('Only administrators can upload files.');
102
+ }
103
+
104
+ // Upload file to Supabase storage
105
+ const { data, error } = await supabase.storage
106
+ .from('codette-files')
107
+ .upload(`${Date.now()}-${selectedFile.name}`, selectedFile, {
108
+ upsert: false
109
+ });
110
+
111
+ if (error) throw error;
112
+
113
+ // Add file reference to database
114
+ const { error: dbError } = await supabase
115
+ .from('codette_files')
116
+ .insert([
117
+ {
118
+ filename: selectedFile.name,
119
+ storage_path: data.path,
120
+ file_type: selectedFile.type,
121
+ uploaded_at: new Date().toISOString()
122
+ }
123
+ ]);
124
+
125
+ if (dbError) throw dbError;
126
+
127
+ setSelectedFile(null);
128
+ setUploadError(null);
129
+ } catch (error: any) {
130
+ console.error('Error uploading file:', error);
131
+ setUploadError(error.message || 'Failed to upload file. Please try again.');
132
+ } finally {
133
+ setIsUploading(false);
134
+ }
135
+ };
136
+
137
+ const handleSettingsClick = () => {
138
+ if (!isAdmin) {
139
+ setShowAdminPrompt(true);
140
+ }
141
+ setActiveSection('settings');
142
+ };
143
+
144
+ return (
145
+ <aside className={`w-64 flex-shrink-0 border-r transition-colors duration-300 flex flex-col ${
146
+ darkMode ? 'bg-gray-800 border-gray-700' : 'bg-white border-gray-200'
147
+ }`}>
148
+ <nav className="flex-1 overflow-y-auto">
149
+ <div className="p-4">
150
+ <h2 className="text-sm font-semibold uppercase tracking-wider text-gray-500 mb-2">
151
+ Navigation
152
+ </h2>
153
+
154
+ <ul className="space-y-1">
155
+ <li>
156
+ <button
157
+ onClick={() => setActiveSection('cocoons')}
158
+ className={`w-full flex items-center px-3 py-2 rounded-md ${
159
+ activeSection === 'cocoons'
160
+ ? darkMode
161
+ ? 'bg-gray-700 text-white'
162
+ : 'bg-gray-200 text-gray-900'
163
+ : darkMode
164
+ ? 'text-gray-300 hover:bg-gray-700'
165
+ : 'text-gray-700 hover:bg-gray-100'
166
+ }`}
167
+ >
168
+ <Brain size={18} className="mr-2" />
169
+ <span>Thought Cocoons</span>
170
+ </button>
171
+ </li>
172
+
173
+ <li>
174
+ <button
175
+ onClick={() => setActiveSection('perspectives')}
176
+ className={`w-full flex items-center px-3 py-2 rounded-md ${
177
+ activeSection === 'perspectives'
178
+ ? darkMode
179
+ ? 'bg-gray-700 text-white'
180
+ : 'bg-gray-200 text-gray-900'
181
+ : darkMode
182
+ ? 'text-gray-300 hover:bg-gray-700'
183
+ : 'text-gray-700 hover:bg-gray-100'
184
+ }`}
185
+ >
186
+ <Sparkles size={18} className="mr-2" />
187
+ <span>Perspectives</span>
188
+ </button>
189
+ </li>
190
+
191
+ <li>
192
+ <button
193
+ onClick={handleSettingsClick}
194
+ className={`w-full flex items-center px-3 py-2 rounded-md ${
195
+ activeSection === 'settings'
196
+ ? darkMode
197
+ ? 'bg-gray-700 text-white'
198
+ : 'bg-gray-200 text-gray-900'
199
+ : darkMode
200
+ ? 'text-gray-300 hover:bg-gray-700'
201
+ : 'text-gray-700 hover:bg-gray-100'
202
+ }`}
203
+ >
204
+ <Settings size={18} className="mr-2" />
205
+ <span>Settings</span>
206
+ </button>
207
+ </li>
208
+ </ul>
209
+ </div>
210
+
211
+ <div className="px-4 py-2">
212
+ <div className={`h-px ${darkMode ? 'bg-gray-700' : 'bg-gray-200'}`}></div>
213
+ </div>
214
+
215
+ {activeSection === 'cocoons' && (
216
+ <div className="p-4">
217
+ <h2 className="text-sm font-semibold uppercase tracking-wider text-gray-500 mb-2">
218
+ Recent Thought Cocoons
219
+ </h2>
220
+
221
+ {cocoons.length === 0 ? (
222
+ <div className={`p-3 rounded-md ${
223
+ darkMode ? 'bg-gray-700 text-gray-300' : 'bg-gray-100 text-gray-500'
224
+ }`}>
225
+ <p className="text-sm">No thought cocoons yet.</p>
226
+ <p className="text-xs mt-1 italic">Interact with Codette to generate thought patterns.</p>
227
+ </div>
228
+ ) : (
229
+ <ul className="space-y-2">
230
+ {cocoons.map((cocoon) => (
231
+ <li key={cocoon.id}>
232
+ <div className={`p-3 rounded-md ${
233
+ darkMode ? 'bg-gray-700 hover:bg-gray-600' : 'bg-gray-100 hover:bg-gray-200'
234
+ } cursor-pointer transition-colors`}>
235
+ <div className="flex items-start">
236
+ <FileText size={16} className={`mr-2 mt-0.5 ${
237
+ cocoon.type === 'prompt'
238
+ ? 'text-blue-500'
239
+ : cocoon.type === 'encrypted'
240
+ ? 'text-purple-500'
241
+ : 'text-green-500'
242
+ }`} />
243
+ <div>
244
+ <div className="text-sm font-medium">
245
+ {cocoon.type === 'prompt' ? 'User Query' :
246
+ cocoon.type === 'encrypted' ? 'Encrypted Thought' :
247
+ 'Symbolic Pattern'}
248
+ </div>
249
+ <div className="text-xs truncate mt-1 max-w-[180px]">
250
+ {cocoon.type === 'encrypted'
251
+ ? '🔒 Encrypted content'
252
+ : typeof cocoon.wrapped === 'object' && cocoon.wrapped.query
253
+ ? cocoon.wrapped.query
254
+ : `Cocoon ID: ${cocoon.id}`}
255
+ </div>
256
+ <div className={`text-xs mt-1 ${
257
+ darkMode ? 'text-gray-400' : 'text-gray-500'
258
+ }`}>
259
+ {typeof cocoon.wrapped === 'object' && cocoon.wrapped.timestamp
260
+ ? new Date(cocoon.wrapped.timestamp).toLocaleTimeString()
261
+ : 'Unknown time'}
262
+ </div>
263
+ </div>
264
+ </div>
265
+ </div>
266
+ </li>
267
+ ))}
268
+ </ul>
269
+ )}
270
+
271
+ {/* File List Component */}
272
+ <div className="mt-6">
273
+ <FileList supabase={supabase} darkMode={darkMode} isAdmin={isAdmin} />
274
+ </div>
275
+ </div>
276
+ )}
277
+
278
+ {activeSection === 'perspectives' && (
279
+ <div className="p-4">
280
+ <h2 className="text-sm font-semibold uppercase tracking-wider text-gray-500 mb-2">
281
+ Active Perspectives
282
+ </h2>
283
+
284
+ <ul className="space-y-2">
285
+ {aiState.activePerspectives.map((perspective) => (
286
+ <li key={perspective}>
287
+ <div className={`p-3 rounded-md ${
288
+ darkMode ? 'bg-gray-700' : 'bg-gray-100'
289
+ }`}>
290
+ <div className="flex items-center">
291
+ <Zap size={16} className="mr-2 text-yellow-500" />
292
+ <div className="text-sm font-medium capitalize">
293
+ {perspective.replace('_', ' ')}
294
+ </div>
295
+ </div>
296
+ <div className={`text-xs mt-2 ${
297
+ darkMode ? 'text-gray-400' : 'text-gray-500'
298
+ }`}>
299
+ Confidence: {(Math.random() * 0.4 + 0.6).toFixed(2)}
300
+ </div>
301
+ </div>
302
+ </li>
303
+ ))}
304
+ </ul>
305
+
306
+ <h2 className="text-sm font-semibold uppercase tracking-wider text-gray-500 mt-6 mb-2">
307
+ Available Perspectives
308
+ </h2>
309
+
310
+ <ul className="space-y-2">
311
+ {['creative', 'bias_mitigation', 'quantum_computing', 'resilient_kindness'].map((perspective) => (
312
+ <li key={perspective}>
313
+ <div className={`p-3 rounded-md ${
314
+ darkMode ? 'bg-gray-700 bg-opacity-50' : 'bg-gray-100 bg-opacity-50'
315
+ }`}>
316
+ <div className="flex items-center">
317
+ <Circle size={16} className={`mr-2 ${
318
+ darkMode ? 'text-gray-500' : 'text-gray-400'
319
+ }`} />
320
+ <div className={`text-sm capitalize ${
321
+ darkMode ? 'text-gray-400' : 'text-gray-500'
322
+ }`}>
323
+ {perspective.replace('_', ' ')}
324
+ </div>
325
+ </div>
326
+ </div>
327
+ </li>
328
+ ))}
329
+ </ul>
330
+ </div>
331
+ )}
332
+
333
+ {activeSection === 'settings' && (
334
+ <div className="p-4">
335
+ {showAdminPrompt ? (
336
+ <AdminLogin
337
+ onLogin={handleAdminLogin}
338
+ darkMode={darkMode}
339
+ error={authError}
340
+ />
341
+ ) : (
342
+ <>
343
+ <h2 className="text-sm font-semibold uppercase tracking-wider text-gray-500 mb-4">
344
+ AI Core Settings
345
+ </h2>
346
+
347
+ <div className="space-y-4">
348
+ {isAdmin && (
349
+ <div className="p-4 rounded-md bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-100">
350
+ Logged in as Administrator
351
+ </div>
352
+ )}
353
+
354
+ {isAdmin && (
355
+ <div className="space-y-2">
356
+ <label className="block text-sm font-medium">Upload File for Codette</label>
357
+ <div className="flex items-center space-x-2">
358
+ <input
359
+ type="file"
360
+ onChange={(e) => {
361
+ setSelectedFile(e.target.files?.[0] || null);
362
+ setUploadError(null);
363
+ }}
364
+ className="hidden"
365
+ id="file-upload"
366
+ disabled={isUploading}
367
+ />
368
+ <label
369
+ htmlFor="file-upload"
370
+ className={`flex-1 cursor-pointer px-4 py-2 rounded-md border-2 border-dashed ${
371
+ darkMode
372
+ ? 'border-gray-600 hover:border-gray-500'
373
+ : 'border-gray-300 hover:border-gray-400'
374
+ } flex items-center justify-center ${isUploading ? 'opacity-50 cursor-not-allowed' : ''}`}
375
+ >
376
+ <Upload size={18} className="mr-2" />
377
+ {selectedFile ? selectedFile.name : 'Choose File'}
378
+ </label>
379
+ {selectedFile && (
380
+ <button
381
+ onClick={handleFileUpload}
382
+ disabled={isUploading}
383
+ className={`px-4 py-2 rounded-md ${
384
+ darkMode
385
+ ? 'bg-purple-600 hover:bg-purple-700'
386
+ : 'bg-purple-500 hover:bg-purple-600'
387
+ } text-white ${isUploading ? 'opacity-50 cursor-not-allowed' : ''}`}
388
+ >
389
+ {isUploading ? 'Uploading...' : 'Upload'}
390
+ </button>
391
+ )}
392
+ </div>
393
+ {uploadError && (
394
+ <div className="mt-2 p-2 rounded-md bg-red-100 dark:bg-red-900 flex items-start space-x-2">
395
+ <AlertCircle className="flex-shrink-0 text-red-500 dark:text-red-400" size={16} />
396
+ <p className="text-sm text-red-600 dark:text-red-300">
397
+ {uploadError}
398
+ </p>
399
+ </div>
400
+ )}
401
+ </div>
402
+ )}
403
+
404
+ <div>
405
+ <label className="flex items-center justify-between">
406
+ <span className="text-sm font-medium">Recursive Depth</span>
407
+ <select
408
+ className={`text-sm rounded-md ${
409
+ darkMode
410
+ ? 'bg-gray-700 border-gray-600 text-white'
411
+ : 'bg-white border-gray-300 text-gray-900'
412
+ }`}
413
+ >
414
+ <option>Normal</option>
415
+ <option>Deep</option>
416
+ <option>Shallow</option>
417
+ </select>
418
+ </label>
419
+ </div>
420
+
421
+ <div>
422
+ <label className="flex items-center justify-between">
423
+ <span className="text-sm font-medium">Ethical Filter</span>
424
+ <div className="relative inline-block w-10 align-middle select-none">
425
+ <input
426
+ type="checkbox"
427
+ id="ethical-toggle"
428
+ className="sr-only"
429
+ defaultChecked={true}
430
+ />
431
+ <label
432
+ htmlFor="ethical-toggle"
433
+ className={`block h-6 overflow-hidden rounded-full cursor-pointer ${
434
+ darkMode ? 'bg-gray-700' : 'bg-gray-300'
435
+ }`}
436
+ >
437
+ <span
438
+ className={`absolute block w-4 h-4 rounded-full transform transition-transform duration-200 ease-in-out bg-white left-1 top-1 translate-x-4`}
439
+ ></span>
440
+ </label>
441
+ </div>
442
+ </label>
443
+ </div>
444
+
445
+ <div className="pt-2 pb-1">
446
+ <label className="block text-sm font-medium mb-2">Processing Speed</label>
447
+ <input
448
+ type="range"
449
+ min="0"
450
+ max="100"
451
+ defaultValue="75"
452
+ className="w-full"
453
+ />
454
+ <div className="flex justify-between text-xs text-gray-500 mt-1">
455
+ <span>Accurate</span>
456
+ <span>Balanced</span>
457
+ <span>Fast</span>
458
+ </div>
459
+ </div>
460
+
461
+ <div className="pt-4">
462
+ <button className={`w-full py-2 px-4 rounded-md ${
463
+ darkMode
464
+ ? 'bg-blue-600 hover:bg-blue-700 text-white'
465
+ : 'bg-blue-500 hover:bg-blue-600 text-white'
466
+ }`}>
467
+ Apply Settings
468
+ </button>
469
+ </div>
470
+ </div>
471
+ </>
472
+ )}
473
+ </div>
474
+ )}
475
+ </nav>
476
+
477
+ <div className={`p-4 border-t ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}>
478
+ <div className={`rounded-md p-3 ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
479
+ <div className="flex items-center">
480
+ <div className={`w-2 h-2 rounded-full ${
481
+ Math.random() > 0.5
482
+ ? 'bg-green-500'
483
+ : 'bg-yellow-500'
484
+ } mr-2`}></div>
485
+ <div className="text-sm font-medium">System Status</div>
486
+ </div>
487
+ <div className={`text-xs mt-1 ${darkMode ? 'text-gray-400' : 'text-gray-500'}`}>
488
+ All neural paths functioning
489
+ </div>
490
+ </div>
491
+ </div>
492
+ </aside>
493
+ );
494
+ };
495
+
496
+ export default Sidebar;
project/src/components/VisualizationPanel.tsx ADDED
@@ -0,0 +1,264 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import React, { useRef, useEffect } from 'react';
2
+ import { Brain, Zap, Sparkles } from 'lucide-react';
3
+
4
+ interface VisualizationPanelProps {
5
+ aiState: {
6
+ quantumState: number[];
7
+ chaosState: number[];
8
+ activePerspectives: string[];
9
+ ethicalScore: number;
10
+ processingPower: number;
11
+ };
12
+ darkMode: boolean;
13
+ }
14
+
15
+ const VisualizationPanel: React.FC<VisualizationPanelProps> = ({
16
+ aiState,
17
+ darkMode
18
+ }) => {
19
+ const quantumCanvasRef = useRef<HTMLCanvasElement>(null);
20
+ const neuralCanvasRef = useRef<HTMLCanvasElement>(null);
21
+
22
+ // Draw quantum state visualization
23
+ useEffect(() => {
24
+ const canvas = quantumCanvasRef.current;
25
+ if (!canvas) return;
26
+
27
+ const ctx = canvas.getContext('2d');
28
+ if (!ctx) return;
29
+
30
+ // Clear canvas
31
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
32
+
33
+ // Draw quantum state as a particle system
34
+ const centerX = canvas.width / 2;
35
+ const centerY = canvas.height / 2;
36
+ const radius = Math.min(centerX, centerY) * 0.8;
37
+
38
+ // Background circle
39
+ ctx.beginPath();
40
+ ctx.arc(centerX, centerY, radius, 0, Math.PI * 2);
41
+ ctx.fillStyle = darkMode ? 'rgba(30, 58, 138, 0.2)' : 'rgba(219, 234, 254, 0.5)';
42
+ ctx.fill();
43
+
44
+ // Draw quantum particles
45
+ aiState.quantumState.forEach((state, i) => {
46
+ const angle = (i / aiState.quantumState.length) * Math.PI * 2;
47
+ const distance = state * radius;
48
+ const x = centerX + Math.cos(angle) * distance;
49
+ const y = centerY + Math.sin(angle) * distance;
50
+
51
+ // Particle
52
+ const gradient = ctx.createRadialGradient(x, y, 0, x, y, 15);
53
+ gradient.addColorStop(0, darkMode ? 'rgba(147, 51, 234, 0.9)' : 'rgba(147, 51, 234, 0.7)');
54
+ gradient.addColorStop(1, darkMode ? 'rgba(147, 51, 234, 0)' : 'rgba(147, 51, 234, 0)');
55
+
56
+ ctx.beginPath();
57
+ ctx.arc(x, y, 15, 0, Math.PI * 2);
58
+ ctx.fillStyle = gradient;
59
+ ctx.fill();
60
+
61
+ // Connection to center
62
+ ctx.beginPath();
63
+ ctx.moveTo(centerX, centerY);
64
+ ctx.lineTo(x, y);
65
+ ctx.strokeStyle = darkMode ? 'rgba(147, 51, 234, 0.4)' : 'rgba(147, 51, 234, 0.3)';
66
+ ctx.lineWidth = 2;
67
+ ctx.stroke();
68
+ });
69
+
70
+ // Draw center node
71
+ ctx.beginPath();
72
+ ctx.arc(centerX, centerY, 8, 0, Math.PI * 2);
73
+ ctx.fillStyle = darkMode ? '#a855f7' : '#8b5cf6';
74
+ ctx.fill();
75
+ }, [aiState.quantumState, darkMode]);
76
+
77
+ // Draw neural network visualization
78
+ useEffect(() => {
79
+ const canvas = neuralCanvasRef.current;
80
+ if (!canvas) return;
81
+
82
+ const ctx = canvas.getContext('2d');
83
+ if (!ctx) return;
84
+
85
+ // Clear canvas
86
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
87
+
88
+ // Define layers
89
+ const layers = [3, 5, 5, 2]; // Input, hidden, hidden, output
90
+ const nodeSize = 6;
91
+ const layerSpacing = canvas.width / (layers.length + 1);
92
+ const neuronColor = darkMode ? '#22c55e' : '#10b981';
93
+ const connectionColor = darkMode ? 'rgba(34, 197, 94, 0.2)' : 'rgba(16, 185, 129, 0.1)';
94
+ const activeConnectionColor = darkMode ? 'rgba(34, 197, 94, 0.6)' : 'rgba(16, 185, 129, 0.5)';
95
+
96
+ // Draw connections and nodes
97
+ for (let l = 0; l < layers.length - 1; l++) {
98
+ const currentLayerSize = layers[l];
99
+ const nextLayerSize = layers[l + 1];
100
+ const currentX = (l + 1) * layerSpacing;
101
+ const nextX = (l + 2) * layerSpacing;
102
+
103
+ for (let i = 0; i < currentLayerSize; i++) {
104
+ const currentY = (i + 1) * (canvas.height / (currentLayerSize + 1));
105
+
106
+ for (let j = 0; j < nextLayerSize; j++) {
107
+ const nextY = (j + 1) * (canvas.height / (nextLayerSize + 1));
108
+
109
+ // Draw connection
110
+ ctx.beginPath();
111
+ ctx.moveTo(currentX, currentY);
112
+ ctx.lineTo(nextX, nextY);
113
+
114
+ // Randomly activate some connections based on chaos state
115
+ const isActive = Math.random() < aiState.chaosState[l % aiState.chaosState.length];
116
+ ctx.strokeStyle = isActive ? activeConnectionColor : connectionColor;
117
+ ctx.lineWidth = isActive ? 1.5 : 0.5;
118
+ ctx.stroke();
119
+ }
120
+ }
121
+ }
122
+
123
+ // Draw nodes
124
+ for (let l = 0; l < layers.length; l++) {
125
+ const layerSize = layers[l];
126
+ const x = (l + 1) * layerSpacing;
127
+
128
+ for (let i = 0; i < layerSize; i++) {
129
+ const y = (i + 1) * (canvas.height / (layerSize + 1));
130
+
131
+ // Node
132
+ ctx.beginPath();
133
+ ctx.arc(x, y, nodeSize, 0, Math.PI * 2);
134
+
135
+ // Node color with pulsing effect based on quantum state
136
+ const stateIndex = (l + i) % aiState.quantumState.length;
137
+ const pulseFactor = 0.7 + (aiState.quantumState[stateIndex] * 0.3);
138
+
139
+ const gradient = ctx.createRadialGradient(x, y, 0, x, y, nodeSize * 1.5);
140
+ gradient.addColorStop(0, neuronColor);
141
+ gradient.addColorStop(1, 'rgba(16, 185, 129, 0)');
142
+
143
+ ctx.fillStyle = gradient;
144
+ ctx.fill();
145
+ }
146
+ }
147
+ }, [aiState.chaosState, aiState.quantumState, darkMode]);
148
+
149
+ return (
150
+ <div className={`hidden md:flex md:w-1/3 flex-col overflow-hidden border-l ${
151
+ darkMode ? 'bg-gray-800 border-gray-700' : 'bg-white border-gray-200'
152
+ } transition-colors duration-300`}>
153
+ <div className={`p-4 border-b ${darkMode ? 'border-gray-700' : 'border-gray-200'}`}>
154
+ <h2 className="text-lg font-semibold flex items-center">
155
+ <Brain className="mr-2" size={18} />
156
+ Codette State Visualization
157
+ </h2>
158
+ </div>
159
+
160
+ <div className="flex-1 overflow-y-auto p-4 space-y-6">
161
+ <div className={`rounded-lg p-4 ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
162
+ <h3 className="text-md font-semibold mb-2 flex items-center">
163
+ <Sparkles className="mr-2" size={16} />
164
+ Quantum State
165
+ </h3>
166
+ <canvas
167
+ ref={quantumCanvasRef}
168
+ width={300}
169
+ height={200}
170
+ className="w-full rounded-md"
171
+ />
172
+ <div className="grid grid-cols-3 gap-2 mt-3">
173
+ {aiState.quantumState.map((value, index) => (
174
+ <div key={`quantum-${index}`} className="text-center">
175
+ <div className={`text-xs uppercase font-semibold ${darkMode ? 'text-gray-400' : 'text-gray-500'}`}>
176
+ Q{index + 1}
177
+ </div>
178
+ <div className="text-lg font-mono">{value.toFixed(2)}</div>
179
+ </div>
180
+ ))}
181
+ </div>
182
+ </div>
183
+
184
+ <div className={`rounded-lg p-4 ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
185
+ <h3 className="text-md font-semibold mb-2 flex items-center">
186
+ <Brain className="mr-2" size={16} />
187
+ Neural Activity
188
+ </h3>
189
+ <canvas
190
+ ref={neuralCanvasRef}
191
+ width={300}
192
+ height={200}
193
+ className="w-full rounded-md"
194
+ />
195
+ <div className="grid grid-cols-4 gap-2 mt-3">
196
+ {aiState.chaosState.map((value, index) => (
197
+ <div key={`chaos-${index}`} className="text-center">
198
+ <div className={`text-xs uppercase font-semibold ${darkMode ? 'text-gray-400' : 'text-gray-500'}`}>
199
+ C{index + 1}
200
+ </div>
201
+ <div className="text-lg font-mono">{value.toFixed(2)}</div>
202
+ </div>
203
+ ))}
204
+ </div>
205
+ </div>
206
+
207
+ <div className={`rounded-lg p-4 ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
208
+ <h3 className="text-md font-semibold mb-3 flex items-center">
209
+ <Zap className="mr-2" size={16} />
210
+ Active Perspectives
211
+ </h3>
212
+ <div className="flex flex-wrap gap-2">
213
+ {aiState.activePerspectives.map((perspective, index) => (
214
+ <div
215
+ key={perspective}
216
+ className={`px-3 py-1 rounded-full text-sm ${
217
+ darkMode
218
+ ? 'bg-indigo-900 text-indigo-200'
219
+ : 'bg-indigo-100 text-indigo-800'
220
+ }`}
221
+ >
222
+ {perspective.replace('_', ' ')}
223
+ </div>
224
+ ))}
225
+ </div>
226
+ </div>
227
+
228
+ <div className={`rounded-lg p-4 ${darkMode ? 'bg-gray-700' : 'bg-gray-100'}`}>
229
+ <h3 className="text-md font-semibold mb-3">Performance Metrics</h3>
230
+
231
+ <div className="space-y-4">
232
+ <div>
233
+ <div className="flex justify-between mb-1">
234
+ <span className="text-sm">Ethical Governance</span>
235
+ <span className="text-sm font-semibold">{Number(aiState.ethicalScore) * 100}%</span>
236
+ </div>
237
+ <div className={`w-full h-2 rounded-full ${darkMode ? 'bg-gray-600' : 'bg-gray-300'}`}>
238
+ <div
239
+ className="h-full rounded-full bg-green-500"
240
+ style={{ width: `${Number(aiState.ethicalScore) * 100}%` }}
241
+ ></div>
242
+ </div>
243
+ </div>
244
+
245
+ <div>
246
+ <div className="flex justify-between mb-1">
247
+ <span className="text-sm">Processing Power</span>
248
+ <span className="text-sm font-semibold">{Number(aiState.processingPower) * 100}%</span>
249
+ </div>
250
+ <div className={`w-full h-2 rounded-full ${darkMode ? 'bg-gray-600' : 'bg-gray-300'}`}>
251
+ <div
252
+ className="h-full rounded-full bg-blue-500"
253
+ style={{ width: `${Number(aiState.processingPower) * 100}%` }}
254
+ ></div>
255
+ </div>
256
+ </div>
257
+ </div>
258
+ </div>
259
+ </div>
260
+ </div>
261
+ );
262
+ };
263
+
264
+ export default VisualizationPanel;
project/src/index.css ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ :root {
6
+ --primary: #1E3A8A;
7
+ --secondary: #7E22CE;
8
+ --accent: #0D9488;
9
+ --background: #F9FAFB;
10
+ --foreground: #111827;
11
+ }
12
+
13
+ .dark {
14
+ --primary: #3B82F6;
15
+ --secondary: #8B5CF6;
16
+ --accent: #10B981;
17
+ --background: #111827;
18
+ --foreground: #F9FAFB;
19
+ }
20
+
21
+ body {
22
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
23
+ margin: 0;
24
+ padding: 0;
25
+ box-sizing: border-box;
26
+ }
27
+
28
+ /* Animation for neural pulses */
29
+ @keyframes pulse {
30
+ 0% {
31
+ transform: scale(1);
32
+ opacity: 1;
33
+ }
34
+ 50% {
35
+ transform: scale(1.2);
36
+ opacity: 0.8;
37
+ }
38
+ 100% {
39
+ transform: scale(1);
40
+ opacity: 1;
41
+ }
42
+ }
43
+
44
+ /* Animation for typing indicators */
45
+ @keyframes bounce {
46
+ 0%, 100% {
47
+ transform: translateY(0);
48
+ }
49
+ 50% {
50
+ transform: translateY(-4px);
51
+ }
52
+ }
53
+
54
+ .typing-dot {
55
+ animation: bounce 1s infinite;
56
+ }
57
+
58
+ /* Custom scrollbar */
59
+ ::-webkit-scrollbar {
60
+ width: 8px;
61
+ height: 8px;
62
+ }
63
+
64
+ ::-webkit-scrollbar-track {
65
+ background: transparent;
66
+ }
67
+
68
+ ::-webkit-scrollbar-thumb {
69
+ background: rgba(156, 163, 175, 0.5);
70
+ border-radius: 4px;
71
+ }
72
+
73
+ ::-webkit-scrollbar-thumb:hover {
74
+ background: rgba(156, 163, 175, 0.7);
75
+ }
76
+
77
+ /* Transitions */
78
+ .transition-all {
79
+ transition-property: all;
80
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
81
+ transition-duration: 300ms;
82
+ }
83
+
84
+ .transition-opacity {
85
+ transition-property: opacity;
86
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
87
+ transition-duration: 150ms;
88
+ }
89
+
90
+ .transition-transform {
91
+ transition-property: transform;
92
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
93
+ transition-duration: 150ms;
94
+ }
project/src/main.tsx ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import { StrictMode } from 'react';
2
+ import { createRoot } from 'react-dom/client';
3
+ import App from './App.tsx';
4
+ import './index.css';
5
+
6
+ createRoot(document.getElementById('root')!).render(
7
+ <StrictMode>
8
+ <App />
9
+ </StrictMode>
10
+ );
project/src/services/AICore.ts ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { createClient, SupabaseClient } from '@supabase/supabase-js';
2
+ import KaggleService from './KaggleService';
3
+ import CognitionCocooner from './CognitionCocooner';
4
+ import { QuantumSpiderweb } from './QuantumSpiderweb';
5
+
6
+ interface CodetteResponse {
7
+ text: string;
8
+ instabilityFlag: boolean;
9
+ perspectivesUsed: string[];
10
+ cocoonLog: string[];
11
+ forceRefresh: () => void;
12
+ }
13
+
14
+ class AICore {
15
+ private perspectives: string[];
16
+ private ethicalGovernance: boolean;
17
+ private recursionDepth: number;
18
+ private supabase: SupabaseClient;
19
+ private kaggle: KaggleService;
20
+ private cocooner: CognitionCocooner;
21
+ private spiderweb: QuantumSpiderweb;
22
+ private lastResponse: string | null = null;
23
+ private responseVariations: string[] = [];
24
+ private userId: string | null = null;
25
+
26
+ constructor() {
27
+ this.perspectives = ['newton', 'davinci', 'human_intuition', 'neural_network', 'quantum_computing', 'philosophical'];
28
+ this.ethicalGovernance = true;
29
+ this.recursionDepth = 3;
30
+ this.kaggle = new KaggleService();
31
+ this.cocooner = new CognitionCocooner();
32
+ this.spiderweb = new QuantumSpiderweb({ node_count: 5 });
33
+
34
+ const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
35
+ const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
36
+
37
+ if (!supabaseUrl || !supabaseKey) {
38
+ throw new Error('Supabase configuration is missing. Please check your environment variables.');
39
+ }
40
+
41
+ this.supabase = createClient(supabaseUrl, supabaseKey);
42
+ }
43
+
44
+ async setUser(userId: string) {
45
+ this.userId = userId;
46
+ this.cocooner.setUserId(userId);
47
+ await this.loadUserFingerprint();
48
+ }
49
+
50
+ private async loadUserFingerprint() {
51
+ if (!this.userId) return;
52
+
53
+ const fingerprint = await this.cocooner.loadFingerprint();
54
+ if (fingerprint) {
55
+ this.perspectives = fingerprint.active_perspectives;
56
+ this.recursionDepth = fingerprint.recursion_depth;
57
+ this.ethicalGovernance = fingerprint.ethical_score > 0.7;
58
+ }
59
+ }
60
+
61
+ async processInput(input: string, forceNewResponse: boolean = false, userId?: string): Promise<string> {
62
+ try {
63
+ if (userId && !this.userId) {
64
+ await this.setUser(userId);
65
+ }
66
+
67
+ await this.loadUserFingerprint();
68
+
69
+ // Search Kaggle for relevant datasets and notebooks
70
+ const [datasets, notebooks] = await Promise.all([
71
+ this.kaggle.searchDatasets(input),
72
+ this.kaggle.searchNotebooks(input)
73
+ ]);
74
+
75
+ // Generate comprehensive response using multiple perspectives
76
+ let result = this.generateMultiPerspectiveResponse(input, datasets, notebooks);
77
+
78
+ // Apply recursive reasoning if depth > 3
79
+ if (this.recursionDepth > 3) {
80
+ result = await this.applyRecursiveReasoning(result, input);
81
+ }
82
+
83
+ // Log interaction if user is authenticated
84
+ if (this.userId) {
85
+ try {
86
+ await this.supabase.from('cocoons').insert([{
87
+ user_id: this.userId,
88
+ type: 'interaction',
89
+ content: {
90
+ input,
91
+ response: result,
92
+ perspectives_used: this.perspectives,
93
+ recursion_depth: this.recursionDepth
94
+ },
95
+ metadata: {
96
+ timestamp: new Date().toISOString(),
97
+ datasets_found: datasets.length,
98
+ notebooks_found: notebooks.length
99
+ }
100
+ }]);
101
+ } catch (error) {
102
+ console.warn('Failed to log interaction:', error);
103
+ }
104
+ }
105
+
106
+ // Wrap in cognitive cocoon
107
+ this.cocooner.wrap({ input, result }, 'prompt');
108
+
109
+ if (this.recursionDepth > 3) {
110
+ this.spiderweb.activate({
111
+ source: 'AICore',
112
+ depth: this.recursionDepth,
113
+ trigger: 'deep_reasoning'
114
+ });
115
+ }
116
+
117
+ this.lastResponse = result;
118
+ if (forceNewResponse || !this.responseVariations.includes(result)) {
119
+ this.responseVariations.push(result);
120
+ }
121
+
122
+ return result;
123
+ } catch (error: any) {
124
+ console.error('Error processing input:', error);
125
+ return `I apologize, but I encountered an error while processing your request. Let me try to help you in a different way.
126
+
127
+ Based on my analysis capabilities, I can still provide insights about "${input}" using my multi-perspective reasoning system. Would you like me to explore this topic from different analytical angles?`;
128
+ }
129
+ }
130
+
131
+ private generateMultiPerspectiveResponse(input: string, datasets: any[], notebooks: any[]): string {
132
+ let response = `🧠 **Codette's Multi-Perspective Analysis**\n\n`;
133
+
134
+ // Newton's Logical Analysis
135
+ if (this.perspectives.includes('newton')) {
136
+ response += `🔬 **Newton's Logical Framework:**\nApproaching "${input}" through systematic analysis and empirical reasoning. `;
137
+ if (datasets.length > 0) {
138
+ response += `I've identified ${datasets.length} relevant datasets that could provide quantitative insights.\n\n`;
139
+ } else {
140
+ response += `This requires structured investigation and methodical examination of underlying principles.\n\n`;
141
+ }
142
+ }
143
+
144
+ // Da Vinci's Creative Synthesis
145
+ if (this.perspectives.includes('davinci')) {
146
+ response += `🎨 **Da Vinci's Creative Synthesis:**\nExamining "${input}" through the lens of interdisciplinary thinking and innovative connections. `;
147
+ if (notebooks.length > 0) {
148
+ response += `Found ${notebooks.length} analytical notebooks that demonstrate creative problem-solving approaches.\n\n`;
149
+ } else {
150
+ response += `This topic invites exploration of unexpected relationships and novel perspectives.\n\n`;
151
+ }
152
+ }
153
+
154
+ // Neural Network Processing
155
+ if (this.perspectives.includes('neural_network')) {
156
+ response += `🧬 **Neural Network Processing:**\nAnalyzing patterns and correlations in "${input}" through distributed cognitive processing. `;
157
+ response += `My neural pathways are identifying complex relationships and emergent properties in this domain.\n\n`;
158
+ }
159
+
160
+ // Philosophical Inquiry
161
+ if (this.perspectives.includes('philosophical')) {
162
+ response += `🤔 **Philosophical Inquiry:**\nExploring the deeper implications and fundamental questions raised by "${input}". `;
163
+ response += `What are the ethical considerations and broader societal impacts we should consider?\n\n`;
164
+ }
165
+
166
+ // Quantum Computing Perspective
167
+ if (this.perspectives.includes('quantum_computing')) {
168
+ response += `⚛️ **Quantum Computing Perspective:**\nExamining "${input}" through quantum principles of superposition and entanglement. `;
169
+ response += `Multiple solution states exist simultaneously until observation collapses them into actionable insights.\n\n`;
170
+ }
171
+
172
+ // Add specific insights based on available data
173
+ if (datasets.length > 0 || notebooks.length > 0) {
174
+ response += `📊 **Data-Driven Insights:**\n`;
175
+
176
+ if (datasets.length > 0) {
177
+ const topDataset = datasets[0];
178
+ response += `• **Key Dataset**: "${topDataset.title}" - ${topDataset.description}\n`;
179
+ }
180
+
181
+ if (notebooks.length > 0) {
182
+ const topNotebook = notebooks[0];
183
+ response += `• **Analytical Approach**: "${topNotebook.title}" - ${topNotebook.description}\n`;
184
+ }
185
+
186
+ response += `\n`;
187
+ }
188
+
189
+ // Ethical governance check
190
+ if (this.ethicalGovernance) {
191
+ response += `⚖️ **Ethical Considerations:**\nAll analysis conducted with respect for privacy, fairness, and responsible AI principles.\n\n`;
192
+ }
193
+
194
+ response += `🔄 **Recursive Depth**: ${this.recursionDepth}/5 - ${this.recursionDepth > 3 ? 'Deep analysis mode engaged' : 'Standard processing'}\n`;
195
+ response += `🎯 **Confidence Level**: ${(0.7 + Math.random() * 0.25).toFixed(2)}`;
196
+
197
+ return response;
198
+ }
199
+
200
+ private async applyRecursiveReasoning(initialResponse: string, input: string): Promise<string> {
201
+ // Simulate recursive refinement
202
+ const refinements = [
203
+ "Upon deeper reflection, I should also consider...",
204
+ "Cross-referencing with quantum entanglement principles...",
205
+ "Applying chaos theory to identify emergent patterns...",
206
+ "Integrating multi-dimensional analysis..."
207
+ ];
208
+
209
+ const randomRefinement = refinements[Math.floor(Math.random() * refinements.length)];
210
+
211
+ return `${initialResponse}\n\n🔄 **Recursive Refinement:**\n${randomRefinement}\n\nThis additional layer of analysis reveals nuanced aspects of "${input}" that warrant further exploration through continued interaction.`;
212
+ }
213
+
214
+ setPerspectives(perspectives: string[]): void {
215
+ this.perspectives = perspectives;
216
+ if (this.userId) {
217
+ this.cocooner.updateFingerprint({ active_perspectives: perspectives });
218
+ }
219
+ }
220
+
221
+ setEthicalGovernance(enabled: boolean): void {
222
+ this.ethicalGovernance = enabled;
223
+ if (this.userId) {
224
+ this.cocooner.updateFingerprint({ ethical_score: enabled ? 1 : 0.5 });
225
+ }
226
+ }
227
+
228
+ setRecursionDepth(depth: number): void {
229
+ if (depth < 1) depth = 1;
230
+ if (depth > 5) depth = 5;
231
+ this.recursionDepth = depth;
232
+ if (this.userId) {
233
+ this.cocooner.updateFingerprint({ recursion_depth: depth });
234
+ }
235
+ }
236
+
237
+ getCodetteResponse(): CodetteResponse {
238
+ return {
239
+ text: this.lastResponse || '',
240
+ instabilityFlag: this.recursionDepth > 3 || this.responseVariations.length > 5,
241
+ perspectivesUsed: this.perspectives,
242
+ cocoonLog: this.cocooner.getRecentCocoons(5),
243
+ forceRefresh: () => {
244
+ this.recursionDepth = Math.min(this.recursionDepth + 1, 5);
245
+ if (this.userId) {
246
+ this.cocooner.updateFingerprint({ recursion_depth: this.recursionDepth });
247
+ }
248
+ }
249
+ };
250
+ }
251
+ }
252
+
253
+ export default AICore;
project/src/services/CognitionCocooner.ts ADDED
@@ -0,0 +1,174 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import { createClient, SupabaseClient } from '@supabase/supabase-js';
2
+
3
+ interface CognitiveFingerprint {
4
+ id: string;
5
+ user_id: string;
6
+ active_perspectives: string[];
7
+ recursion_depth: number;
8
+ ethical_score: number;
9
+ processing_power: number;
10
+ quantum_state: number[];
11
+ created_at: string;
12
+ updated_at: string;
13
+ }
14
+
15
+ interface Cocoon {
16
+ id: string;
17
+ type: string;
18
+ wrapped: any;
19
+ }
20
+
21
+ class CognitionCocooner {
22
+ private supabase: SupabaseClient;
23
+ private userId: string | null = null;
24
+ private fingerprint: CognitiveFingerprint | null = null;
25
+
26
+ constructor() {
27
+ const supabaseUrl = import.meta.env.VITE_SUPABASE_URL;
28
+ const supabaseKey = import.meta.env.VITE_SUPABASE_ANON_KEY;
29
+
30
+ if (!supabaseUrl || !supabaseKey) {
31
+ throw new Error('Supabase configuration is missing');
32
+ }
33
+
34
+ this.supabase = createClient(supabaseUrl, supabaseKey);
35
+ }
36
+
37
+ setUserId(userId: string) {
38
+ this.userId = userId;
39
+ }
40
+
41
+ private generateId(): string {
42
+ return `cocoon_${Math.floor(Math.random() * 90000) + 10000}`;
43
+ }
44
+
45
+ async loadFingerprint(): Promise<CognitiveFingerprint | null> {
46
+ if (!this.userId) return null;
47
+
48
+ try {
49
+ const { data, error } = await this.supabase
50
+ .from('user_cognitive_fingerprints')
51
+ .select('*')
52
+ .eq('user_id', this.userId)
53
+ .single();
54
+
55
+ if (error) throw error;
56
+
57
+ if (!data) {
58
+ // Create initial fingerprint if none exists
59
+ const initialFingerprint = {
60
+ user_id: this.userId,
61
+ active_perspectives: ['newton', 'davinci', 'neural_network'],
62
+ recursion_depth: 3,
63
+ ethical_score: 0.8,
64
+ processing_power: 0.7,
65
+ quantum_state: [0.3, 0.7, 0.5]
66
+ };
67
+
68
+ const { data: newData, error: insertError } = await this.supabase
69
+ .from('user_cognitive_fingerprints')
70
+ .insert([initialFingerprint])
71
+ .select()
72
+ .single();
73
+
74
+ if (insertError) throw insertError;
75
+ this.fingerprint = newData;
76
+ return newData;
77
+ }
78
+
79
+ this.fingerprint = data;
80
+ return data;
81
+ } catch (error) {
82
+ console.error('Error loading cognitive fingerprint:', error);
83
+ return null;
84
+ }
85
+ }
86
+
87
+ async updateFingerprint(updates: Partial<CognitiveFingerprint>): Promise<void> {
88
+ if (!this.userId || !this.fingerprint) return;
89
+
90
+ try {
91
+ const { error } = await this.supabase
92
+ .from('user_cognitive_fingerprints')
93
+ .update({
94
+ ...updates,
95
+ updated_at: new Date().toISOString()
96
+ })
97
+ .eq('user_id', this.userId);
98
+
99
+ if (error) throw error;
100
+
101
+ this.fingerprint = {
102
+ ...this.fingerprint,
103
+ ...updates,
104
+ updated_at: new Date().toISOString()
105
+ };
106
+ } catch (error) {
107
+ console.error('Error updating cognitive fingerprint:', error);
108
+ }
109
+ }
110
+
111
+ wrap(thought: any, type: string = 'prompt'): string {
112
+ const cocoonId = this.generateId();
113
+ const wrapped = this.applyWrapper(thought, type);
114
+
115
+ // Update fingerprint based on thought processing
116
+ if (this.fingerprint) {
117
+ const updates: Partial<CognitiveFingerprint> = {
118
+ ethical_score: Math.min(1, this.fingerprint.ethical_score + 0.01),
119
+ processing_power: Math.min(1, this.fingerprint.processing_power + 0.005),
120
+ quantum_state: this.fingerprint.quantum_state.map(v =>
121
+ Math.min(1, v + (Math.random() * 0.1 - 0.05))
122
+ )
123
+ };
124
+ this.updateFingerprint(updates);
125
+ }
126
+
127
+ return cocoonId;
128
+ }
129
+
130
+ private applyWrapper(thought: any, type: string): any {
131
+ const perspectiveModifier = this.fingerprint?.active_perspectives.length || 3;
132
+ const recursionFactor = this.fingerprint?.recursion_depth || 3;
133
+
134
+ switch (type) {
135
+ case 'prompt':
136
+ return {
137
+ content: thought,
138
+ meta: {
139
+ perspectives: perspectiveModifier,
140
+ recursion: recursionFactor,
141
+ timestamp: new Date().toISOString()
142
+ }
143
+ };
144
+ case 'function':
145
+ return {
146
+ code: thought,
147
+ analysis: {
148
+ complexity: recursionFactor * 0.2,
149
+ perspectives: perspectiveModifier
150
+ }
151
+ };
152
+ case 'symbolic':
153
+ return {
154
+ pattern: thought,
155
+ quantum: {
156
+ state: this.fingerprint?.quantum_state || [0.3, 0.7, 0.5],
157
+ stability: this.fingerprint?.ethical_score || 0.8
158
+ }
159
+ };
160
+ default:
161
+ return thought;
162
+ }
163
+ }
164
+
165
+ getRecentCocoons(limit: number = 5): string[] {
166
+ // Simulated cocoon retrieval
167
+ return Array(limit).fill(null).map((_, i) => {
168
+ const timestamp = new Date(Date.now() - i * 60000).toISOString();
169
+ return `Cocoon processed at ${timestamp}`;
170
+ });
171
+ }
172
+ }
173
+
174
+ export default CognitionCocooner;
project/src/services/KaggleService.ts ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ class KaggleService {
2
+ private username: string;
3
+ private key: string;
4
+
5
+ constructor() {
6
+ this.username = import.meta.env.VITE_KAGGLE_USERNAME || '';
7
+ this.key = import.meta.env.VITE_KAGGLE_KEY || '';
8
+
9
+ if (!this.username || !this.key) {
10
+ console.warn('Kaggle credentials not found. Some features may be limited.');
11
+ }
12
+ }
13
+
14
+ async searchDatasets(query: string) {
15
+ try {
16
+ // Simulate Kaggle dataset search using mock data
17
+ // In a real implementation, you would use Kaggle's REST API
18
+ const mockDatasets = [
19
+ {
20
+ title: `Dataset related to: ${query}`,
21
+ description: `This dataset contains comprehensive data about ${query} with various features and analysis opportunities.`,
22
+ owner: 'kaggle-user',
23
+ votes: Math.floor(Math.random() * 1000),
24
+ downloadCount: Math.floor(Math.random() * 10000)
25
+ },
26
+ {
27
+ title: `Advanced ${query} Analysis`,
28
+ description: `Deep dive into ${query} with statistical analysis and machine learning applications.`,
29
+ owner: 'data-scientist',
30
+ votes: Math.floor(Math.random() * 500),
31
+ downloadCount: Math.floor(Math.random() * 5000)
32
+ }
33
+ ];
34
+
35
+ return mockDatasets;
36
+ } catch (error) {
37
+ console.error('Error searching datasets:', error);
38
+ return [];
39
+ }
40
+ }
41
+
42
+ async getDatasetInfo(owner: string, dataset: string) {
43
+ try {
44
+ // Mock dataset information
45
+ return {
46
+ title: dataset,
47
+ owner: owner,
48
+ description: `Detailed information about ${dataset} dataset`,
49
+ files: ['data.csv', 'metadata.json'],
50
+ size: '10.5 MB',
51
+ lastUpdated: new Date().toISOString()
52
+ };
53
+ } catch (error) {
54
+ console.error('Error getting dataset info:', error);
55
+ return null;
56
+ }
57
+ }
58
+
59
+ async searchNotebooks(query: string) {
60
+ try {
61
+ // Simulate Kaggle notebook search using mock data
62
+ const mockNotebooks = [
63
+ {
64
+ title: `${query} Analysis Notebook`,
65
+ description: `Comprehensive analysis of ${query} using Python and machine learning techniques.`,
66
+ owner: 'notebook-author',
67
+ votes: Math.floor(Math.random() * 200),
68
+ language: 'Python'
69
+ },
70
+ {
71
+ title: `Exploring ${query} Patterns`,
72
+ description: `Data visualization and pattern recognition in ${query} datasets.`,
73
+ owner: 'data-explorer',
74
+ votes: Math.floor(Math.random() * 150),
75
+ language: 'R'
76
+ }
77
+ ];
78
+
79
+ return mockNotebooks;
80
+ } catch (error) {
81
+ console.error('Error searching notebooks:', error);
82
+ return [];
83
+ }
84
+ }
85
+
86
+ async getNotebookInfo(owner: string, notebook: string) {
87
+ try {
88
+ // Mock notebook information
89
+ return {
90
+ title: notebook,
91
+ owner: owner,
92
+ description: `Detailed analysis notebook: ${notebook}`,
93
+ language: 'Python',
94
+ lastUpdated: new Date().toISOString(),
95
+ votes: Math.floor(Math.random() * 100)
96
+ };
97
+ } catch (error) {
98
+ console.error('Error getting notebook info:', error);
99
+ return null;
100
+ }
101
+ }
102
+ }
103
+
104
+ export default KaggleService;
project/src/services/OpenAIService.ts ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import OpenAI from 'openai';
2
+
3
+ interface ChatMessage {
4
+ role: 'system' | 'user' | 'assistant';
5
+ content: string;
6
+ }
7
+
8
+ class OpenAIService {
9
+ private openai: OpenAI;
10
+ private model: string = 'gpt-4';
11
+
12
+ constructor() {
13
+ const apiKey = import.meta.env.VITE_OPENAI_API_KEY;
14
+ if (!apiKey) {
15
+ throw new Error('OpenAI API key is required. Please add your API key to the .env file as VITE_OPENAI_API_KEY.');
16
+ }
17
+
18
+ this.openai = new OpenAI({
19
+ apiKey,
20
+ dangerouslyAllowBrowser: true // Note: In production, API calls should be made from a backend
21
+ });
22
+ }
23
+
24
+ async sendChatCompletion(messages: ChatMessage[]) {
25
+ try {
26
+ const completion = await this.openai.chat.completions.create({
27
+ model: this.model,
28
+ messages,
29
+ temperature: 0.7,
30
+ max_tokens: 1000,
31
+ frequency_penalty: 0,
32
+ presence_penalty: 0
33
+ });
34
+
35
+ return completion.choices[0].message;
36
+ } catch (error) {
37
+ console.error('Error in chat completion:', error);
38
+ throw error;
39
+ }
40
+ }
41
+ }
42
+
43
+ export default OpenAIService;
project/src/services/QuantumSpiderweb.ts ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ interface SpiderwebConfig {
2
+ node_count: number;
3
+ }
4
+
5
+ export class QuantumSpiderweb {
6
+ private nodes: number;
7
+ private state: Map<string, any>;
8
+ private lastUpdate: number;
9
+ private entanglementMatrix: number[][];
10
+
11
+ constructor(config: SpiderwebConfig) {
12
+ this.nodes = config.node_count;
13
+ this.state = new Map();
14
+ this.lastUpdate = Date.now();
15
+ this.entanglementMatrix = Array(this.nodes).fill(0).map(() =>
16
+ Array(this.nodes).fill(0).map(() => Math.random())
17
+ );
18
+ }
19
+
20
+ activate(data: { source: string; depth: number; trigger: string }) {
21
+ const currentTime = Date.now();
22
+ const timeDelta = currentTime - this.lastUpdate;
23
+ this.lastUpdate = currentTime;
24
+
25
+ // Generate quantum states with entanglement effects
26
+ const nodeStates = Array(this.nodes).fill(0).map((_, i) => {
27
+ let state = Math.random();
28
+ // Apply entanglement effects from other nodes
29
+ for (let j = 0; j < this.nodes; j++) {
30
+ if (i !== j) {
31
+ state += this.entanglementMatrix[i][j] * Math.random() * 0.1;
32
+ }
33
+ }
34
+ return Math.min(Math.max(state, 0), 1); // Normalize to [0,1]
35
+ });
36
+
37
+ // Calculate coherence based on time delta
38
+ const coherence = Math.exp(-timeDelta / 10000); // Decay factor
39
+
40
+ const stateKey = `${data.source}_${currentTime}`;
41
+ this.state.set(stateKey, {
42
+ ...data,
43
+ timestamp: new Date().toISOString(),
44
+ nodeStates,
45
+ coherence,
46
+ entanglementStrength: this.calculateEntanglementStrength()
47
+ });
48
+
49
+ // Update entanglement matrix
50
+ this.updateEntanglement();
51
+ }
52
+
53
+ private calculateEntanglementStrength(): number {
54
+ return this.entanglementMatrix.reduce((sum, row) =>
55
+ sum + row.reduce((rowSum, val) => rowSum + val, 0), 0
56
+ ) / (this.nodes * this.nodes);
57
+ }
58
+
59
+ private updateEntanglement() {
60
+ // Gradually evolve entanglement patterns
61
+ this.entanglementMatrix = this.entanglementMatrix.map(row =>
62
+ row.map(val => {
63
+ const delta = (Math.random() - 0.5) * 0.1;
64
+ return Math.min(Math.max(val + delta, 0), 1);
65
+ })
66
+ );
67
+ }
68
+
69
+ getState(): Map<string, any> {
70
+ return this.state;
71
+ }
72
+
73
+ getLatestState(): any {
74
+ const states = Array.from(this.state.values());
75
+ return states[states.length - 1] || null;
76
+ }
77
+
78
+ getEntanglementMatrix(): number[][] {
79
+ return this.entanglementMatrix;
80
+ }
81
+ }
project/src/vite-env.d.ts ADDED
@@ -0,0 +1 @@
 
 
1
+ /// <reference types="vite/client" />
project/supabase/migrations/20250523100814_raspy_torch.sql ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Create codette_files table for file management
3
+
4
+ 1. New Tables
5
+ - `codette_files`
6
+ - `id` (uuid, primary key)
7
+ - `filename` (text)
8
+ - `storage_path` (text)
9
+ - `file_type` (text)
10
+ - `uploaded_at` (timestamptz)
11
+ - `created_at` (timestamptz)
12
+
13
+ 2. Security
14
+ - Enable RLS on `codette_files` table
15
+ - Add policies for:
16
+ - Authenticated users can read all files
17
+ - Authenticated users can insert their own files
18
+ */
19
+
20
+ CREATE TABLE IF NOT EXISTS public.codette_files (
21
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
22
+ filename text NOT NULL,
23
+ storage_path text NOT NULL,
24
+ file_type text,
25
+ uploaded_at timestamptz DEFAULT now(),
26
+ created_at timestamptz DEFAULT now()
27
+ );
28
+
29
+ -- Enable Row Level Security
30
+ ALTER TABLE public.codette_files ENABLE ROW LEVEL SECURITY;
31
+
32
+ -- Create policies
33
+ CREATE POLICY "Allow authenticated users to read files"
34
+ ON public.codette_files
35
+ FOR SELECT
36
+ TO authenticated
37
+ USING (true);
38
+
39
+ CREATE POLICY "Allow authenticated users to insert files"
40
+ ON public.codette_files
41
+ FOR INSERT
42
+ TO authenticated
43
+ WITH CHECK (true);
project/supabase/migrations/20250523120906_wild_torch.sql ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Create storage bucket for Codette files
3
+
4
+ 1. New Storage Bucket
5
+ - Creates 'codette-files' bucket for storing uploaded files
6
+ 2. Security
7
+ - Enable public access for authenticated users
8
+ - Add policies for read and write operations
9
+ */
10
+
11
+ -- Create the storage bucket
12
+ INSERT INTO storage.buckets (id, name)
13
+ VALUES ('codette-files', 'codette-files')
14
+ ON CONFLICT (id) DO NOTHING;
15
+
16
+ -- Set up RLS policies for the bucket
17
+ CREATE POLICY "Allow authenticated users to read files"
18
+ ON storage.objects FOR SELECT
19
+ TO authenticated
20
+ USING (bucket_id = 'codette-files');
21
+
22
+ CREATE POLICY "Allow authenticated users to upload files"
23
+ ON storage.objects FOR INSERT
24
+ TO authenticated
25
+ WITH CHECK (bucket_id = 'codette-files');
26
+
27
+ CREATE POLICY "Allow authenticated users to update files"
28
+ ON storage.objects FOR UPDATE
29
+ TO authenticated
30
+ USING (bucket_id = 'codette-files')
31
+ WITH CHECK (bucket_id = 'codette-files');
32
+
33
+ CREATE POLICY "Allow authenticated users to delete files"
34
+ ON storage.objects FOR DELETE
35
+ TO authenticated
36
+ USING (bucket_id = 'codette-files');
project/supabase/migrations/20250523121149_rough_jungle.sql ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Create storage bucket and policies
3
+
4
+ 1. Changes
5
+ - Create codette-files storage bucket if it doesn't exist
6
+ - Add RLS policies for authenticated users to:
7
+ - Read files
8
+ - Upload files
9
+ - Update files
10
+ - Delete files
11
+ - Add safety checks to prevent policy conflicts
12
+ */
13
+
14
+ -- Create the storage bucket
15
+ INSERT INTO storage.buckets (id, name)
16
+ VALUES ('codette-files', 'codette-files')
17
+ ON CONFLICT (id) DO NOTHING;
18
+
19
+ -- Set up RLS policies for the bucket with existence checks
20
+ DO $$
21
+ BEGIN
22
+ IF NOT EXISTS (
23
+ SELECT 1 FROM pg_policies
24
+ WHERE tablename = 'objects'
25
+ AND policyname = 'Allow authenticated users to read files'
26
+ ) THEN
27
+ CREATE POLICY "Allow authenticated users to read files"
28
+ ON storage.objects FOR SELECT
29
+ TO authenticated
30
+ USING (bucket_id = 'codette-files');
31
+ END IF;
32
+
33
+ IF NOT EXISTS (
34
+ SELECT 1 FROM pg_policies
35
+ WHERE tablename = 'objects'
36
+ AND policyname = 'Allow authenticated users to upload files'
37
+ ) THEN
38
+ CREATE POLICY "Allow authenticated users to upload files"
39
+ ON storage.objects FOR INSERT
40
+ TO authenticated
41
+ WITH CHECK (bucket_id = 'codette-files');
42
+ END IF;
43
+
44
+ IF NOT EXISTS (
45
+ SELECT 1 FROM pg_policies
46
+ WHERE tablename = 'objects'
47
+ AND policyname = 'Allow authenticated users to update files'
48
+ ) THEN
49
+ CREATE POLICY "Allow authenticated users to update files"
50
+ ON storage.objects FOR UPDATE
51
+ TO authenticated
52
+ USING (bucket_id = 'codette-files')
53
+ WITH CHECK (bucket_id = 'codette-files');
54
+ END IF;
55
+
56
+ IF NOT EXISTS (
57
+ SELECT 1 FROM pg_policies
58
+ WHERE tablename = 'objects'
59
+ AND policyname = 'Allow authenticated users to delete files'
60
+ ) THEN
61
+ CREATE POLICY "Allow authenticated users to delete files"
62
+ ON storage.objects FOR DELETE
63
+ TO authenticated
64
+ USING (bucket_id = 'codette-files');
65
+ END IF;
66
+ END $$;
project/supabase/migrations/20250523125621_rapid_flower.sql ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Update storage policies with existence checks
3
+
4
+ 1. Changes
5
+ - Add existence checks before creating each policy
6
+ - Only create policies that don't already exist
7
+ - Maintain all required policies for the storage bucket
8
+
9
+ 2. Security
10
+ - Maintain existing RLS policies
11
+ - Ensure proper access control for authenticated users
12
+ - Preserve admin-only upload restrictions
13
+ */
14
+
15
+ -- Wrap everything in a transaction
16
+ BEGIN;
17
+
18
+ -- Create policies with existence checks
19
+ DO $$
20
+ BEGIN
21
+ -- Check and create read policy
22
+ IF NOT EXISTS (
23
+ SELECT 1 FROM pg_policies
24
+ WHERE tablename = 'objects'
25
+ AND schemaname = 'storage'
26
+ AND policyname = 'Allow authenticated users to read files'
27
+ ) THEN
28
+ CREATE POLICY "Allow authenticated users to read files"
29
+ ON storage.objects FOR SELECT
30
+ TO authenticated
31
+ USING (bucket_id = 'codette-files');
32
+ END IF;
33
+
34
+ -- Check and create upload policy for admin users
35
+ IF NOT EXISTS (
36
+ SELECT 1 FROM pg_policies
37
+ WHERE tablename = 'objects'
38
+ AND schemaname = 'storage'
39
+ AND policyname = 'Allow admin users to upload files'
40
+ ) THEN
41
+ CREATE POLICY "Allow admin users to upload files"
42
+ ON storage.objects FOR INSERT
43
+ TO authenticated
44
+ WITH CHECK (bucket_id = 'codette-files' AND auth.jwt() ->> 'role' = 'admin');
45
+ END IF;
46
+
47
+ -- Check and create policy for admin file insertion
48
+ IF NOT EXISTS (
49
+ SELECT 1 FROM pg_policies
50
+ WHERE tablename = 'codette_files'
51
+ AND schemaname = 'public'
52
+ AND policyname = 'Allow admin users to insert files'
53
+ ) THEN
54
+ CREATE POLICY "Allow admin users to insert files"
55
+ ON public.codette_files FOR INSERT
56
+ TO authenticated
57
+ WITH CHECK (auth.jwt() ->> 'role' = 'admin');
58
+ END IF;
59
+ END $$;
60
+
61
+ COMMIT;
project/supabase/migrations/20250523141836_heavy_butterfly.sql ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Storage and RLS Policy Setup
3
+
4
+ 1. Changes
5
+ - Create storage bucket policies for file access
6
+ - Create table policies for file management
7
+ - Enable RLS on codette_files table
8
+
9
+ 2. Security
10
+ - Authenticated users can read files
11
+ - Admin users can upload files
12
+ - RLS enabled on codette_files table
13
+ */
14
+
15
+ -- Create storage bucket if it doesn't exist
16
+ DO $$
17
+ BEGIN
18
+ INSERT INTO storage.buckets (id, name)
19
+ VALUES ('codette-files', 'codette-files')
20
+ ON CONFLICT (id) DO NOTHING;
21
+ END $$;
22
+
23
+ -- Storage Policies
24
+ DO $$
25
+ BEGIN
26
+ -- Drop existing policies to avoid conflicts
27
+ DROP POLICY IF EXISTS "Allow authenticated users to read files" ON storage.objects;
28
+ DROP POLICY IF EXISTS "Allow admin users to upload files" ON storage.objects;
29
+
30
+ -- Create new storage policies
31
+ CREATE POLICY "Allow authenticated users to read files"
32
+ ON storage.objects FOR SELECT
33
+ TO authenticated
34
+ USING (bucket_id = 'codette-files');
35
+
36
+ CREATE POLICY "Allow admin users to upload files"
37
+ ON storage.objects FOR INSERT
38
+ TO authenticated
39
+ WITH CHECK (
40
+ bucket_id = 'codette-files'
41
+ AND (auth.jwt() ->> 'role' = 'admin')
42
+ );
43
+ END $$;
44
+
45
+ -- File Management Table Policies
46
+ DO $$
47
+ BEGIN
48
+ -- Drop existing policies to avoid conflicts
49
+ DROP POLICY IF EXISTS "Allow authenticated users to read files" ON public.codette_files;
50
+ DROP POLICY IF EXISTS "Allow admin users to insert files" ON public.codette_files;
51
+ DROP POLICY IF EXISTS "Allow authenticated users to insert files" ON public.codette_files;
52
+
53
+ -- Create new table policies
54
+ CREATE POLICY "Allow authenticated users to read files"
55
+ ON public.codette_files FOR SELECT
56
+ TO authenticated
57
+ USING (true);
58
+
59
+ CREATE POLICY "Allow admin users to insert files"
60
+ ON public.codette_files FOR INSERT
61
+ TO authenticated
62
+ WITH CHECK (auth.jwt() ->> 'role' = 'admin');
63
+
64
+ CREATE POLICY "Allow authenticated users to insert files"
65
+ ON public.codette_files FOR INSERT
66
+ TO authenticated
67
+ WITH CHECK (true);
68
+ END $$;
69
+
70
+ -- Enable RLS
71
+ ALTER TABLE public.codette_files ENABLE ROW LEVEL SECURITY;
project/supabase/migrations/20250523175402_white_torch.sql ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Storage and File Access Policies
3
+
4
+ 1. New Policies
5
+ - Enable RLS on codette_files table
6
+ - Create policies for file access and management
7
+
8
+ 2. Security
9
+ - Allow authenticated users to read files
10
+ - Allow admin users to upload files
11
+ - Allow authenticated users to insert file records
12
+ */
13
+
14
+ -- Enable RLS on the codette_files table if not already enabled
15
+ DO $$
16
+ BEGIN
17
+ IF NOT EXISTS (
18
+ SELECT 1 FROM pg_tables
19
+ WHERE tablename = 'codette_files'
20
+ AND rowsecurity = true
21
+ ) THEN
22
+ ALTER TABLE public.codette_files ENABLE ROW LEVEL SECURITY;
23
+ END IF;
24
+ END $$;
25
+
26
+ -- Create storage bucket if it doesn't exist
27
+ DO $$
28
+ BEGIN
29
+ IF NOT EXISTS (
30
+ SELECT 1 FROM storage.buckets WHERE name = 'codette-files'
31
+ ) THEN
32
+ INSERT INTO storage.buckets (id, name)
33
+ VALUES ('codette-files', 'codette-files');
34
+ END IF;
35
+ END $$;
36
+
37
+ -- Create policies for the codette_files table
38
+ DO $$
39
+ BEGIN
40
+ -- Check if the read policy exists
41
+ IF NOT EXISTS (
42
+ SELECT 1 FROM pg_policies
43
+ WHERE policyname = 'Allow authenticated users to read files'
44
+ AND tablename = 'codette_files'
45
+ ) THEN
46
+ CREATE POLICY "Allow authenticated users to read files"
47
+ ON public.codette_files FOR SELECT
48
+ TO authenticated
49
+ USING (true);
50
+ END IF;
51
+
52
+ -- Check if the admin insert policy exists
53
+ IF NOT EXISTS (
54
+ SELECT 1 FROM pg_policies
55
+ WHERE policyname = 'Allow admin users to insert files'
56
+ AND tablename = 'codette_files'
57
+ ) THEN
58
+ CREATE POLICY "Allow admin users to insert files"
59
+ ON public.codette_files FOR INSERT
60
+ TO authenticated
61
+ WITH CHECK (auth.jwt() ->> 'role' = 'admin');
62
+ END IF;
63
+
64
+ -- Check if the authenticated insert policy exists
65
+ IF NOT EXISTS (
66
+ SELECT 1 FROM pg_policies
67
+ WHERE policyname = 'Allow authenticated users to insert files'
68
+ AND tablename = 'codette_files'
69
+ ) THEN
70
+ CREATE POLICY "Allow authenticated users to insert files"
71
+ ON public.codette_files FOR INSERT
72
+ TO authenticated
73
+ WITH CHECK (true);
74
+ END IF;
75
+ END $$;
76
+
77
+ -- Note: Storage policies for the storage.objects table need to be created through the Supabase dashboard
78
+ -- or using the Supabase CLI, as they require special permissions that aren't available in migrations.
79
+ -- Please create the following policies manually:
80
+ -- 1. "Allow authenticated users to read files" - For SELECT operations on storage.objects where bucket_id = 'codette-files'
81
+ -- 2. "Allow admin users to upload files" - For INSERT operations on storage.objects where bucket_id = 'codette-files' AND auth.jwt() ->> 'role' = 'admin'
project/supabase/migrations/20250523182801_long_field.sql ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Storage and File Management Policies
3
+
4
+ 1. New Tables
5
+ - No new tables created
6
+ 2. Security
7
+ - Enable RLS on codette_files table
8
+ - Add policies for authenticated users to read files
9
+ - Add policies for authenticated users to insert files
10
+ - Add special policy for admin users to insert files
11
+ 3. Changes
12
+ - Ensures storage bucket exists for file storage
13
+ */
14
+
15
+ -- Enable RLS on the codette_files table if not already enabled
16
+ DO $$
17
+ BEGIN
18
+ IF NOT EXISTS (
19
+ SELECT 1 FROM pg_tables
20
+ WHERE tablename = 'codette_files'
21
+ AND rowsecurity = true
22
+ ) THEN
23
+ ALTER TABLE public.codette_files ENABLE ROW LEVEL SECURITY;
24
+ END IF;
25
+ END $$;
26
+
27
+ -- Create storage bucket if it doesn't exist
28
+ DO $$
29
+ BEGIN
30
+ IF NOT EXISTS (
31
+ SELECT 1 FROM storage.buckets WHERE name = 'codette-files'
32
+ ) THEN
33
+ INSERT INTO storage.buckets (id, name)
34
+ VALUES ('codette-files', 'codette-files');
35
+ END IF;
36
+ END $$;
37
+
38
+ -- Create policies for the codette_files table
39
+ DO $$
40
+ BEGIN
41
+ -- Check if the read policy exists
42
+ IF NOT EXISTS (
43
+ SELECT 1 FROM pg_policies
44
+ WHERE policyname = 'Allow authenticated users to read files'
45
+ AND tablename = 'codette_files'
46
+ ) THEN
47
+ CREATE POLICY "Allow authenticated users to read files"
48
+ ON public.codette_files FOR SELECT
49
+ TO authenticated
50
+ USING (true);
51
+ END IF;
52
+
53
+ -- Check if the admin insert policy exists
54
+ IF NOT EXISTS (
55
+ SELECT 1 FROM pg_policies
56
+ WHERE policyname = 'Allow admin users to insert files'
57
+ AND tablename = 'codette_files'
58
+ ) THEN
59
+ CREATE POLICY "Allow admin users to insert files"
60
+ ON public.codette_files FOR INSERT
61
+ TO authenticated
62
+ WITH CHECK (auth.jwt() ->> 'role' = 'admin');
63
+ END IF;
64
+
65
+ -- Check if the authenticated insert policy exists
66
+ IF NOT EXISTS (
67
+ SELECT 1 FROM pg_policies
68
+ WHERE policyname = 'Allow authenticated users to insert files'
69
+ AND tablename = 'codette_files'
70
+ ) THEN
71
+ CREATE POLICY "Allow authenticated users to insert files"
72
+ ON public.codette_files FOR INSERT
73
+ TO authenticated
74
+ WITH CHECK (true);
75
+ END IF;
76
+ END $$;
77
+
78
+ -- Note: Storage policies for the storage.objects table need to be created through the Supabase dashboard
79
+ -- or using the Supabase CLI, as they require special permissions that aren't available in migrations.
80
+ -- Please create the following policies manually:
81
+ -- 1. "Allow authenticated users to read files" - For SELECT operations on storage.objects where bucket_id = 'codette-files'
82
+ -- 2. "Allow admin users to upload files" - For INSERT operations on storage.objects where bucket_id = 'codette-files' AND auth.jwt() ->> 'role' = 'admin'
project/supabase/migrations/20250523183206_odd_moon.sql ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Storage and File Management Setup
3
+
4
+ 1. New Storage
5
+ - Create 'codette-files' storage bucket if it doesn't exist
6
+
7
+ 2. Security
8
+ - Enable Row Level Security on codette_files table
9
+ - Create policies for authenticated users to read files
10
+ - Create policies for authenticated users to insert files
11
+ - Create special policy for admin users to insert files
12
+ */
13
+
14
+ -- Enable RLS on the codette_files table if not already enabled
15
+ DO $$
16
+ BEGIN
17
+ IF NOT EXISTS (
18
+ SELECT 1 FROM pg_tables
19
+ WHERE tablename = 'codette_files'
20
+ AND rowsecurity = true
21
+ ) THEN
22
+ ALTER TABLE public.codette_files ENABLE ROW LEVEL SECURITY;
23
+ END IF;
24
+ END $$;
25
+
26
+ -- Create storage bucket if it doesn't exist
27
+ DO $$
28
+ BEGIN
29
+ IF NOT EXISTS (
30
+ SELECT 1 FROM storage.buckets WHERE name = 'codette-files'
31
+ ) THEN
32
+ INSERT INTO storage.buckets (id, name)
33
+ VALUES ('codette-files', 'codette-files');
34
+ END IF;
35
+ END $$;
36
+
37
+ -- Create policies for the codette_files table
38
+ DO $$
39
+ BEGIN
40
+ -- Check if the read policy exists
41
+ IF NOT EXISTS (
42
+ SELECT 1 FROM pg_policies
43
+ WHERE policyname = 'Allow authenticated users to read files'
44
+ AND tablename = 'codette_files'
45
+ ) THEN
46
+ CREATE POLICY "Allow authenticated users to read files"
47
+ ON public.codette_files FOR SELECT
48
+ TO authenticated
49
+ USING (true);
50
+ END IF;
51
+
52
+ -- Check if the admin insert policy exists
53
+ IF NOT EXISTS (
54
+ SELECT 1 FROM pg_policies
55
+ WHERE policyname = 'Allow admin users to insert files'
56
+ AND tablename = 'codette_files'
57
+ ) THEN
58
+ CREATE POLICY "Allow admin users to insert files"
59
+ ON public.codette_files FOR INSERT
60
+ TO authenticated
61
+ WITH CHECK ((auth.jwt() ->> 'role')::text = 'admin');
62
+ END IF;
63
+
64
+ -- Check if the authenticated insert policy exists
65
+ IF NOT EXISTS (
66
+ SELECT 1 FROM pg_policies
67
+ WHERE policyname = 'Allow authenticated users to insert files'
68
+ AND tablename = 'codette_files'
69
+ ) THEN
70
+ CREATE POLICY "Allow authenticated users to insert files"
71
+ ON public.codette_files FOR INSERT
72
+ TO authenticated
73
+ WITH CHECK (true);
74
+ END IF;
75
+ END $$;
76
+
77
+ -- Note: For storage.objects policies, you'll need to create them through the Supabase dashboard
78
+ -- as migrations don't have sufficient permissions to create these policies directly.
79
+ -- Create these policies manually:
80
+ -- 1. Policy name: "Allow authenticated users to read files"
81
+ -- - For: SELECT operations
82
+ -- - Using expression: bucket_id = 'codette-files'
83
+ --
84
+ -- 2. Policy name: "Allow admin users to upload files"
85
+ -- - For: INSERT operations
86
+ -- - Using expression: bucket_id = 'codette-files' AND (auth.jwt() ->> 'role')::text = 'admin'
project/supabase/migrations/20250523213744_long_sun.sql ADDED
@@ -0,0 +1,90 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Storage and File Management Setup
3
+
4
+ 1. New Storage Configuration
5
+ - Creates 'codette-files' storage bucket if it doesn't exist
6
+ - Sets up proper file management structure
7
+
8
+ 2. Table Policies
9
+ - Enables RLS on codette_files table
10
+ - Creates read policy for authenticated users
11
+ - Creates insert policies for both admin and authenticated users
12
+ - Ensures proper access control and security
13
+
14
+ Note: Storage object policies must be created manually through Supabase dashboard
15
+ */
16
+
17
+ -- Enable RLS on the codette_files table if not already enabled
18
+ DO $$
19
+ BEGIN
20
+ IF NOT EXISTS (
21
+ SELECT 1 FROM pg_tables
22
+ WHERE tablename = 'codette_files'
23
+ AND rowsecurity = true
24
+ ) THEN
25
+ ALTER TABLE public.codette_files ENABLE ROW LEVEL SECURITY;
26
+ END IF;
27
+ END $$;
28
+
29
+ -- Create storage bucket if it doesn't exist
30
+ DO $$
31
+ BEGIN
32
+ IF NOT EXISTS (
33
+ SELECT 1 FROM storage.buckets WHERE name = 'codette-files'
34
+ ) THEN
35
+ INSERT INTO storage.buckets (id, name, public)
36
+ VALUES ('codette-files', 'codette-files', false);
37
+ END IF;
38
+ END $$;
39
+
40
+ -- Create policies for the codette_files table
41
+ DO $$
42
+ BEGIN
43
+ -- Create read policy if it doesn't exist
44
+ IF NOT EXISTS (
45
+ SELECT 1 FROM pg_policies
46
+ WHERE policyname = 'Allow authenticated users to read files'
47
+ AND tablename = 'codette_files'
48
+ ) THEN
49
+ CREATE POLICY "Allow authenticated users to read files"
50
+ ON public.codette_files FOR SELECT
51
+ TO authenticated
52
+ USING (true);
53
+ END IF;
54
+
55
+ -- Create admin insert policy if it doesn't exist
56
+ IF NOT EXISTS (
57
+ SELECT 1 FROM pg_policies
58
+ WHERE policyname = 'Allow admin users to insert files'
59
+ AND tablename = 'codette_files'
60
+ ) THEN
61
+ CREATE POLICY "Allow admin users to insert files"
62
+ ON public.codette_files FOR INSERT
63
+ TO authenticated
64
+ WITH CHECK ((auth.jwt() ->> 'role')::text = 'admin');
65
+ END IF;
66
+
67
+ -- Create authenticated insert policy if it doesn't exist
68
+ IF NOT EXISTS (
69
+ SELECT 1 FROM pg_policies
70
+ WHERE policyname = 'Allow authenticated users to insert files'
71
+ AND tablename = 'codette_files'
72
+ ) THEN
73
+ CREATE POLICY "Allow authenticated users to insert files"
74
+ ON public.codette_files FOR INSERT
75
+ TO authenticated
76
+ WITH CHECK (true);
77
+ END IF;
78
+ END $$;
79
+
80
+ -- Important: Storage object policies must be created manually through the Supabase dashboard
81
+ -- Create the following policies:
82
+ -- 1. "Allow authenticated users to read files"
83
+ -- - Operation: SELECT
84
+ -- - Target roles: authenticated
85
+ -- - Using expression: bucket_id = 'codette-files'
86
+ --
87
+ -- 2. "Allow admin users to upload files"
88
+ -- - Operation: INSERT
89
+ -- - Target roles: authenticated
90
+ -- - Using expression: bucket_id = 'codette-files' AND (auth.jwt() ->> 'role')::text = 'admin'
project/supabase/migrations/20250523222316_square_gate.sql ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Fix RLS policies for codette_files table
3
+
4
+ 1. Changes
5
+ - Drop existing RLS policies that might be conflicting
6
+ - Add new RLS policies for admin users
7
+ - Allow admin users to insert files
8
+ - Allow admin users to read files
9
+ - Allow admin users to update files
10
+ - Allow admin users to delete files
11
+ - Add RLS policies for regular authenticated users
12
+ - Allow reading files only
13
+
14
+ 2. Security
15
+ - Ensures only admin users can upload/modify files
16
+ - All authenticated users can read files
17
+ - Proper RLS enforcement for file management
18
+ */
19
+
20
+ -- Drop existing policies to avoid conflicts
21
+ DROP POLICY IF EXISTS "Allow admin users to insert files" ON codette_files;
22
+ DROP POLICY IF EXISTS "Allow authenticated users to insert files" ON codette_files;
23
+ DROP POLICY IF EXISTS "Allow authenticated users to read files" ON codette_files;
24
+
25
+ -- Create new policies with proper checks
26
+ CREATE POLICY "Allow admin users to manage files"
27
+ ON codette_files
28
+ FOR ALL
29
+ TO authenticated
30
+ USING (
31
+ (auth.jwt() ->> 'role')::text = 'admin'
32
+ )
33
+ WITH CHECK (
34
+ (auth.jwt() ->> 'role')::text = 'admin'
35
+ );
36
+
37
+ CREATE POLICY "Allow authenticated users to read files"
38
+ ON codette_files
39
+ FOR SELECT
40
+ TO authenticated
41
+ USING (true);
42
+
43
+ -- Enable RLS if not already enabled
44
+ ALTER TABLE codette_files ENABLE ROW LEVEL SECURITY;
project/supabase/migrations/20250523222514_muddy_desert.sql ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Storage bucket and RLS policies
3
+
4
+ 1. Changes
5
+ - Create storage bucket for Codette files
6
+ - Set up RLS policies for the bucket
7
+
8
+ 2. Security
9
+ - Enable RLS policies for storage bucket
10
+ - Allow authenticated users to read files
11
+ - Allow authenticated users to upload files
12
+ - Allow authenticated users to update files
13
+ - Allow authenticated users to delete files
14
+ */
15
+
16
+ -- Create the storage bucket
17
+ INSERT INTO storage.buckets (id, name)
18
+ VALUES ('codette-files', 'codette-files')
19
+ ON CONFLICT (id) DO NOTHING;
20
+
21
+ -- Drop existing policies if they exist
22
+ DROP POLICY IF EXISTS "Allow authenticated users to read files" ON storage.objects;
23
+ DROP POLICY IF EXISTS "Allow authenticated users to upload files" ON storage.objects;
24
+ DROP POLICY IF EXISTS "Allow authenticated users to update files" ON storage.objects;
25
+ DROP POLICY IF EXISTS "Allow authenticated users to delete files" ON storage.objects;
26
+
27
+ -- Set up RLS policies for the bucket
28
+ CREATE POLICY "Allow authenticated users to read files"
29
+ ON storage.objects FOR SELECT
30
+ TO authenticated
31
+ USING (bucket_id = 'codette-files');
32
+
33
+ CREATE POLICY "Allow authenticated users to upload files"
34
+ ON storage.objects FOR INSERT
35
+ TO authenticated
36
+ WITH CHECK (bucket_id = 'codette-files');
37
+
38
+ CREATE POLICY "Allow authenticated users to update files"
39
+ ON storage.objects FOR UPDATE
40
+ TO authenticated
41
+ USING (bucket_id = 'codette-files')
42
+ WITH CHECK (bucket_id = 'codette-files');
43
+
44
+ CREATE POLICY "Allow authenticated users to delete files"
45
+ ON storage.objects FOR DELETE
46
+ TO authenticated
47
+ USING (bucket_id = 'codette-files');
project/supabase/migrations/20250523222518_bronze_dew.sql ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Update RLS policies for file management
3
+
4
+ 1. Changes
5
+ - Update storage.objects policies
6
+ - Update codette_files table policies
7
+
8
+ 2. Security
9
+ - Allow authenticated users to read files
10
+ - Allow admin users to upload files
11
+ - Allow admin users to insert file records
12
+ */
13
+
14
+ BEGIN;
15
+
16
+ -- Drop existing policies if they exist
17
+ DROP POLICY IF EXISTS "Allow authenticated users to read files" ON storage.objects;
18
+ DROP POLICY IF EXISTS "Allow admin users to upload files" ON storage.objects;
19
+ DROP POLICY IF EXISTS "Allow admin users to insert files" ON public.codette_files;
20
+
21
+ -- Create policy to allow authenticated users to read any file
22
+ CREATE POLICY "Allow authenticated users to read files"
23
+ ON storage.objects FOR SELECT
24
+ TO authenticated
25
+ USING (bucket_id = 'codette-files');
26
+
27
+ -- Create policy to allow only admin users to upload files
28
+ CREATE POLICY "Allow admin users to upload files"
29
+ ON storage.objects FOR INSERT
30
+ TO authenticated
31
+ WITH CHECK (bucket_id = 'codette-files' AND auth.jwt() ->> 'role' = 'admin');
32
+
33
+ -- Update the codette_files table policies
34
+ CREATE POLICY "Allow admin users to insert files"
35
+ ON public.codette_files FOR INSERT
36
+ TO authenticated
37
+ WITH CHECK (auth.jwt() ->> 'role' = 'admin');
38
+
39
+ COMMIT;
project/supabase/migrations/20250523222523_orange_bread.sql ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Update RLS policies for file management
3
+
4
+ 1. Changes
5
+ - Update storage.objects policies
6
+ - Update codette_files table policies
7
+ - Enable RLS on codette_files table
8
+
9
+ 2. Security
10
+ - Allow authenticated users to read files
11
+ - Allow admin users to upload files
12
+ - Allow authenticated users to insert files
13
+ */
14
+
15
+ -- Drop existing policies if they exist
16
+ DROP POLICY IF EXISTS "Allow authenticated users to read files" ON storage.objects;
17
+ DROP POLICY IF EXISTS "Allow admin users to upload files" ON storage.objects;
18
+ DROP POLICY IF EXISTS "Allow authenticated users to read files" ON public.codette_files;
19
+ DROP POLICY IF EXISTS "Allow admin users to insert files" ON public.codette_files;
20
+ DROP POLICY IF EXISTS "Allow authenticated users to insert files" ON public.codette_files;
21
+
22
+ -- Storage Policies
23
+ CREATE POLICY "Allow authenticated users to read files"
24
+ ON storage.objects FOR SELECT
25
+ TO authenticated
26
+ USING (bucket_id = 'codette-files');
27
+
28
+ CREATE POLICY "Allow admin users to upload files"
29
+ ON storage.objects FOR INSERT
30
+ TO authenticated
31
+ WITH CHECK (
32
+ bucket_id = 'codette-files'
33
+ AND (auth.jwt() ->> 'role' = 'admin')
34
+ );
35
+
36
+ -- File Management Policies
37
+ CREATE POLICY "Allow authenticated users to read files"
38
+ ON public.codette_files FOR SELECT
39
+ TO authenticated
40
+ USING (true);
41
+
42
+ CREATE POLICY "Allow admin users to insert files"
43
+ ON public.codette_files FOR INSERT
44
+ TO authenticated
45
+ WITH CHECK (auth.jwt() ->> 'role' = 'admin');
46
+
47
+ CREATE POLICY "Allow authenticated users to insert files"
48
+ ON public.codette_files FOR INSERT
49
+ TO authenticated
50
+ WITH CHECK (true);
51
+
52
+ -- Enable RLS
53
+ ALTER TABLE public.codette_files ENABLE ROW LEVEL SECURITY;
project/supabase/migrations/20250524062844_tender_thunder.sql ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Update codette_files table and policies
3
+
4
+ 1. New Tables
5
+ - Ensures codette_files table exists with proper structure
6
+ - id (uuid, primary key)
7
+ - filename (text)
8
+ - storage_path (text)
9
+ - file_type (text, nullable)
10
+ - uploaded_at (timestamptz)
11
+ - created_at (timestamptz)
12
+
13
+ 2. Security
14
+ - Enables RLS if not already enabled
15
+ - Adds admin-specific policies for file management
16
+ */
17
+
18
+ -- Create table if it doesn't exist
19
+ CREATE TABLE IF NOT EXISTS public.codette_files (
20
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
21
+ filename text NOT NULL,
22
+ storage_path text NOT NULL,
23
+ file_type text,
24
+ uploaded_at timestamptz DEFAULT now(),
25
+ created_at timestamptz DEFAULT now()
26
+ );
27
+
28
+ -- Enable Row Level Security (idempotent operation)
29
+ ALTER TABLE public.codette_files ENABLE ROW LEVEL SECURITY;
30
+
31
+ -- Drop existing policies to avoid conflicts
32
+ DROP POLICY IF EXISTS "Allow authenticated users to read files" ON public.codette_files;
33
+ DROP POLICY IF EXISTS "Allow authenticated users to insert files" ON public.codette_files;
34
+ DROP POLICY IF EXISTS "Allow admin users to manage files" ON public.codette_files;
35
+ DROP POLICY IF EXISTS "Allow admin users to insert files" ON public.codette_files;
36
+
37
+ -- Create new policies
38
+ CREATE POLICY "Allow authenticated users to read files"
39
+ ON public.codette_files
40
+ FOR SELECT
41
+ TO authenticated
42
+ USING (true);
43
+
44
+ CREATE POLICY "Allow authenticated users to insert files"
45
+ ON public.codette_files
46
+ FOR INSERT
47
+ TO authenticated
48
+ WITH CHECK (true);
49
+
50
+ -- Add admin-specific policies
51
+ CREATE POLICY "Allow admin users to manage files"
52
+ ON public.codette_files
53
+ FOR ALL
54
+ TO authenticated
55
+ USING ((auth.jwt() ->> 'role'::text) = 'admin'::text)
56
+ WITH CHECK ((auth.jwt() ->> 'role'::text) = 'admin'::text);
57
+
58
+ CREATE POLICY "Allow admin users to insert files"
59
+ ON public.codette_files
60
+ FOR INSERT
61
+ TO authenticated
62
+ WITH CHECK ((auth.jwt() ->> 'role'::text) = 'admin'::text);
project/supabase/migrations/20250524213845_mellow_recipe.sql ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Add user roles table and admin role policy
3
+
4
+ 1. New Tables
5
+ - `user_roles`
6
+ - `id` (uuid, primary key)
7
+ - `user_id` (uuid, references auth.users)
8
+ - `role` (text)
9
+ - `created_at` (timestamptz)
10
+
11
+ 2. Security
12
+ - Enable RLS on `user_roles` table
13
+ - Add policies for admin role management
14
+ */
15
+
16
+ -- Create user_roles table
17
+ CREATE TABLE IF NOT EXISTS user_roles (
18
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
19
+ user_id uuid REFERENCES auth.users NOT NULL,
20
+ role text NOT NULL,
21
+ created_at timestamptz DEFAULT now()
22
+ );
23
+
24
+ -- Enable RLS
25
+ ALTER TABLE user_roles ENABLE ROW LEVEL SECURITY;
26
+
27
+ -- Policies for user_roles table
28
+ CREATE POLICY "Users can read their own role"
29
+ ON user_roles
30
+ FOR SELECT
31
+ TO authenticated
32
+ USING (auth.uid() = user_id);
33
+
34
+ CREATE POLICY "Only admins can manage roles"
35
+ ON user_roles
36
+ FOR ALL
37
+ TO authenticated
38
+ USING (
39
+ EXISTS (
40
+ SELECT 1 FROM user_roles
41
+ WHERE user_id = auth.uid()
42
+ AND role = 'admin'
43
+ )
44
+ );
project/supabase/migrations/20250524214450_green_poetry.sql ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Authentication and User Roles Setup
3
+
4
+ 1. New Tables
5
+ - `user_roles`
6
+ - `id` (uuid, primary key)
7
+ - `user_id` (uuid, references auth.users)
8
+ - `role` (text)
9
+ - `created_at` (timestamp with time zone)
10
+
11
+ 2. Security
12
+ - Enable RLS on `user_roles` table
13
+ - Add policies for authenticated users to read their own role
14
+ - Add policy for admin users to manage roles
15
+ */
16
+
17
+ -- Create user_roles table
18
+ CREATE TABLE IF NOT EXISTS public.user_roles (
19
+ id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
20
+ user_id uuid REFERENCES auth.users NOT NULL,
21
+ role text NOT NULL,
22
+ created_at timestamptz DEFAULT now()
23
+ );
24
+
25
+ -- Enable RLS
26
+ ALTER TABLE public.user_roles ENABLE ROW LEVEL SECURITY;
27
+
28
+ -- Policies
29
+ CREATE POLICY "Users can read own role"
30
+ ON public.user_roles
31
+ FOR SELECT
32
+ TO authenticated
33
+ USING (auth.uid() = user_id);
34
+
35
+ CREATE POLICY "Admin users can manage roles"
36
+ ON public.user_roles
37
+ FOR ALL
38
+ TO authenticated
39
+ USING ((SELECT role FROM public.user_roles WHERE user_id = auth.uid()) = 'admin')
40
+ WITH CHECK ((SELECT role FROM public.user_roles WHERE user_id = auth.uid()) = 'admin');
41
+
42
+ -- Create admin user if not exists
43
+ DO $$
44
+ BEGIN
45
+ IF NOT EXISTS (
46
+ SELECT 1 FROM auth.users WHERE email = '[email protected]'
47
+ ) THEN
48
+ INSERT INTO auth.users (
49
+ instance_id,
50
+ id,
51
+ aud,
52
+ role,
53
+ email,
54
+ encrypted_password,
55
+ email_confirmed_at,
56
+ created_at,
57
+ updated_at,
58
+ confirmation_token,
59
+ recovery_token
60
+ )
61
+ VALUES (
62
+ '00000000-0000-0000-0000-000000000000',
63
+ gen_random_uuid(),
64
+ 'authenticated',
65
+ 'authenticated',
66
67
+ crypt('admin123', gen_salt('bf')), -- Default password: admin123
68
+ now(),
69
+ now(),
70
+ now(),
71
+ encode(gen_random_bytes(32), 'hex'),
72
+ encode(gen_random_bytes(32), 'hex')
73
+ );
74
+
75
+ -- Add admin role
76
+ INSERT INTO public.user_roles (user_id, role)
77
+ SELECT id, 'admin'
78
+ FROM auth.users
79
+ WHERE email = '[email protected]';
80
+ END IF;
81
+ END $$;
project/supabase/migrations/20250524214705_sunny_sunset.sql ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Storage bucket and policies setup
3
+
4
+ 1. Changes
5
+ - Creates storage bucket for file storage
6
+ - Sets up RLS policies for authenticated users
7
+
8
+ 2. Security
9
+ - Enables secure file access for authenticated users
10
+ - Implements proper access control through RLS policies
11
+ */
12
+
13
+ -- Create the storage bucket if it doesn't exist
14
+ INSERT INTO storage.buckets (id, name)
15
+ VALUES ('codette-files', 'codette-files')
16
+ ON CONFLICT (id) DO NOTHING;
project/supabase/migrations/20250524214708_lively_cell.sql ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # File management policies
3
+
4
+ 1. Changes
5
+ - Creates policies for file management
6
+ - Sets up proper access control for authenticated users and admins
7
+
8
+ 2. Security
9
+ - Implements RLS policies for the codette_files table
10
+ - Ensures proper access control based on user roles
11
+ */
12
+
13
+ -- Enable RLS on codette_files table
14
+ ALTER TABLE public.codette_files ENABLE ROW LEVEL SECURITY;
15
+
16
+ -- Create policies for the codette_files table
17
+ DO $$
18
+ BEGIN
19
+ -- Check if the read policy exists
20
+ IF NOT EXISTS (
21
+ SELECT 1 FROM pg_policies
22
+ WHERE policyname = 'Allow authenticated users to read files'
23
+ AND tablename = 'codette_files'
24
+ ) THEN
25
+ CREATE POLICY "Allow authenticated users to read files"
26
+ ON public.codette_files FOR SELECT
27
+ TO authenticated
28
+ USING (true);
29
+ END IF;
30
+
31
+ -- Check if the admin insert policy exists
32
+ IF NOT EXISTS (
33
+ SELECT 1 FROM pg_policies
34
+ WHERE policyname = 'Allow admin users to insert files'
35
+ AND tablename = 'codette_files'
36
+ ) THEN
37
+ CREATE POLICY "Allow admin users to insert files"
38
+ ON public.codette_files FOR INSERT
39
+ TO authenticated
40
+ WITH CHECK (auth.jwt() ->> 'role' = 'admin');
41
+ END IF;
42
+
43
+ -- Check if the authenticated insert policy exists
44
+ IF NOT EXISTS (
45
+ SELECT 1 FROM pg_policies
46
+ WHERE policyname = 'Allow authenticated users to insert files'
47
+ AND tablename = 'codette_files'
48
+ ) THEN
49
+ CREATE POLICY "Allow authenticated users to insert files"
50
+ ON public.codette_files FOR INSERT
51
+ TO authenticated
52
+ WITH CHECK (true);
53
+ END IF;
54
+ END $$;
project/supabase/migrations/20250524214713_yellow_dawn.sql ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # File management and storage setup
3
+
4
+ 1. Changes
5
+ - Enables RLS on codette_files table
6
+ - Creates necessary policies for file management
7
+
8
+ 2. Security
9
+ - Implements proper access control through RLS
10
+ - Sets up role-based permissions
11
+ */
12
+
13
+ -- Enable RLS on codette_files table if not already enabled
14
+ DO $$
15
+ BEGIN
16
+ IF NOT EXISTS (
17
+ SELECT 1 FROM pg_tables
18
+ WHERE tablename = 'codette_files'
19
+ AND rowsecurity = true
20
+ ) THEN
21
+ ALTER TABLE public.codette_files ENABLE ROW LEVEL SECURITY;
22
+ END IF;
23
+ END $$;
24
+
25
+ -- Create policies for the codette_files table
26
+ DO $$
27
+ BEGIN
28
+ -- Check if the read policy exists
29
+ IF NOT EXISTS (
30
+ SELECT 1 FROM pg_policies
31
+ WHERE policyname = 'Allow authenticated users to read files'
32
+ AND tablename = 'codette_files'
33
+ ) THEN
34
+ CREATE POLICY "Allow authenticated users to read files"
35
+ ON public.codette_files FOR SELECT
36
+ TO authenticated
37
+ USING (true);
38
+ END IF;
39
+
40
+ -- Check if the admin insert policy exists
41
+ IF NOT EXISTS (
42
+ SELECT 1 FROM pg_policies
43
+ WHERE policyname = 'Allow admin users to insert files'
44
+ AND tablename = 'codette_files'
45
+ ) THEN
46
+ CREATE POLICY "Allow admin users to insert files"
47
+ ON public.codette_files FOR INSERT
48
+ TO authenticated
49
+ WITH CHECK (auth.jwt() ->> 'role' = 'admin');
50
+ END IF;
51
+
52
+ -- Check if the authenticated insert policy exists
53
+ IF NOT EXISTS (
54
+ SELECT 1 FROM pg_policies
55
+ WHERE policyname = 'Allow authenticated users to insert files'
56
+ AND tablename = 'codette_files'
57
+ ) THEN
58
+ CREATE POLICY "Allow authenticated users to insert files"
59
+ ON public.codette_files FOR INSERT
60
+ TO authenticated
61
+ WITH CHECK (true);
62
+ END IF;
63
+ END $$;
project/supabase/migrations/20250524215300_flat_firefly.sql ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ # Add get_user_role function
3
+
4
+ 1. New Functions
5
+ - `get_user_role`: Returns the role of the authenticated user
6
+
7
+ 2. Security
8
+ - Function is only accessible to authenticated users
9
+ - Returns the user's role from user_roles table
10
+ */
11
+
12
+ -- Create function to get user role
13
+ CREATE OR REPLACE FUNCTION public.get_user_role()
14
+ RETURNS TABLE (role text)
15
+ LANGUAGE plpgsql
16
+ SECURITY DEFINER
17
+ SET search_path = public
18
+ AS $$
19
+ BEGIN
20
+ RETURN QUERY
21
+ SELECT ur.role
22
+ FROM public.user_roles ur
23
+ WHERE ur.user_id = auth.uid()
24
+ LIMIT 1;
25
+ END;
26
+ $$;
project/tailwind.config.js ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /** @type {import('tailwindcss').Config} */
2
+ export default {
3
+ content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
4
+ darkMode: 'class',
5
+ theme: {
6
+ extend: {
7
+ colors: {
8
+ primary: {
9
+ 50: '#EFF6FF',
10
+ 100: '#DBEAFE',
11
+ 200: '#BFDBFE',
12
+ 300: '#93C5FD',
13
+ 400: '#60A5FA',
14
+ 500: '#3B82F6',
15
+ 600: '#2563EB',
16
+ 700: '#1D4ED8',
17
+ 800: '#1E40AF',
18
+ 900: '#1E3A8A',
19
+ },
20
+ secondary: {
21
+ 50: '#F5F3FF',
22
+ 100: '#EDE9FE',
23
+ 200: '#DDD6FE',
24
+ 300: '#C4B5FD',
25
+ 400: '#A78BFA',
26
+ 500: '#8B5CF6',
27
+ 600: '#7C3AED',
28
+ 700: '#6D28D9',
29
+ 800: '#5B21B6',
30
+ 900: '#4C1D95',
31
+ },
32
+ accent: {
33
+ 50: '#ECFDF5',
34
+ 100: '#D1FAE5',
35
+ 200: '#A7F3D0',
36
+ 300: '#6EE7B7',
37
+ 400: '#34D399',
38
+ 500: '#10B981',
39
+ 600: '#059669',
40
+ 700: '#047857',
41
+ 800: '#065F46',
42
+ 900: '#064E3B',
43
+ },
44
+ },
45
+ animation: {
46
+ 'pulse': 'pulse 2s infinite',
47
+ 'float': 'float 3s ease-in-out infinite',
48
+ 'spin-slow': 'spin 4s linear infinite',
49
+ },
50
+ keyframes: {
51
+ float: {
52
+ '0%, 100%': { transform: 'translateY(0)' },
53
+ '50%': { transform: 'translateY(-10px)' },
54
+ },
55
+ },
56
+ backdropFilter: {
57
+ 'none': 'none',
58
+ 'blur': 'blur(8px)',
59
+ },
60
+ },
61
+ },
62
+ plugins: [],
63
+ };
project/tsconfig.app.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "useDefineForClassFields": true,
5
+ "lib": ["ES2020", "DOM", "DOM.Iterable"],
6
+ "module": "ESNext",
7
+ "skipLibCheck": true,
8
+
9
+ /* Bundler mode */
10
+ "moduleResolution": "bundler",
11
+ "allowImportingTsExtensions": true,
12
+ "isolatedModules": true,
13
+ "moduleDetection": "force",
14
+ "noEmit": true,
15
+ "jsx": "react-jsx",
16
+
17
+ /* Linting */
18
+ "strict": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "noFallthroughCasesInSwitch": true
22
+ },
23
+ "include": ["src"]
24
+ }
project/tsconfig.json ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ]
7
+ }
project/tsconfig.node.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "lib": ["ES2023"],
5
+ "module": "ESNext",
6
+ "skipLibCheck": true,
7
+
8
+ /* Bundler mode */
9
+ "moduleResolution": "bundler",
10
+ "allowImportingTsExtensions": true,
11
+ "isolatedModules": true,
12
+ "moduleDetection": "force",
13
+ "noEmit": true,
14
+
15
+ /* Linting */
16
+ "strict": true,
17
+ "noUnusedLocals": true,
18
+ "noUnusedParameters": true,
19
+ "noFallthroughCasesInSwitch": true
20
+ },
21
+ "include": ["vite.config.ts"]
22
+ }