104 lines
3.0 KiB
YAML
104 lines
3.0 KiB
YAML
# puml-validator - Validates and fixes PlantUML syntax
|
|
# Usage: cat diagram.puml | puml-validator
|
|
# Returns: valid PlantUML (original if valid, fixed if correctable, error if unfixable)
|
|
|
|
name: puml-validator
|
|
description: Validates PlantUML syntax and fixes errors if possible
|
|
category: Utility
|
|
|
|
steps:
|
|
# Step 1: Write input to temp file and validate
|
|
- type: code
|
|
code: |
|
|
import subprocess
|
|
import tempfile
|
|
import os
|
|
|
|
# Write to temp file
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.puml', delete=False) as f:
|
|
f.write(input)
|
|
temp_path = f.name
|
|
|
|
# Try to validate with plantuml
|
|
try:
|
|
result = subprocess.run(
|
|
['plantuml', '-syntax', temp_path],
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=30
|
|
)
|
|
output = result.stdout + result.stderr
|
|
is_valid = ('SYNTAX ERROR' not in output.upper()
|
|
and 'ERROR' not in output.upper()
|
|
and 'NO DIAGRAM FOUND' not in output.upper())
|
|
error_msg = output.strip() if not is_valid else ""
|
|
except FileNotFoundError:
|
|
# plantuml not installed, skip validation
|
|
is_valid = True
|
|
error_msg = ""
|
|
except Exception as e:
|
|
is_valid = False
|
|
error_msg = str(e)
|
|
finally:
|
|
os.unlink(temp_path)
|
|
|
|
needs_fix = "true" if not is_valid else "false"
|
|
output_var: needs_fix, error_msg
|
|
|
|
# Step 2: If valid, just return original
|
|
- type: code
|
|
code: |
|
|
if needs_fix == "false":
|
|
final_output = input
|
|
done = "true"
|
|
else:
|
|
done = "false"
|
|
final_output = ""
|
|
output_var: done, final_output
|
|
|
|
# Step 3: If invalid, try to fix with AI
|
|
- type: prompt
|
|
prompt: |
|
|
Fix this PlantUML diagram. It has syntax errors.
|
|
|
|
Error message: {error_msg}
|
|
|
|
Original diagram:
|
|
```
|
|
{input}
|
|
```
|
|
|
|
Common issues:
|
|
- Mermaid syntax mixed with PlantUML (use PlantUML only)
|
|
- Missing @startuml/@enduml
|
|
- Invalid arrow syntax (use --> not ->)
|
|
- Unclosed notes or rectangles
|
|
|
|
Return ONLY the fixed PlantUML code, nothing else. Start with @startuml and end with @enduml.
|
|
If the diagram is unfixable, respond with: ERROR: [reason]
|
|
provider: claude-haiku
|
|
output_var: fixed_output
|
|
skip_if: done == "true"
|
|
|
|
# Step 4: Check if fix succeeded or returned error
|
|
- type: code
|
|
code: |
|
|
if done == "true":
|
|
result = final_output
|
|
success = "true"
|
|
elif fixed_output.strip().startswith("ERROR:"):
|
|
result = fixed_output
|
|
success = "false"
|
|
else:
|
|
result = fixed_output.strip()
|
|
# Remove any markdown code blocks if present
|
|
if result.startswith("```"):
|
|
import re
|
|
match = re.search(r'```(?:puml|plantuml)?\s*(.*?)```', result, re.DOTALL)
|
|
if match:
|
|
result = match.group(1).strip()
|
|
success = "true"
|
|
output_var: result, success
|
|
|
|
output: "{result}"
|