/**
* THOR Advanced Capabilities JavaScript
* Handles all interactions with THOR's advanced features
*/
document.addEventListener('DOMContentLoaded', function() {
// Initialize tooltips
const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
tooltipTriggerList.map(function (tooltipTriggerEl) {
return new bootstrap.Tooltip(tooltipTriggerEl);
});
// ====== Code Generation ======
const generateCodeBtn = document.getElementById('generateCodeBtn');
const codeDescription = document.getElementById('codeDescription');
const codeLanguage = document.getElementById('codeLanguage');
const generatedCode = document.getElementById('generatedCode');
const copyCodeBtn = document.getElementById('copyCodeBtn');
const saveCodeBtn = document.getElementById('saveCodeBtn');
if (generateCodeBtn) {
generateCodeBtn.addEventListener('click', function() {
if (!codeDescription.value.trim()) {
alert('Please provide a description of the code you want to generate.');
return;
}
// Show loading state
generatedCode.textContent = 'Generating code...';
generateCodeBtn.disabled = true;
saveCodeBtn.disabled = true;
// Make API request to generate code
fetch('/api/thor/generate-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
description: codeDescription.value,
language: codeLanguage.value
})
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
generatedCode.textContent = data.code;
saveCodeBtn.disabled = false;
} else {
generatedCode.textContent = `Error: ${data.message || 'Failed to generate code'}`;
}
})
.catch(error => {
console.error('Error generating code:', error);
generatedCode.textContent = `Error: ${error.message || 'An unexpected error occurred'}`;
})
.finally(() => {
generateCodeBtn.disabled = false;
});
});
}
if (copyCodeBtn) {
copyCodeBtn.addEventListener('click', function() {
navigator.clipboard.writeText(generatedCode.textContent)
.then(() => {
const originalTitle = copyCodeBtn.getAttribute('data-bs-original-title');
copyCodeBtn.setAttribute('data-bs-original-title', 'Copied!');
const tooltip = bootstrap.Tooltip.getInstance(copyCodeBtn);
if (tooltip) {
tooltip.show();
setTimeout(() => {
copyCodeBtn.setAttribute('data-bs-original-title', originalTitle);
tooltip.hide();
}, 1000);
}
})
.catch(error => {
console.error('Failed to copy:', error);
alert('Failed to copy code to clipboard');
});
});
}
// ====== Code Analysis ======
const analyzeCodeBtn = document.getElementById('analyzeCodeBtn');
const codeToAnalyze = document.getElementById('codeToAnalyze');
const issuesList = document.getElementById('issuesList');
const improvementsList = document.getElementById('improvementsList');
const analysisSummary = document.getElementById('analysisSummary');
const exportAnalysisBtn = document.getElementById('exportAnalysisBtn');
if (analyzeCodeBtn) {
analyzeCodeBtn.addEventListener('click', function() {
if (!codeToAnalyze.value.trim()) {
alert('Please paste code to analyze.');
return;
}
// Show loading state
issuesList.innerHTML = '
Analyzing code...';
improvementsList.innerHTML = 'Analyzing code...';
analysisSummary.textContent = 'Analyzing code...';
analyzeCodeBtn.disabled = true;
exportAnalysisBtn.disabled = true;
// Make API request to analyze code
fetch('/api/thor/analyze-code', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
code: codeToAnalyze.value
})
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
// Display the analysis results
displayAnalysisResults(data.analysis);
exportAnalysisBtn.disabled = false;
} else {
issuesList.innerHTML = `Error: ${data.message || 'Failed to analyze code'}`;
improvementsList.innerHTML = `Error: ${data.message || 'Failed to analyze code'}`;
analysisSummary.textContent = `Error: ${data.message || 'Failed to analyze code'}`;
}
})
.catch(error => {
console.error('Error analyzing code:', error);
issuesList.innerHTML = `Error: ${error.message || 'An unexpected error occurred'}`;
improvementsList.innerHTML = `Error: ${error.message || 'An unexpected error occurred'}`;
analysisSummary.textContent = `Error: ${error.message || 'An unexpected error occurred'}`;
})
.finally(() => {
analyzeCodeBtn.disabled = false;
});
});
}
function displayAnalysisResults(analysis) {
// Reset content
issuesList.innerHTML = '';
improvementsList.innerHTML = '';
// If analysis result is a string, handle it differently
if (typeof analysis === 'string') {
analysisSummary.textContent = analysis;
issuesList.innerHTML = 'No specific issues identified.';
improvementsList.innerHTML = 'No specific improvements suggested.';
return;
}
// Parse and display issues
if (analysis.issues && analysis.issues.length > 0) {
analysis.issues.forEach(issue => {
const severityClass = getSeverityClass(issue.severity);
issuesList.innerHTML += `
${issue.severity || 'Info'}
${issue.title || 'Issue'}
${issue.description || ''}
${issue.line ? `Line: ${issue.line}` : ''}
`;
});
} else {
issuesList.innerHTML = 'No issues found.';
}
// Parse and display improvements
if (analysis.improvements && analysis.improvements.length > 0) {
analysis.improvements.forEach(improvement => {
improvementsList.innerHTML += `
${improvement.title || 'Improvement'}
${improvement.description || ''}
${improvement.example ? `${improvement.example}` : ''}
`;
});
} else {
improvementsList.innerHTML = 'No specific improvements suggested.';
}
// Display summary
analysisSummary.textContent = analysis.summary || 'No summary provided.';
}
function getSeverityClass(severity) {
switch (severity?.toLowerCase()) {
case 'critical':
return 'bg-danger';
case 'high':
return 'bg-warning text-dark';
case 'medium':
return 'bg-info text-dark';
case 'low':
return 'bg-success';
default:
return 'bg-secondary';
}
}
// ====== Dataset Creation ======
const generateDatasetBtn = document.getElementById('generateDatasetBtn');
const datasetDescription = document.getElementById('datasetDescription');
const datasetFormat = document.getElementById('datasetFormat');
const datasetSize = document.getElementById('datasetSize');
const generatedDataset = document.getElementById('generatedDataset');
const copyDatasetBtn = document.getElementById('copyDatasetBtn');
const downloadDatasetBtn = document.getElementById('downloadDatasetBtn');
if (generateDatasetBtn) {
generateDatasetBtn.addEventListener('click', function() {
if (!datasetDescription.value.trim()) {
alert('Please provide a description of the dataset you want to create.');
return;
}
// Show loading state
generatedDataset.textContent = 'Generating dataset...';
generateDatasetBtn.disabled = true;
downloadDatasetBtn.disabled = true;
// Make API request to generate dataset
fetch('/api/thor/create-dataset', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
description: datasetDescription.value,
format: datasetFormat.value,
size: parseInt(datasetSize.value)
})
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
// Format the dataset for display
let displayData = data.dataset;
if (typeof displayData === 'object') {
displayData = JSON.stringify(displayData, null, 2);
}
generatedDataset.textContent = displayData;
downloadDatasetBtn.disabled = false;
} else {
generatedDataset.textContent = `Error: ${data.message || 'Failed to generate dataset'}`;
}
})
.catch(error => {
console.error('Error generating dataset:', error);
generatedDataset.textContent = `Error: ${error.message || 'An unexpected error occurred'}`;
})
.finally(() => {
generateDatasetBtn.disabled = false;
});
});
}
if (copyDatasetBtn) {
copyDatasetBtn.addEventListener('click', function() {
navigator.clipboard.writeText(generatedDataset.textContent)
.then(() => {
const originalTitle = copyDatasetBtn.getAttribute('data-bs-original-title');
copyDatasetBtn.setAttribute('data-bs-original-title', 'Copied!');
const tooltip = bootstrap.Tooltip.getInstance(copyDatasetBtn);
if (tooltip) {
tooltip.show();
setTimeout(() => {
copyDatasetBtn.setAttribute('data-bs-original-title', originalTitle);
tooltip.hide();
}, 1000);
}
})
.catch(error => {
console.error('Failed to copy:', error);
alert('Failed to copy dataset to clipboard');
});
});
}
if (downloadDatasetBtn) {
downloadDatasetBtn.addEventListener('click', function() {
const dataStr = generatedDataset.textContent;
const dataBlob = new Blob([dataStr], { type: 'text/plain' });
const url = URL.createObjectURL(dataBlob);
const a = document.createElement('a');
a.style.display = 'none';
a.href = url;
a.download = `dataset.${datasetFormat.value}`;
document.body.appendChild(a);
a.click();
// Cleanup
window.URL.revokeObjectURL(url);
document.body.removeChild(a);
});
}
// ====== Network Scan ======
const generateNetworkScanBtn = document.getElementById('generateNetworkScanBtn');
const networkDescription = document.getElementById('networkDescription');
const networkScript = document.getElementById('networkScript');
const scriptExplanation = document.getElementById('scriptExplanation');
const copyNetworkScriptBtn = document.getElementById('copyNetworkScriptBtn');
const saveNetworkScriptBtn = document.getElementById('saveNetworkScriptBtn');
if (generateNetworkScanBtn) {
generateNetworkScanBtn.addEventListener('click', function() {
if (!networkDescription.value.trim()) {
alert('Please provide a description of the network task.');
return;
}
// Show loading state
networkScript.textContent = 'Generating script...';
scriptExplanation.innerHTML = 'Generating explanation...
';
generateNetworkScanBtn.disabled = true;
saveNetworkScriptBtn.disabled = true;
// Make API request to generate network scan script
fetch('/api/thor/network-scan', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
target_description: networkDescription.value
})
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
networkScript.textContent = data.result.script || 'No script generated.';
scriptExplanation.innerHTML = `${data.result.explanation || 'No explanation provided.'}
`;
saveNetworkScriptBtn.disabled = false;
} else {
networkScript.textContent = `Error: ${data.message || 'Failed to generate network scan script'}`;
scriptExplanation.innerHTML = `Error: ${data.message || 'Failed to generate explanation'}
`;
}
})
.catch(error => {
console.error('Error generating network scan:', error);
networkScript.textContent = `Error: ${error.message || 'An unexpected error occurred'}`;
scriptExplanation.innerHTML = `Error: ${error.message || 'An unexpected error occurred'}
`;
})
.finally(() => {
generateNetworkScanBtn.disabled = false;
});
});
}
if (copyNetworkScriptBtn) {
copyNetworkScriptBtn.addEventListener('click', function() {
navigator.clipboard.writeText(networkScript.textContent)
.then(() => {
const originalTitle = copyNetworkScriptBtn.getAttribute('data-bs-original-title');
copyNetworkScriptBtn.setAttribute('data-bs-original-title', 'Copied!');
const tooltip = bootstrap.Tooltip.getInstance(copyNetworkScriptBtn);
if (tooltip) {
tooltip.show();
setTimeout(() => {
copyNetworkScriptBtn.setAttribute('data-bs-original-title', originalTitle);
tooltip.hide();
}, 1000);
}
})
.catch(error => {
console.error('Failed to copy:', error);
alert('Failed to copy script to clipboard');
});
});
}
// ====== Clone Manager ======
const refreshClonesBtn = document.getElementById('refreshClonesBtn');
const clonesTableBody = document.getElementById('clonesTableBody');
const deactivateAllClonesBtn = document.getElementById('deactivateAllClonesBtn');
const createCloneForm = document.getElementById('createCloneForm');
const cloneDescription = document.getElementById('cloneDescription');
const createCloneResult = document.getElementById('createCloneResult');
const updateCloneForm = document.getElementById('updateCloneForm');
const cloneToUpdate = document.getElementById('cloneToUpdate');
const updateDescription = document.getElementById('updateDescription');
const updateCapabilities = document.getElementById('updateCapabilities');
const updateCloneResult = document.getElementById('updateCloneResult');
// Load clone list when the modal is shown
const cloneManagerModal = document.getElementById('cloneManagerModal');
if (cloneManagerModal) {
cloneManagerModal.addEventListener('shown.bs.modal', function() {
loadCloneList();
});
}
// Refresh clones button
if (refreshClonesBtn) {
refreshClonesBtn.addEventListener('click', function() {
loadCloneList();
});
}
// Deactivate all clones button
if (deactivateAllClonesBtn) {
deactivateAllClonesBtn.addEventListener('click', function() {
if (confirm('Are you sure you want to deactivate all THOR clones?')) {
deactivateAllClonesBtn.disabled = true;
deactivateAllClonesBtn.innerHTML = 'Deactivating...';
fetch('/api/thor/deactivate-clones', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
showAlert('All clones deactivated successfully', 'success');
loadCloneList();
} else {
showAlert(`Error: ${data.message || 'Failed to deactivate clones'}`, 'danger');
}
})
.catch(error => {
console.error('Error deactivating clones:', error);
showAlert(`Error: ${error.message || 'An unexpected error occurred'}`, 'danger');
})
.finally(() => {
deactivateAllClonesBtn.disabled = false;
deactivateAllClonesBtn.innerHTML = 'Deactivate All Clones';
});
}
});
}
// Create clone form
if (createCloneForm) {
createCloneForm.addEventListener('submit', function(event) {
event.preventDefault();
if (!cloneDescription.value.trim()) {
alert('Please provide a description for the clone.');
return;
}
const submitBtn = createCloneForm.querySelector('button[type="submit"]');
submitBtn.disabled = true;
submitBtn.innerHTML = 'Creating...';
createCloneResult.innerHTML = 'Creating clone...
';
fetch('/api/thor/create-clone', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
description: cloneDescription.value
})
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
createCloneResult.innerHTML = `
Success! Clone "${data.clone.name}" created successfully.
`;
cloneDescription.value = '';
// Update clone list and select the new clone
loadCloneList().then(() => {
// Switch to the clones tab
const clonesTab = document.getElementById('cloneList-tab');
if (clonesTab) {
const tab = new bootstrap.Tab(clonesTab);
tab.show();
}
});
} else {
createCloneResult.innerHTML = `
Error! ${data.message || 'Failed to create clone'}
`;
}
})
.catch(error => {
console.error('Error creating clone:', error);
createCloneResult.innerHTML = `
Error! ${error.message || 'An unexpected error occurred'}
`;
})
.finally(() => {
submitBtn.disabled = false;
submitBtn.innerHTML = 'Create THOR Clone';
});
});
}
// Update clone form
if (updateCloneForm) {
updateCloneForm.addEventListener('submit', function(event) {
event.preventDefault();
if (!cloneToUpdate.value) {
alert('Please select a clone to update.');
return;
}
let capabilitiesObj = {};
if (updateCapabilities.value.trim()) {
try {
capabilitiesObj = JSON.parse(updateCapabilities.value);
} catch (e) {
alert('Invalid JSON in capabilities field. Please check the format and try again.');
return;
}
}
const submitBtn = updateCloneForm.querySelector('button[type="submit"]');
submitBtn.disabled = true;
submitBtn.innerHTML = 'Updating...';
updateCloneResult.innerHTML = 'Updating clone...
';
const updates = {
description: updateDescription.value.trim() || undefined,
capabilities: Object.keys(capabilitiesObj).length > 0 ? capabilitiesObj : undefined
};
fetch('/api/thor/update-clone', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
clone_name: cloneToUpdate.value,
updates: updates
})
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
updateCloneResult.innerHTML = `
Success! Clone "${cloneToUpdate.value}" updated successfully.
`;
// Update clone list
loadCloneList().then(() => {
// Switch to the clones tab
const clonesTab = document.getElementById('cloneList-tab');
if (clonesTab) {
const tab = new bootstrap.Tab(clonesTab);
tab.show();
}
});
} else {
updateCloneResult.innerHTML = `
Error! ${data.message || 'Failed to update clone'}
`;
}
})
.catch(error => {
console.error('Error updating clone:', error);
updateCloneResult.innerHTML = `
Error! ${error.message || 'An unexpected error occurred'}
`;
})
.finally(() => {
submitBtn.disabled = false;
submitBtn.innerHTML = 'Update Clone';
});
});
}
function loadCloneList() {
if (!clonesTableBody) return Promise.resolve();
clonesTableBody.innerHTML = '| Loading clones... |
';
return fetch('/api/thor/list-clones')
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
if (data.clones && data.clones.length > 0) {
clonesTableBody.innerHTML = '';
// Populate the table
data.clones.forEach(clone => {
const createdDate = new Date(clone.created_at).toLocaleString();
const statusBadge = clone.is_active
? 'Active'
: 'Inactive';
clonesTableBody.innerHTML += `
| ${clone.name} |
${clone.description || 'No description'} |
${clone.base_version || 'Unknown'} |
${createdDate} |
${statusBadge} |
${!clone.is_active ?
`` :
``
}
|
`;
});
// Add event listeners for the activate buttons
document.querySelectorAll('.activate-clone-btn').forEach(btn => {
btn.addEventListener('click', function() {
const cloneName = this.getAttribute('data-clone');
activateClone(cloneName, this);
});
});
// Update the select for updating clones
if (cloneToUpdate) {
const currentValue = cloneToUpdate.value;
cloneToUpdate.innerHTML = '';
data.clones.forEach(clone => {
const option = document.createElement('option');
option.value = clone.name;
option.textContent = `${clone.name} (${clone.is_active ? 'Active' : 'Inactive'})`;
cloneToUpdate.appendChild(option);
});
// Restore selection if possible
if (currentValue && Array.from(cloneToUpdate.options).some(opt => opt.value === currentValue)) {
cloneToUpdate.value = currentValue;
}
}
} else {
clonesTableBody.innerHTML = '| No clones found. Create your first THOR clone! |
';
if (cloneToUpdate) {
cloneToUpdate.innerHTML = '';
}
}
} else {
clonesTableBody.innerHTML = `| Error: ${data.message || 'Failed to load clones'} |
`;
}
})
.catch(error => {
console.error('Error loading clones:', error);
clonesTableBody.innerHTML = `| Error: ${error.message || 'An unexpected error occurred'} |
`;
return Promise.reject(error);
});
}
function activateClone(cloneName, buttonElement) {
if (!cloneName) return;
buttonElement.disabled = true;
buttonElement.innerHTML = '';
fetch('/api/thor/activate-clone', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
clone_name: cloneName
})
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
showAlert(`Clone "${cloneName}" activated successfully`, 'success');
loadCloneList();
} else {
showAlert(`Error: ${data.message || 'Failed to activate clone'}`, 'danger');
buttonElement.disabled = false;
buttonElement.innerHTML = ' Activate';
}
})
.catch(error => {
console.error('Error activating clone:', error);
showAlert(`Error: ${error.message || 'An unexpected error occurred'}`, 'danger');
buttonElement.disabled = false;
buttonElement.innerHTML = ' Activate';
});
}
// ====== Self-Improvement ======
const requestImprovementsBtn = document.getElementById('requestImprovementsBtn');
const improvementSuggestions = document.getElementById('improvementSuggestions');
const implementImprovementsBtn = document.getElementById('implementImprovementsBtn');
if (requestImprovementsBtn) {
requestImprovementsBtn.addEventListener('click', function() {
// Show loading state
improvementSuggestions.innerHTML = `
Loading...
THOR is analyzing systems and generating improvement suggestions...
`;
requestImprovementsBtn.disabled = true;
implementImprovementsBtn.disabled = true;
// Make API request for improvement suggestions
fetch('/api/thor/suggest-improvements', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
})
.then(response => response.json())
.then(data => {
if (data.status === 'success') {
displayImprovementSuggestions(data.suggestions);
implementImprovementsBtn.disabled = false;
} else {
improvementSuggestions.innerHTML = `
Error: ${data.message || 'Failed to generate improvement suggestions'}
`;
}
})
.catch(error => {
console.error('Error requesting improvements:', error);
improvementSuggestions.innerHTML = `
Error: ${error.message || 'An unexpected error occurred'}
`;
})
.finally(() => {
requestImprovementsBtn.disabled = false;
});
});
}
function displayImprovementSuggestions(suggestions) {
if (!improvementSuggestions) return;
if (!suggestions || (Array.isArray(suggestions) && suggestions.length === 0)) {
improvementSuggestions.innerHTML = `
No improvement suggestions at this time. THOR systems are running optimally.
`;
return;
}
// If suggestions is a string, display it directly
if (typeof suggestions === 'string') {
improvementSuggestions.innerHTML = `${suggestions}
`;
return;
}
// If it's an object with a text property
if (suggestions.text) {
improvementSuggestions.innerHTML = `${suggestions.text}
`;
return;
}
// Otherwise, assume it's an array of suggestion objects
let html = '';
suggestions.forEach((suggestion, index) => {
const title = suggestion.title || `Improvement ${index + 1}`;
const description = suggestion.description || suggestion.text || 'No description provided';
const priority = suggestion.priority || 'medium';
const priorityBadge = getPriorityBadge(priority);
html += `
${title}
${priorityBadge}
${description}
${suggestion.implementation ? `
Implementation:
${suggestion.implementation}
` : ''}
`;
});
html += '
';
improvementSuggestions.innerHTML = html;
}
function getPriorityBadge(priority) {
switch (priority.toLowerCase()) {
case 'critical':
return 'Critical';
case 'high':
return 'High';
case 'medium':
return 'Medium';
case 'low':
return 'Low';
default:
return 'Normal';
}
}
// ====== Helper Functions ======
function showAlert(message, type = 'info') {
// Create alert container if it doesn't exist
let alertContainer = document.getElementById('thor-alert-container');
if (!alertContainer) {
alertContainer = document.createElement('div');
alertContainer.id = 'thor-alert-container';
alertContainer.style.position = 'fixed';
alertContainer.style.top = '20px';
alertContainer.style.right = '20px';
alertContainer.style.zIndex = '9999';
document.body.appendChild(alertContainer);
}
// Create alert
const alertId = 'thor-alert-' + Date.now();
const alertElement = document.createElement('div');
alertElement.className = `alert alert-${type} alert-dismissible fade show`;
alertElement.id = alertId;
alertElement.innerHTML = `
${message}
`;
// Add alert to container
alertContainer.appendChild(alertElement);
// Auto-dismiss after 5 seconds
setTimeout(() => {
const alert = document.getElementById(alertId);
if (alert) {
const bsAlert = new bootstrap.Alert(alert);
bsAlert.close();
}
}, 5000);
}
});