artifact-editor/smarttools/artifact-ai/config.yaml

166 lines
5.8 KiB
YAML

# artifact-ai - Generate or modify artifacts using AI
# Usage: cat diagram.puml | artifact-ai --format plantuml --instruction "Add a cache layer"
# Usage: echo "" | artifact-ai --format mermaid --instruction "Create a flowchart for login"
name: artifact-ai
description: Generate or modify artifacts (diagrams, 3D models, code) using AI
category: Artifact
arguments:
- flag: --format
variable: format
required: true
description: "Artifact format: plantuml, mermaid, openscad, svg, excalidraw, code"
- flag: --instruction
variable: instruction
required: true
description: Natural language instruction for generating or modifying the artifact
steps:
# Step 1: Build format-specific prompt and call AI
- type: code
output_var: prompt
code: |
import json
format_prompts = {
'plantuml': """You are a PlantUML expert. Create or modify PlantUML diagrams.
Supported diagram types:
- Sequence diagrams: actor, participant, ->, -->
- Class diagrams: class, interface, extends, implements
- Activity diagrams: start, stop, :action;, if/then/else
- Component diagrams: component, package, [interface]
- State diagrams: state, [*], -->
Always wrap with @startuml/@enduml.""",
'mermaid': """You are a Mermaid diagram expert. Create or modify Mermaid diagrams.
Supported diagram types:
- Flowcharts: graph TD/LR, A-->B
- Sequence: sequenceDiagram, Alice->>Bob
- Class: classDiagram, class ClassName
- State: stateDiagram-v2
- Entity Relationship: erDiagram
- Gantt: gantt, section, task
Start with the diagram type declaration (graph TD, sequenceDiagram, etc.).""",
'openscad': """You are an OpenSCAD 3D modeling expert. Create or modify parametric 3D models.
Core operations:
- Primitives: cube(), sphere(), cylinder(), polyhedron()
- Transformations: translate(), rotate(), scale(), mirror()
- Boolean: union(), difference(), intersection()
- 2D: circle(), square(), polygon(), linear_extrude(), rotate_extrude()
Use modules for reusable components. Use $fn for smoothness.""",
'svg': """You are an SVG expert. Create or modify vector graphics.
Core elements:
- Shapes: <rect>, <circle>, <ellipse>, <line>, <polyline>, <polygon>, <path>
- Text: <text>, <tspan>
- Groups: <g>, <defs>, <use>, <symbol>
- Styling: fill, stroke, stroke-width, opacity, transform
Include xmlns and viewBox. Use descriptive IDs.""",
'excalidraw': """You are an Excalidraw expert. Create hand-drawn style diagrams as JSON.
Structure:
- type: element type (rectangle, diamond, ellipse, arrow, line, text)
- x, y: position
- width, height: dimensions
- strokeColor, backgroundColor, fillStyle
- roughness: 0-2 (0=smooth, 2=sketchy)
Output valid JSON with "type": "excalidraw" and "elements" array.""",
'code': """You are a programming expert. Create or modify code in any language.
Focus on:
- Clean, readable code
- Proper language conventions
- Comments for complex logic only
- Error handling where appropriate
Detect the language from context or instruction."""
}
format_outputs = {
'plantuml': "Output ONLY valid PlantUML code starting with @startuml and ending with @enduml.",
'mermaid': "Output ONLY valid Mermaid code starting with the diagram type.",
'openscad': "Output ONLY valid OpenSCAD code with proper syntax.",
'svg': "Output ONLY valid SVG code starting with <?xml or <svg and ending with </svg>.",
'excalidraw': 'Output ONLY valid Excalidraw JSON starting with { and ending with }.',
'code': "Output ONLY the code, no markdown fences or explanations."
}
current_code = input.strip() if input.strip() else "(empty - create from scratch)"
format_guide = format_prompts.get(format, f"You are a {format} expert.")
output_instruction = format_outputs.get(format, "Output ONLY the code, no explanations.")
prompt = f"""{format_guide}
CRITICAL: {output_instruction}
Current code:
---
{current_code}
---
User request: {instruction}
{output_instruction}"""
# Don't print - just set the variable
result = prompt
- type: prompt
prompt: "{prompt}"
provider: claude
output_var: ai_output
# Step 2: Clean up output based on format
- type: code
output_var: result
code: |
import re
code = ai_output.strip()
# Remove markdown code blocks if present (three backticks)
fence_pattern = r'`{3}(?:\w+)?\n(.*?)`{3}'
match = re.search(fence_pattern, code, re.DOTALL)
if match:
code = match.group(1).strip()
# Format-specific cleanup
if format == 'svg':
# Remove any wrapper formats
code = re.sub(r'^@startuml\s*\n?', '', code)
code = re.sub(r'\n?@enduml\s*$', '', code)
# Find SVG content
svg_match = re.search(r'(<\?xml[^?]*\?>)?\s*(<svg[\s\S]*?</svg>)', code)
if svg_match:
xml_decl = svg_match.group(1) or ''
svg_content = svg_match.group(2)
code = (xml_decl + '\n' + svg_content).strip() if xml_decl else svg_content
elif format == 'excalidraw':
# Find JSON object
json_match = re.search(r'\{[\s\S]*\}', code)
if json_match:
code = json_match.group(0)
elif format == 'plantuml':
# Ensure proper tags
if not code.strip().startswith('@start'):
code = '@startuml\n' + code
if not code.strip().endswith('@enduml') and '@enduml' not in code:
code = code + '\n@enduml'
print(code.strip())