diff --git a/README.md b/README.md
index b829879..70dd38e 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,9 @@
Ein kuratiertes Verzeichnis für digitale Forensik- und Incident-Response-Tools, entwickelt für die Seminargruppe CC24-w1.
+*DISCLAIMER:*
+Hier wurde Exzessives Vibe-Coding verwendet. Die Auswahl der Software ist aber kuratiert.
+
## 🎯 Projektübersicht
CC24-Hub ist eine statische Website, die eine strukturierte Übersicht über bewährte DFIR-Tools bietet. Das Projekt orientiert sich am NIST-Framework (SP 800-86) und kategorisiert Tools nach forensischen Domänen und Untersuchungsphasen.
diff --git a/src/components/AIQueryInterface.astro b/src/components/AIQueryInterface.astro
index f29a7a6..6aa81b5 100644
--- a/src/components/AIQueryInterface.astro
+++ b/src/components/AIQueryInterface.astro
@@ -1,598 +1,381 @@
---
-// src/components/AIQueryInterface.astro
import { promises as fs } from 'fs';
import { load } from 'js-yaml';
import path from 'path';
-// Load tools data for tool details
+// Load tools data for validation
const yamlPath = path.join(process.cwd(), 'src/data/tools.yaml');
const yamlContent = await fs.readFile(yamlPath, 'utf8');
const data = load(yamlContent) as any;
const tools = data.tools;
-const phases = data.phases.filter((phase: any) => phase.id !== 'collaboration-general');
---
-
-
+
+
-
-
- Beschreiben Sie Ihr Ermittlungsszenario auf Deutsch oder Englisch und erhalten Sie
- personalisierte Tool-Empfehlungen basierend auf dem NIST-Framework.
+
+ Beschreiben Sie Ihr forensisches Szenario und erhalten Sie maßgeschneiderte Tool-Empfehlungen
+ basierend auf bewährten DFIR-Workflows und der verfügbaren Software-Datenbank.
-
-
-
-
- 0/2000
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
KI analysiert Ihr Szenario...
-
Dies kann einige Sekunden dauern.
-
-
-
-
-
-
-
-
-
-
-
-
Fehler bei der Analyse
-
Ein unerwarteter Fehler ist aufgetreten.
-
-
-
-
-
-
-
-
-
-
-
-
- Szenario-Analyse
-
-
-
-
-
-
-
- Empfohlener DFIR-Workflow
-
-
-
-
- {phases.map((phase: any, index: number) => (
-
-
-
{index + 1}
-
-
{phase.name}
-
-
-
-
-
-
- {index < phases.length - 1 && (
-
-
-
-
-
-
- )}
-
- ))}
-
-
-
-
-
-
-
-
-
-
- Workflow-Empfehlung
-
-
-
-
-
-
-
+
+
+
+
-
-
+
+
- Wichtige Hinweise
-
-
+ Die Anfrage wird an mistral.ai übertragen und unterliegt deren
+ Datenschutzrichtlinien.
+ Eine typische Anfrage kostet mich $0.0008.
+
+
+
+
+
+
-
-
-
+
+
+
+
+
+
+
+
+
+
Analysiere Szenario und generiere Empfehlungen...
+
+
+
+
+
+
Fehler bei der KI-Anfrage
+
Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut.
-
-
-
-
\ No newline at end of file
diff --git a/src/pages/index.astro b/src/pages/index.astro
index 4c2a8bf..f20260f 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -156,7 +156,7 @@ const tools = data.tools;
switchToView('ai');
}
- // Function to switch between different views
+// Function to switch between different views
function switchToView(view) {
// Hide all views first (using non-null assertions since we've already checked)
toolsGrid!.style.display = 'none';
@@ -176,6 +176,43 @@ const tools = data.tools;
aiInterface!.style.display = 'block';
// Keep filters visible in AI mode for view switching
filtersSection!.style.display = 'block';
+
+ // Hide filter controls in AI mode - AGGRESSIVE APPROACH
+ const domainPhaseContainer = document.querySelector('.domain-phase-container') as HTMLElement;
+ const searchInput = document.getElementById('search-tools') as HTMLElement;
+ const tagCloud = document.querySelector('.tag-cloud') as HTMLElement;
+ // Hide all checkbox wrappers
+ const checkboxWrappers = document.querySelectorAll('.checkbox-wrapper');
+ // Hide the "Nach Tags filtern" header and button
+ const tagHeader = document.querySelector('.tag-header') as HTMLElement;
+ // Hide any elements containing "Proprietäre Software" or "Nach Tags filtern"
+ const filterLabels = document.querySelectorAll('label, .tag-header, h4, h3');
+ // Hide ALL input elements in the filters section (more aggressive)
+ const allInputs = filtersSection!.querySelectorAll('input, select, textarea');
+
+
+ if (domainPhaseContainer) domainPhaseContainer.style.display = 'none';
+ if (searchInput) searchInput.style.display = 'none';
+ if (tagCloud) tagCloud.style.display = 'none';
+ if (tagHeader) tagHeader.style.display = 'none';
+
+ // Hide ALL inputs in the filters section
+ allInputs.forEach(input => {
+ (input as HTMLElement).style.display = 'none';
+ });
+
+ checkboxWrappers.forEach(wrapper => {
+ (wrapper as HTMLElement).style.display = 'none';
+ });
+
+ // Hide specific filter section elements by text content
+ filterLabels.forEach(element => {
+ const text = element.textContent?.toLowerCase() || '';
+ if (text.includes('proprietäre') || text.includes('tags filtern') || text.includes('nach tags') || text.includes('suchen') || text.includes('search')) {
+ (element as HTMLElement).style.display = 'none';
+ }
+ });
+
// Restore previous AI results if they exist
if ((window as any).restoreAIResults) {
(window as any).restoreAIResults();
@@ -189,10 +226,72 @@ const tools = data.tools;
case 'matrix':
matrixContainer!.style.display = 'block';
filtersSection!.style.display = 'block';
+
+ // Show filter controls in matrix mode
+ const domainPhaseContainerMatrix = document.querySelector('.domain-phase-container') as HTMLElement;
+ const searchInputMatrix = document.getElementById('search-tools') as HTMLElement;
+ const tagCloudMatrix = document.querySelector('.tag-cloud') as HTMLElement;
+ const checkboxWrappersMatrix = document.querySelectorAll('.checkbox-wrapper');
+ const tagHeaderMatrix = document.querySelector('.tag-header') as HTMLElement;
+ const filterLabelsMatrix = document.querySelectorAll('label, .tag-header, h4, h3');
+ const allInputsMatrix = filtersSection!.querySelectorAll('input, select, textarea');
+
+ if (domainPhaseContainerMatrix) domainPhaseContainerMatrix.style.display = 'grid';
+ if (searchInputMatrix) searchInputMatrix.style.display = 'block';
+ if (tagCloudMatrix) tagCloudMatrix.style.display = 'flex';
+ if (tagHeaderMatrix) tagHeaderMatrix.style.display = 'flex';
+
+ // Restore ALL inputs in the filters section
+ allInputsMatrix.forEach(input => {
+ (input as HTMLElement).style.display = 'block';
+ });
+
+ checkboxWrappersMatrix.forEach(wrapper => {
+ (wrapper as HTMLElement).style.display = 'flex';
+ });
+
+ // Restore filter section elements
+ filterLabelsMatrix.forEach(element => {
+ const text = element.textContent?.toLowerCase() || '';
+ if (text.includes('proprietäre') || text.includes('tags filtern') || text.includes('nach tags') || text.includes('suchen') || text.includes('search')) {
+ (element as HTMLElement).style.display = 'block';
+ }
+ });
break;
default: // grid
toolsGrid!.style.display = 'block';
filtersSection!.style.display = 'block';
+
+ // Show filter controls in grid mode
+ const domainPhaseContainerGrid = document.querySelector('.domain-phase-container') as HTMLElement;
+ const searchInputGrid = document.getElementById('search-tools') as HTMLElement;
+ const tagCloudGrid = document.querySelector('.tag-cloud') as HTMLElement;
+ const checkboxWrappersGrid = document.querySelectorAll('.checkbox-wrapper');
+ const tagHeaderGrid = document.querySelector('.tag-header') as HTMLElement;
+ const filterLabelsGrid = document.querySelectorAll('label, .tag-header, h4, h3');
+ const allInputsGrid = filtersSection!.querySelectorAll('input, select, textarea');
+
+ if (domainPhaseContainerGrid) domainPhaseContainerGrid.style.display = 'grid';
+ if (searchInputGrid) searchInputGrid.style.display = 'block';
+ if (tagCloudGrid) tagCloudGrid.style.display = 'flex';
+ if (tagHeaderGrid) tagHeaderGrid.style.display = 'flex';
+
+ // Restore ALL inputs in the filters section
+ allInputsGrid.forEach(input => {
+ (input as HTMLElement).style.display = 'block';
+ });
+
+ checkboxWrappersGrid.forEach(wrapper => {
+ (wrapper as HTMLElement).style.display = 'flex';
+ });
+
+ // Restore filter section elements
+ filterLabelsGrid.forEach(element => {
+ const text = element.textContent?.toLowerCase() || '';
+ if (text.includes('proprietäre') || text.includes('tags filtern') || text.includes('nach tags') || text.includes('suchen') || text.includes('search')) {
+ (element as HTMLElement).style.display = 'block';
+ }
+ });
break;
}