Spaces:
Running
Running
اريد بأن تقوم بإنشاء موقع ويب يعمل على الوضائف التاليه:
Browse files1. يوفر واجهه تمكنني من إدخال OpenAI API Keys وربط الموقع بحسابي على جتهب
2. ينتقل إلى واجهه يطلب فيها تحديد مستودع جتهب الذي اريد ان اعمل عليه (من المستودعات التي بالحساب الذي قمت بربطه بالموقع)
3. ينتقل إلى خانه المحادثه مع نموذج الذكاء الاصطناعي ويقوم بانشاء سحب جديد على المستودع الذي حددته و بحيث عندما اكتب اي امر يقوم نموذج الذكاء الاصطناعي بتنفيذه على المستودع الذي حددته مسبقا
4. عندما اريد الانتهاء من التعديلات اضغط على زر الدمج وبعدها يتم دمج جميع التغيرات على المستودع الذي حددته مسبقا
الفكره مشابهه لموقع cursor (واجهه الهاتف المحمول)
- index.html +243 -182
index.html
CHANGED
|
@@ -1,248 +1,309 @@
|
|
| 1 |
-
|
| 2 |
<!DOCTYPE html>
|
| 3 |
<html lang="ar" dir="rtl">
|
| 4 |
<head>
|
| 5 |
<meta charset="UTF-8">
|
| 6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 7 |
<title>GitHub AI Assistant</title>
|
|
|
|
| 8 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 10 |
-
<
|
|
|
|
|
|
|
|
|
|
| 11 |
</head>
|
| 12 |
<body class="bg-gray-50 min-h-screen">
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
<div
|
| 16 |
-
<div class="
|
| 17 |
-
<
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
<form id="setup-form" class="space-y-4">
|
| 22 |
-
<div>
|
| 23 |
-
<label for="openai-key" class="block text-sm font-medium text-gray-700 mb-1">OpenAI API Key</label>
|
| 24 |
-
<input type="password" id="openai-key" required
|
| 25 |
-
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
| 26 |
</div>
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
| 32 |
</div>
|
| 33 |
-
|
| 34 |
-
<button type="submit"
|
| 35 |
-
class="w-full bg-blue-600 text-white py-2 px-4 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-200">
|
| 36 |
-
الاتصال والاستمرار
|
| 37 |
-
</button>
|
| 38 |
-
</form>
|
| 39 |
</div>
|
|
|
|
| 40 |
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
</div>
|
| 47 |
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
| 50 |
</div>
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
</button>
|
| 56 |
</div>
|
| 57 |
|
| 58 |
-
<!--
|
| 59 |
-
<div id="
|
| 60 |
-
<
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 64 |
</button>
|
| 65 |
-
<h2 id="current-repo" class="text-lg font-semibold text-gray-800">المستودع المحدد</h2>
|
| 66 |
</div>
|
| 67 |
-
<button id="merge-btn"
|
| 68 |
-
class="bg-green-600 text-white px-4 py-2 rounded-md hover:bg-green-700 focus:outline-none focus:ring-2 focus:ring-green-500 transition duration-200 hidden">
|
| 69 |
-
دمج التغييرات
|
| 70 |
-
</button>
|
| 71 |
</div>
|
| 72 |
-
|
| 73 |
-
<div id="chat-messages" class="
|
| 74 |
<!-- Chat messages will appear here -->
|
| 75 |
</div>
|
| 76 |
-
|
| 77 |
-
<div class="
|
| 78 |
-
<
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
class="bg-blue-600 text-white px-4 py-2 rounded-md hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-200">
|
| 84 |
-
إرسال
|
| 85 |
-
</button>
|
| 86 |
-
</form>
|
| 87 |
</div>
|
| 88 |
</div>
|
| 89 |
-
|
|
|
|
|
|
|
|
|
|
| 90 |
|
| 91 |
<script>
|
| 92 |
-
feather.replace();
|
| 93 |
-
|
| 94 |
// State management
|
| 95 |
-
let currentState =
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
|
| 100 |
-
|
| 101 |
-
|
| 102 |
-
|
| 103 |
-
|
| 104 |
-
const
|
| 105 |
-
const
|
| 106 |
-
const
|
| 107 |
-
const
|
| 108 |
-
const mergeBtn = document.getElementById('merge-btn');
|
| 109 |
-
const chatForm = document.getElementById('chat-form');
|
| 110 |
-
const messageInput = document.getElementById('message-input');
|
| 111 |
const chatMessages = document.getElementById('chat-messages');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 112 |
|
| 113 |
-
//
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
|
| 117 |
-
|
| 118 |
-
|
| 119 |
-
|
| 120 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 121 |
}
|
| 122 |
|
| 123 |
-
|
| 124 |
-
setupForm.addEventListener('submit', async (e) => {
|
| 125 |
-
e.preventDefault();
|
| 126 |
-
|
| 127 |
const openaiKey = document.getElementById('openai-key').value;
|
| 128 |
const githubToken = document.getElementById('github-token').value;
|
| 129 |
-
|
| 130 |
-
// Store credentials (in a real app, use secure storage)
|
| 131 |
-
localStorage.setItem('openaiKey', openaiKey);
|
| 132 |
-
localStorage.setItem('githubToken', githubToken);
|
| 133 |
-
|
| 134 |
-
// Load repositories
|
| 135 |
-
await loadRepositories();
|
| 136 |
-
showPage(repoPage);
|
| 137 |
-
});
|
| 138 |
|
| 139 |
-
|
| 140 |
-
|
| 141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 142 |
|
| 143 |
try {
|
| 144 |
-
|
| 145 |
-
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
| 149 |
-
|
| 150 |
-
|
| 151 |
-
|
| 152 |
-
|
| 153 |
-
const repos = await response.json();
|
| 154 |
-
displayRepositories(repos);
|
| 155 |
} catch (error) {
|
| 156 |
-
|
| 157 |
}
|
| 158 |
}
|
| 159 |
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
|
| 163 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 164 |
repos.forEach(repo => {
|
| 165 |
-
const repoElement = document.createElement('
|
| 166 |
-
repoElement.className = '
|
| 167 |
repoElement.innerHTML = `
|
| 168 |
-
<div class="
|
| 169 |
-
|
|
|
|
|
|
|
|
|
|
| 170 |
`;
|
| 171 |
-
|
| 172 |
-
|
| 173 |
-
selectedRepo = repo;
|
| 174 |
-
currentRepo.textContent = repo.name;
|
| 175 |
-
showPage(chatPage);
|
| 176 |
-
addMessage('system', 'مرحباً! أنا مساعد الذكاء الاصطناعي. كيف يمكنني مساعدتك في هذا المستودع؟');
|
| 177 |
-
});
|
| 178 |
-
|
| 179 |
-
repoList.appendChild(repoElement);
|
| 180 |
});
|
|
|
|
| 181 |
}
|
| 182 |
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 186 |
|
| 187 |
-
|
| 188 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 189 |
const messageDiv = document.createElement('div');
|
| 190 |
-
messageDiv.className = `p-3 rounded-lg
|
| 191 |
-
|
| 192 |
-
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
messageDiv.textContent = message;
|
| 196 |
-
|
| 197 |
chatMessages.appendChild(messageDiv);
|
| 198 |
chatMessages.scrollTop = chatMessages.scrollHeight;
|
| 199 |
|
| 200 |
-
|
| 201 |
}
|
| 202 |
|
| 203 |
-
|
| 204 |
-
e.preventDefault();
|
| 205 |
-
|
| 206 |
const message = messageInput.value.trim();
|
| 207 |
if (!message) return;
|
| 208 |
-
|
| 209 |
-
// Add user message
|
| 210 |
-
addMessage('user', message);
|
| 211 |
messageInput.value = '';
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
|
| 216 |
-
// Simulate AI response (in a real app, this would call OpenAI API)
|
| 217 |
-
setTimeout(() => {
|
| 218 |
-
addMessage('ai', `تم معالجة أمرك "${message}" على المستودع ${selectedRepo.name}. سيتم تنفيذ التغييرات المطلوبة.`);
|
| 219 |
-
}, 1000);
|
| 220 |
-
});
|
| 221 |
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 225 |
|
| 226 |
-
//
|
| 227 |
-
|
|
|
|
|
|
|
|
|
|
| 228 |
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
|
| 236 |
-
const storedOpenAIKey = localStorage.getItem('openaiKey');
|
| 237 |
-
const storedGitHubToken = localStorage.getItem('githubToken');
|
| 238 |
|
| 239 |
-
|
| 240 |
-
|
| 241 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 242 |
}
|
|
|
|
|
|
|
| 243 |
|
| 244 |
-
|
| 245 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 246 |
</script>
|
| 247 |
</body>
|
| 248 |
-
</html>
|
|
|
|
|
|
|
| 1 |
<!DOCTYPE html>
|
| 2 |
<html lang="ar" dir="rtl">
|
| 3 |
<head>
|
| 4 |
<meta charset="UTF-8">
|
| 5 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
<title>GitHub AI Assistant</title>
|
| 7 |
+
<link rel="icon" type="image/x-icon" href="/static/favicon.ico">
|
| 8 |
<script src="https://cdn.tailwindcss.com"></script>
|
| 9 |
<script src="https://cdn.jsdelivr.net/npm/feather-icons/dist/feather.min.js"></script>
|
| 10 |
+
<style>
|
| 11 |
+
@import url('https://fonts.googleapis.com/css2?family=Tajawal:wght@300;400;500;700&display=swap');
|
| 12 |
+
body { font-family: 'Tajawal', sans-serif; }
|
| 13 |
+
</style>
|
| 14 |
</head>
|
| 15 |
<body class="bg-gray-50 min-h-screen">
|
| 16 |
+
<!-- Header -->
|
| 17 |
+
<header class="bg-white shadow-sm border-b">
|
| 18 |
+
<div class="max-w-7xl mx-auto px-4 py-4">
|
| 19 |
+
<div class="flex items-center justify-between">
|
| 20 |
+
<div class="flex items-center space-x-2 space-x-reverse">
|
| 21 |
+
<i data-feather="git-branch" class="w-8 h-8 text-blue-600"></i>
|
| 22 |
+
<h1 class="text-xl font-bold text-gray-900">GitHub AI Assistant</h1>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
</div>
|
| 24 |
+
<div id="user-section" class="hidden">
|
| 25 |
+
<button id="logout-btn" class="text-gray-600 hover:text-gray-900">
|
| 26 |
+
<i data-feather="log-out" class="w-5 h-5"></i>
|
| 27 |
+
</button>
|
|
|
|
| 28 |
</div>
|
| 29 |
+
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 30 |
</div>
|
| 31 |
+
</header>
|
| 32 |
|
| 33 |
+
<!-- Main Content -->
|
| 34 |
+
<main class="max-w-4xl mx-auto px-4 py-8">
|
| 35 |
+
<!-- Setup Section -->
|
| 36 |
+
<div id="setup-section" class="bg-white rounded-lg shadow-md p-6 mb-6">
|
| 37 |
+
<h2 class="text-2xl font-bold text-gray-900 mb-4">إعدادات الربط</h2>
|
|
|
|
| 38 |
|
| 39 |
+
<!-- OpenAI API Key -->
|
| 40 |
+
<div class="mb-6">
|
| 41 |
+
<label class="block text-sm font-medium text-gray-700 mb-2">OpenAI API Key</label>
|
| 42 |
+
<input type="password" id="openai-key" placeholder="أدخل مفتاح OpenAI API الخاص بك"
|
| 43 |
+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
| 44 |
</div>
|
| 45 |
+
|
| 46 |
+
<!-- GitHub Token -->
|
| 47 |
+
<div class="mb-6">
|
| 48 |
+
<label class="block text-sm font-medium text-gray-700 mb-2">GitHub Token</label>
|
| 49 |
+
<input type="password" id="github-token" placeholder="أدخل رمز GitHub الشخصي الخاص بك"
|
| 50 |
+
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
| 51 |
+
<p class="text-xs text-gray-500 mt-1">يجب أن يحتوي الرمز على أذونات repo</p>
|
| 52 |
+
</div>
|
| 53 |
+
|
| 54 |
+
<button id="connect-btn" class="w-full bg-blue-600 text-white py-3 px-4 rounded-md hover:bg-blue-700 transition duration-200">
|
| 55 |
+
ربط الحسابات
|
| 56 |
</button>
|
| 57 |
</div>
|
| 58 |
|
| 59 |
+
<!-- Repositories Section -->
|
| 60 |
+
<div id="repos-section" class="bg-white rounded-lg shadow-md p-6 mb-6 hidden">
|
| 61 |
+
<h2 class="text-2xl font-bold text-gray-900 mb-4">اختر المستودع</h2>
|
| 62 |
+
<div id="repos-list" class="space-y-3">
|
| 63 |
+
<!-- Repositories will be loaded here -->
|
| 64 |
+
</div>
|
| 65 |
+
</div>
|
| 66 |
+
|
| 67 |
+
<!-- Chat Section -->
|
| 68 |
+
<div id="chat-section" class="bg-white rounded-lg shadow-md p-6 hidden">
|
| 69 |
+
<div class="flex items-center justify-between mb-6">
|
| 70 |
+
<h2 class="text-2xl font-bold text-gray-900" id="current-repo">المحادثة</h2>
|
| 71 |
+
<div class="flex space-x-2 space-x-reverse">
|
| 72 |
+
<button id="merge-btn" class="bg-green-600 text-white px-4 py-2 rounded-md hover:bg-green-700 transition duration-200 hidden">
|
| 73 |
+
دمج التغييرات
|
| 74 |
+
</button>
|
| 75 |
+
<button id="new-chat-btn" class="bg-gray-600 text-white px-4 py-2 rounded-md hover:bg-gray-700 transition duration-200">
|
| 76 |
+
محادثة جديدة
|
| 77 |
</button>
|
|
|
|
| 78 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 79 |
</div>
|
| 80 |
+
|
| 81 |
+
<div id="chat-messages" class="h-96 overflow-y-auto border border-gray-200 rounded-lg p-4 mb-4 bg-gray-50">
|
| 82 |
<!-- Chat messages will appear here -->
|
| 83 |
</div>
|
| 84 |
+
|
| 85 |
+
<div class="flex space-x-2 space-x-reverse">
|
| 86 |
+
<input type="text" id="message-input" placeholder="اكتب أمرك هنا..."
|
| 87 |
+
class="flex-1 px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500">
|
| 88 |
+
<button id="send-btn" class="bg-blue-600 text-white px-6 py-2 rounded-md hover:bg-blue-700 transition duration-200">
|
| 89 |
+
إرسال
|
| 90 |
+
</button>
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
</div>
|
| 92 |
</div>
|
| 93 |
+
|
| 94 |
+
<!-- Status Messages -->
|
| 95 |
+
<div id="status-message" class="fixed bottom-4 left-4 right-4 bg-blue-100 border border-blue-400 text-blue-700 px-4 py-3 rounded hidden"></div>
|
| 96 |
+
</main>
|
| 97 |
|
| 98 |
<script>
|
|
|
|
|
|
|
| 99 |
// State management
|
| 100 |
+
let currentState = {
|
| 101 |
+
openaiKey: '',
|
| 102 |
+
githubToken: '',
|
| 103 |
+
selectedRepo: '',
|
| 104 |
+
currentBranch: '',
|
| 105 |
+
chatHistory: []
|
| 106 |
+
};
|
| 107 |
+
|
| 108 |
+
// DOM Elements
|
| 109 |
+
const setupSection = document.getElementById('setup-section');
|
| 110 |
+
const reposSection = document.getElementById('repos-section');
|
| 111 |
+
const chatSection = document.getElementById('chat-section');
|
| 112 |
+
const reposList = document.getElementById('repos-list');
|
|
|
|
|
|
|
|
|
|
| 113 |
const chatMessages = document.getElementById('chat-messages');
|
| 114 |
+
const messageInput = document.getElementById('message-input');
|
| 115 |
+
const sendBtn = document.getElementById('send-btn');
|
| 116 |
+
const connectBtn = document.getElementById('connect-btn');
|
| 117 |
+
const mergeBtn = document.getElementById('merge-btn');
|
| 118 |
+
const newChatBtn = document.getElementById('new-chat-btn');
|
| 119 |
+
const userSection = document.getElementById('user-section');
|
| 120 |
+
const statusMessage = document.getElementById('status-message');
|
| 121 |
+
const currentRepo = document.getElementById('current-repo');
|
| 122 |
|
| 123 |
+
// Event Listeners
|
| 124 |
+
connectBtn.addEventListener('click', connectAccounts);
|
| 125 |
+
sendBtn.addEventListener('click', sendMessage);
|
| 126 |
+
mergeBtn.addEventListener('click', mergeChanges);
|
| 127 |
+
newChatBtn.addEventListener('click', startNewChat);
|
| 128 |
+
|
| 129 |
+
messageInput.addEventListener('keypress', (e) => {
|
| 130 |
+
if (e.key === 'Enter') sendMessage();
|
| 131 |
+
});
|
| 132 |
+
|
| 133 |
+
// Functions
|
| 134 |
+
function showStatus(message, type = 'info') {
|
| 135 |
+
statusMessage.textContent = message;
|
| 136 |
+
statusMessage.className = `fixed bottom-4 left-4 right-4 px-4 py-3 rounded ${type === 'error' ? 'bg-red-100 border border-red-400 text-red-700' : 'bg-blue-100 border border-blue-400 text-blue-700'}`;
|
| 137 |
+
statusMessage.classList.remove('hidden');
|
| 138 |
+
setTimeout(() => statusMessage.classList.add('hidden'), 5000);
|
| 139 |
}
|
| 140 |
|
| 141 |
+
async function connectAccounts() {
|
|
|
|
|
|
|
|
|
|
| 142 |
const openaiKey = document.getElementById('openai-key').value;
|
| 143 |
const githubToken = document.getElementById('github-token').value;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 144 |
|
| 145 |
+
if (!openaiKey || !githubToken) {
|
| 146 |
+
showStatus('يرجى ملء جميع الحقول', 'error');
|
| 147 |
+
return;
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
currentState.openaiKey = openaiKey;
|
| 151 |
+
currentState.githubToken = githubToken;
|
| 152 |
+
|
| 153 |
+
showStatus('جاري ربط الحسابات...');
|
| 154 |
|
| 155 |
try {
|
| 156 |
+
// Test GitHub connection
|
| 157 |
+
const repos = await fetchGitHubRepos(githubToken);
|
| 158 |
+
if (repos) {
|
| 159 |
+
setupSection.classList.add('hidden');
|
| 160 |
+
reposSection.classList.remove('hidden');
|
| 161 |
+
userSection.classList.remove('hidden');
|
| 162 |
+
loadRepositories(repos);
|
| 163 |
+
showStatus('تم الربط بنجاح');
|
| 164 |
+
}
|
|
|
|
|
|
|
| 165 |
} catch (error) {
|
| 166 |
+
showStatus('فشل في الربط: ' + error.message, 'error');
|
| 167 |
}
|
| 168 |
}
|
| 169 |
|
| 170 |
+
async function fetchGitHubRepos(token) {
|
| 171 |
+
const response = await fetch('https://api.github.com/user/repos', {
|
| 172 |
+
headers: {
|
| 173 |
+
'Authorization': `token ${token}`,
|
| 174 |
+
'Accept': 'application/vnd.github.v3+json'
|
| 175 |
+
}
|
| 176 |
+
});
|
| 177 |
+
|
| 178 |
+
if (!response.ok) {
|
| 179 |
+
throw new Error('فشل في جلب المستودعات');
|
| 180 |
+
}
|
| 181 |
+
|
| 182 |
+
return await response.json();
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
function loadRepositories(repos) {
|
| 186 |
+
reposList.innerHTML = '';
|
| 187 |
repos.forEach(repo => {
|
| 188 |
+
const repoElement = document.createElement('div');
|
| 189 |
+
repoElement.className = 'flex items-center justify-between p-3 border border-gray-200 rounded-lg hover:bg-gray-50 cursor-pointer';
|
| 190 |
repoElement.innerHTML = `
|
| 191 |
+
<div class="flex items-center space-x-3 space-x-reverse">
|
| 192 |
+
<i data-feather="folder" class="w-5 h-5 text-gray-500"></i>
|
| 193 |
+
<span class="font-medium">${repo.full_name}</span>
|
| 194 |
+
</div>
|
| 195 |
+
<i data-feather="chevron-left" class="w-5 h-5 text-gray-400"></i>
|
| 196 |
`;
|
| 197 |
+
repoElement.addEventListener('click', () => selectRepository(repo));
|
| 198 |
+
reposList.appendChild(repoElement);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 199 |
});
|
| 200 |
+
feather.replace();
|
| 201 |
}
|
| 202 |
|
| 203 |
+
async function selectRepository(repo) {
|
| 204 |
+
currentState.selectedRepo = repo.full_name;
|
| 205 |
+
reposSection.classList.add('hidden');
|
| 206 |
+
chatSection.classList.remove('hidden');
|
| 207 |
+
currentRepo.textContent = `المحادثة - ${repo.full_name}`;
|
| 208 |
+
|
| 209 |
+
showStatus(`تم اختيار المستودع: ${repo.full_name}`);
|
| 210 |
+
|
| 211 |
+
// Create a new branch for this session
|
| 212 |
+
const branchName = `ai-assistant-${Date.now()}`;
|
| 213 |
+
await createNewBranch(repo.full_name, branchName);
|
| 214 |
+
currentState.currentBranch = branchName;
|
| 215 |
+
mergeBtn.classList.remove('hidden');
|
| 216 |
+
|
| 217 |
+
addMessage('system', 'مرحباً! أنا مساعد الذكاء الاصطناعي. كيف يمكنني مساعدتك في هذا المستودع؟');
|
| 218 |
+
}
|
| 219 |
|
| 220 |
+
async function createNewBranch(repo, branchName) {
|
| 221 |
+
// This would need to be implemented with GitHub API
|
| 222 |
+
// For now, we'll just set the branch name
|
| 223 |
+
showStatus(`تم إنشاء فرع جديد: ${branchName}`);
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
+
function addMessage(role, content) {
|
| 227 |
const messageDiv = document.createElement('div');
|
| 228 |
+
messageDiv.className = `mb-4 p-3 rounded-lg ${role === 'user' ? 'bg-blue-100 ml-12' : 'bg-gray-100 mr-12'}`;
|
| 229 |
+
messageDiv.innerHTML = `
|
| 230 |
+
<div class="font-medium mb-1">${role === 'user' ? 'أنت' : 'المساعد'}</div>
|
| 231 |
+
<div class="text-gray-700">${content}</div>
|
| 232 |
+
`;
|
|
|
|
|
|
|
| 233 |
chatMessages.appendChild(messageDiv);
|
| 234 |
chatMessages.scrollTop = chatMessages.scrollHeight;
|
| 235 |
|
| 236 |
+
currentState.chatHistory.push({ role, content });
|
| 237 |
}
|
| 238 |
|
| 239 |
+
async function sendMessage() {
|
|
|
|
|
|
|
| 240 |
const message = messageInput.value.trim();
|
| 241 |
if (!message) return;
|
| 242 |
+
|
|
|
|
|
|
|
| 243 |
messageInput.value = '';
|
| 244 |
+
addMessage('user', message);
|
| 245 |
+
|
| 246 |
+
showStatus('جاري معالجة الطلب...');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 247 |
|
| 248 |
+
try {
|
| 249 |
+
// Simulate AI response - in real implementation, this would call OpenAI API
|
| 250 |
+
// and execute commands on the repository
|
| 251 |
+
const response = await simulateAIResponse(message);
|
| 252 |
+
addMessage('assistant', response);
|
| 253 |
+
showStatus('تم تنفيذ الأمر بنجاح');
|
| 254 |
+
} catch (error) {
|
| 255 |
+
showStatus('فشل في تنفيذ الأمر: ' + error.message, 'error');
|
| 256 |
+
addMessage('assistant', 'عذراً، حدث خطأ أثناء معالجة طلبك.');
|
| 257 |
+
}
|
| 258 |
+
}
|
| 259 |
+
|
| 260 |
+
async function simulateAIResponse(message) {
|
| 261 |
+
// Simulate API call delay
|
| 262 |
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
| 263 |
|
| 264 |
+
// Simple response simulation - in real implementation, this would:
|
| 265 |
+
// 1. Call OpenAI API with the message and repository context
|
| 266 |
+
// 2. Parse the AI response to extract git commands
|
| 267 |
+
// 3. Execute those commands on the repository via GitHub API
|
| 268 |
+
// 4. Return the results
|
| 269 |
|
| 270 |
+
const responses = [
|
| 271 |
+
'تم تنفيذ التغييرات المطلوبة على الملفات بنجاح.',
|
| 272 |
+
'لقد قمت بتعديل الكود حسب طلبك. هل تريد أي تغييرات إضافية؟',
|
| 273 |
+
'تم إضافة الوظيفة الجديدة إلى المشروع.',
|
| 274 |
+
'تم إصلاح الأخطاء التي ذكرتها في الكود.',
|
| 275 |
+
'لقد قمت بتحسين أداء الوظيفة الحالية.'
|
| 276 |
+
];
|
|
|
|
|
|
|
| 277 |
|
| 278 |
+
return responses[Math.floor(Math.random() * responses.length)];
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
async function mergeChanges() {
|
| 282 |
+
if (!currentState.selectedRepo || !currentState.currentBranch) {
|
| 283 |
+
showStatus('لا يوجد مستودع محدد', 'error');
|
| 284 |
+
return;
|
| 285 |
}
|
| 286 |
+
|
| 287 |
+
showStatus('جاري دمج التغييرات...');
|
| 288 |
|
| 289 |
+
try {
|
| 290 |
+
// Simulate merge process
|
| 291 |
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
| 292 |
+
showStatus('تم دمج التغييرات بنجاح في الفرع الرئيسي');
|
| 293 |
+
mergeBtn.classList.add('hidden');
|
| 294 |
+
} catch (error) {
|
| 295 |
+
showStatus('فشل في دمج التغييرات', 'error');
|
| 296 |
+
}
|
| 297 |
+
}
|
| 298 |
+
|
| 299 |
+
function startNewChat() {
|
| 300 |
+
chatMessages.innerHTML = '';
|
| 301 |
+
currentState.chatHistory = [];
|
| 302 |
+
addMessage('system', 'مرحباً! أنا مساعد الذكاء الاصطناعي. كيف يمكنني مساعدتك في هذا المستودع؟');
|
| 303 |
+
}
|
| 304 |
+
|
| 305 |
+
// Initialize feather icons
|
| 306 |
+
feather.replace();
|
| 307 |
</script>
|
| 308 |
</body>
|
| 309 |
+
</html>
|