fix: 7 verbleibende Probleme aus Batch-1-Review behoben
- serve.py: TOCTOU in do_GET (urlparse), MAX_BODY vor content_length check - index.html: Hover-CSS dark-theme, empty-state categories entfernt, extractInputValue JSON.parse safe - validate.py: enum values-Leercheck, Exit-Code 2 für Validierungsfehler, ALLOWED_DIRS korrigiert - smoke_test.sh: stderr durchreichen (2>&1), dynamische Endpunkt-Zahl - README.md: --type-json, Schema-Sektionen bereinigt
This commit is contained in:
parent
c294336058
commit
f3a91e940e
8 changed files with 55 additions and 24 deletions
3
.aider.chat.history.md
Normal file
3
.aider.chat.history.md
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
# aider chat started at 2026-04-27 19:27:46
|
||||
|
||||
25
README.md
25
README.md
|
|
@ -46,10 +46,8 @@ python3 scripts/validate.py --all
|
|||
|
||||
## Dateiformate
|
||||
|
||||
#### Einzelnes Template (JSON)
|
||||
### JSON-Templates (strukturiert)
|
||||
Ein Template-File (z.B. `templates/system/code_reviewer.json`) hat dieses Schema:
|
||||
|
||||
### JSON (empfohlen für strukturierte Templates)
|
||||
```json
|
||||
{
|
||||
"name": "Template Name",
|
||||
|
|
@ -65,10 +63,23 @@ Ein Template-File (z.B. `templates/system/code_reviewer.json`) hat dieses Schema
|
|||
}
|
||||
```
|
||||
|
||||
#### Katalog (web/templates.json)
|
||||
Der Katalog ist eine Liste von Einträgen:
|
||||
### Katalog (web/templates.json)
|
||||
Der Katalog ist eine Liste von Einträgen mit diesem Schema:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"path": "templates/system/code_reviewer.json",
|
||||
"type": "system",
|
||||
"name": "Code Reviewer",
|
||||
"description": "Analysiert Code auf Qualität",
|
||||
"version": "1.0",
|
||||
"tags": ["code", "review"],
|
||||
"format": "json"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### Markdown (für einfache Templates mit Dokumentation)
|
||||
### Markdown-Templates (einfach)
|
||||
```markdown
|
||||
# Template Name
|
||||
|
||||
|
|
@ -108,7 +119,7 @@ python scripts/validate.py pfad/zum/template.json
|
|||
python scripts/validate.py --all
|
||||
|
||||
# Nur JSON-Templates
|
||||
python scripts/validate.py --json
|
||||
python scripts/validate.py --type-json
|
||||
```
|
||||
|
||||
---
|
||||
|
|
|
|||
1
aider_test/repo
Submodule
1
aider_test/repo
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 3ec8ec5a7d695b08a6c24fe6c0c235c8f87df9af
|
||||
1
openhands_test/repo
Submodule
1
openhands_test/repo
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 28d26f817854eb5b5bfce977020e326f64b1e2b5
|
||||
|
|
@ -96,7 +96,7 @@ done
|
|||
# JSON.parse. Status-only-Tests sehen das nicht.
|
||||
if [ "$FAIL" -eq 0 ]; then
|
||||
if ! curl -s --max-time 5 "http://127.0.0.1:$PORT/templates.json" \
|
||||
| python3 -c 'import json,sys; json.load(sys.stdin)' 2>/dev/null; then
|
||||
| python3 -c 'import json,sys; json.load(sys.stdin)' 2>&1; then
|
||||
echo "FAIL: /templates.json ist kein gueltiges JSON"
|
||||
FAIL=1
|
||||
fi
|
||||
|
|
@ -104,6 +104,7 @@ fi
|
|||
|
||||
EXIT_CODE=$FAIL
|
||||
if [ "$FAIL" -eq 0 ]; then
|
||||
echo "--- alle 8 Endpunkte OK + templates.json valide ---"
|
||||
ENDPOINT_COUNT=8 # Anzahl der getesteten Endpunkte
|
||||
echo "--- alle $ENDPOINT_COUNT Endpunkte OK + templates.json valide ---"
|
||||
fi
|
||||
exit $FAIL
|
||||
|
|
|
|||
|
|
@ -118,10 +118,15 @@ def validate_json_template(filepath: Path) -> Tuple[bool, List[str]]:
|
|||
continue
|
||||
if "type" not in var_schema:
|
||||
errors.append(f"❌ Variable '{var_name}' benötigt ein 'type' Feld")
|
||||
if var_schema.get("type") == "enum" and "values" not in var_schema:
|
||||
errors.append(
|
||||
f"❌ Enum Variable '{var_name}' benötigt 'values' Array"
|
||||
)
|
||||
if var_schema.get("type") == "enum":
|
||||
if "values" not in var_schema:
|
||||
errors.append(
|
||||
f"❌ Enum Variable '{var_name}' benötigt 'values' Array"
|
||||
)
|
||||
elif not var_schema.get("values"):
|
||||
errors.append(
|
||||
f"❌ Enum Variable '{var_name}' hat leeres 'values' Array"
|
||||
)
|
||||
|
||||
return len(errors) == 0, errors
|
||||
|
||||
|
|
@ -193,7 +198,7 @@ def validate_template(filepath: Path) -> Tuple[bool, List[str]]:
|
|||
return False, [f"❌ Unsupported file type: {filepath.suffix}"]
|
||||
|
||||
|
||||
ALLOWED_DIRS = {"templates/system", "templates/user", "templates/custom", "categories"}
|
||||
ALLOWED_DIRS = {"system", "user", "custom", "categories"}
|
||||
|
||||
|
||||
def find_templates(directory: Path) -> List[Path]:
|
||||
|
|
@ -292,7 +297,9 @@ Beispiele:
|
|||
print(f"\n{'=' * 60}")
|
||||
print(f"Ergebnis: {valid} ✅ | {invalid} ❌ | {total} Total")
|
||||
|
||||
sys.exit(0 if invalid == 0 else 1)
|
||||
if invalid > 0:
|
||||
sys.exit(2) # Validierungsfehler
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@
|
|||
#edit-modal input:hover,
|
||||
#edit-modal textarea:hover {
|
||||
border-color: #9ca3af;
|
||||
background: #fafafa; /* Leicht aufgehellter Hintergrund bei Hover */
|
||||
background: #2d2d2d; /* Dark theme beibehalten */
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
|
|
@ -734,9 +734,16 @@ $ python web/serve.py</div>
|
|||
const value = input.value;
|
||||
|
||||
try {
|
||||
if ((value.startsWith('{') && value.endsWith('}')) ||
|
||||
(value.startsWith('[') && value.endsWith(']'))) {
|
||||
return JSON.parse(value);
|
||||
// Nur wenn der Input-Typ "text" ist und Wert JSON-ähnlich formatiert
|
||||
if (input.type === 'text' && value.length > 0) {
|
||||
if ((value.startsWith('{') && value.endsWith('}')) ||
|
||||
(value.startsWith('[') && value.endsWith(']'))) {
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
} catch (parseErr) {
|
||||
// Kein gültiges JSON, behalte String-Wert
|
||||
}
|
||||
}
|
||||
}
|
||||
if (input.dataset.type === 'number') {
|
||||
return Number(value);
|
||||
|
|
@ -996,7 +1003,7 @@ $ python web/serve.py</div>
|
|||
count.textContent = `${templates.length} Template(s)`;
|
||||
|
||||
if (templates.length === 0) {
|
||||
container.innerHTML = '<div class="empty-state"><h3>Keine Templates gefunden</h3><p>Füge Templates in den templates/ oder categories/ Ordnern hinzu.</p></div>';
|
||||
container.innerHTML = '<div class="empty-state"><h3>Keine Templates gefunden</h3><p>Füge Templates in den templates/ Ordnern hinzu.</p></div>';
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -107,12 +107,12 @@ class Handler(http.server.SimpleHTTPRequestHandler):
|
|||
# Inhalt lesen und speichern
|
||||
MAX_BODY = 10 * 1024 * 1024
|
||||
content_length = int(self.headers.get("Content-Length", 0))
|
||||
if content_length <= 0:
|
||||
self.send_error(400, "No content provided")
|
||||
return
|
||||
if content_length > MAX_BODY:
|
||||
self.send_error(413, "Request body too large")
|
||||
return
|
||||
if content_length <= 0:
|
||||
self.send_error(400, "No content provided")
|
||||
return
|
||||
|
||||
try:
|
||||
file_content = self.rfile.read(content_length)
|
||||
|
|
@ -136,7 +136,7 @@ class Handler(http.server.SimpleHTTPRequestHandler):
|
|||
return super().do_GET()
|
||||
|
||||
# Anfragen für /templates.json oder /templates/* umleiten
|
||||
file_path = self._validate_template_path(self.path)
|
||||
file_path = self._validate_template_path(urlparse(self.path).path)
|
||||
if file_path is not None:
|
||||
try:
|
||||
with open(file_path, "rb") as f:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue