meshing-guidelines/SKILL.md
Mesh gradient library for SwiftUI. Use for creating, animating, and exporting mesh gradients. Supports 2x2, 3x3, and 4x4 grid templates, animated gradients, Metal shaders, and platform-specific export to photo library or disk.
npx skillsauth add rryam/meshingkit meshing-guidelinesInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
MeshingKit is a Swift package for creating mesh gradients in SwiftUI. It provides 68 predefined gradient templates, animated gradients, Metal shader noise effects, and platform-specific export functionality.
# Swift Package Manager build
swift build
# Build for a specific target
swift build --target MeshingKit
# Xcode build for iOS Simulator
xcodebuild build -project Sources/Meshin/Meshin.xcodeproj -scheme Meshin -destination "generic/platform=iOS Simulator"
# Run tests with verbose output
swift test --verbose
# Run tests with code coverage
swift test --enable-code-coverage
# Run SwiftLint with strict mode
swiftlint --strict
# Pre-commit hook runs on staged files
# Setup: scripts/setup-hooks.sh
MeshingKit.swift exposes static methods for creating gradients:
// Create a static mesh gradient
MeshingKit.gradient(template: myTemplate)
// Create an animated mesh gradient view
MeshingKit.animatedGradient(template: myTemplate)
// Create with custom animation pattern
MeshingKit.animatedGradient(template: template, animationPattern: .fluid)
GradientTemplate Protocol:
public protocol GradientTemplate: Sendable {
var size: Int { get }
var points: [SIMD2<Float>] { get }
var colors: [Color] { get }
var background: Color { get }
}
Custom Template Example:
struct MyGradient: GradientTemplate {
var size: Int { 3 }
var points: [SIMD2<Float>] {
[
SIMD2(0, 0), SIMD2(0.5, 0), SIMD2(1, 0),
SIMD2(0, 0.5), SIMD2(0.5, 0.5), SIMD2(1, 0.5),
SIMD2(0, 1), SIMD2(0.5, 1), SIMD2(1, 1)
]
}
var colors: [Color] {
[.red, .green, .blue, .yellow, .purple, .orange, .pink, .cyan, .mint]
}
var background: Color { .black }
}
PredefinedTemplate Enum:
// All 68 templates
let allTemplates = PredefinedTemplate.allCases
// Search by name (uses NaturalLanguage)
let sunsetTemplates = PredefinedTemplate.find(by: "sunset")
// Access base template
let base = PredefinedTemplate.aurora.baseTemplate
Templates are organized by grid size:
GradientTemplateSize2 - 2x2 grids (4 points)GradientTemplateSize3 - 3x3 grids (9 points)GradientTemplateSize4 - 4x4 grids (16 points)AnimatedMeshGradientView: SwiftUI view for animated gradients with configurable speed.
ParameterizedNoiseView: Metal shader-based noise effect for textures and visual effects.
PredefinedTemplate.find(by: token) uses:
public enum ExportFormat: String, CaseIterable, Identifiable, Sendable {
case png, jpg, mp4
public var id: Self { self }
public var fileExtension: String { rawValue }
}
public enum VideoExportError: Error, Sendable {
case frameRenderingFailed
case failedToStartWriting
case pixelBufferPoolCreationFailed
case pixelBufferCreationFailed
case failedToAppendPixelBuffer
case failedToAddInput
case failedToCreateOutputURL
case fileNotAccessible
case unsupportedFormat
case photosPermissionDenied
}
saveGradientToPhotoAlbum:
@MainActor
static func saveGradientToPhotoAlbum(
template: any GradientTemplate,
size: CGSize,
scale: CGFloat = 1.0,
blurRadius: CGFloat = 0,
showDots: Bool = false,
smoothsColors: Bool = true,
completion: @escaping (Result<Void, Error>) -> Void
)
exportVideoToPhotoLibrary:
static func exportVideoToPhotoLibrary(
template: any GradientTemplate,
size: CGSize,
duration: TimeInterval = 5.0,
frameRate: Int32 = 30,
blurRadius: CGFloat = 0,
showDots: Bool = false,
animate: Bool = true,
smoothsColors: Bool = true,
completion: @escaping (Result<URL, Error>) -> Void
)
PhotoLibraryError:
public enum PhotoLibraryError: Error, Sendable {
case permissionDenied
case saveFailed(Error)
}
saveToDisk:
@MainActor
static func saveToDisk(
image: NSImage,
fileName: String = "gradient",
format: ExportFormat = .png,
completion: @escaping (Result<URL, Error>) -> Void
)
saveGradientToDisk:
@MainActor
static func saveGradientToDisk(
template: any GradientTemplate,
size: CGSize,
scale: CGFloat = 1.0,
blurRadius: CGFloat = 0,
showDots: Bool = false,
smoothsColors: Bool = true,
fileName: String = "gradient",
format: ExportFormat = .png,
completion: @escaping (Result<URL, Error>) -> Void
)
exportVideo (macOS):
@MainActor
static func exportVideo(
template: any GradientTemplate,
size: CGSize,
duration: TimeInterval = 5.0,
frameRate: Int32 = 30,
blurRadius: CGFloat = 0,
showDots: Bool = false,
animate: Bool = true,
smoothsColors: Bool = true
) async throws -> URL
SaveToDiskError:
public enum SaveToDiskError: Error, Sendable {
case userCancelled
case cgImageCreationFailed
case imageEncodingFailed(Error)
}
iOS - Save to Photo Library:
MeshingKit.saveGradientToPhotoAlbum(
template: .aurora,
size: CGSize(width: 1080, height: 1920)
) { result in
switch result {
case .success:
print("Saved to photo library!")
case .failure(let error):
print("Error: \(error)")
}
}
iOS - Export Video to Photo Library:
MeshingKit.exportVideoToPhotoLibrary(
template: .midnightDreams,
size: CGSize(width: 1080, height: 1920),
duration: 5.0,
frameRate: 30
) { result in
switch result {
case .success(let url):
print("Video saved: \(url)")
case .failure(let error):
print("Error: \(error)")
}
}
macOS - Save to Disk:
MeshingKit.saveGradientToDisk(
template: .sunsetWave,
size: CGSize(width: 1920, height: 1080),
blurRadius: 10,
fileName: "my-gradient",
format: .png
) { result in
switch result {
case .success(let url):
print("Saved to: \(url)")
case .failure(let error):
print("Error: \(error)")
}
}
macOS - Export Video:
let videoURL = try await MeshingKit.exportVideo(
template: .aurora,
size: CGSize(width: 1920, height: 1080),
duration: 5.0,
frameRate: 30,
animate: true
)
print("Video exported to: \(videoURL)")
struct AnimatedMeshGradientView: View {
public let template: any GradientTemplate
public let animationSpeed: Double
public init(
template: any GradientTemplate,
animationSpeed: Double = 1.0
)
}
public enum AnimationPattern: String, CaseIterable, Identifiable, Sendable {
case fluid, waves, ripples, pulse, none
}
The GradientAnimation.swift module provides animation functions for video export:
static func animatedPositions(
for date: Double,
positions: [SIMD2<Float>],
animate: Bool
) -> [SIMD2<Float>]
ParameterizedNoiseView:
Uses Metal shaders to generate procedural noise textures:
struct ParameterizedNoiseView: View {
@State private var noiseParameter: Float = 0.5
public init(parameter: Float = 0.5)
public var body: some View { ... }
}
Sources/MeshingKit/
├── MeshingKit.swift # Main API
├── GradientTemplate.swift # Protocol
├── PredefinedTemplate.swift # 68 templates + search
├── GradientExport.swift # ExportFormat, VideoExportError
├── GradientExport+iOS.swift # iOS photo library
├── GradientExport+macOS.swift # macOS disk save
├── GradientAnimation.swift # Animation functions
├── GradientVideoExport.swift # Video export public API
├── GradientVideoExportHelper.swift # Video export implementation
├── Color+Hex.swift # Color utilities
├── AnimatedMeshGradientView.swift # Animated view
├── AnimationPattern.swift # Animation patterns
├── ParameterizedNoiseView.swift # Metal shader noise
├── GradientTemplateSize2.swift # 2x2 templates
├── GradientTemplateSize3.swift # 3x3 templates
└── GradientTemplateSize4.swift # 4x4 templates
Sources/Meshin/ # Demo app (SwiftUI)
├── MeshinApp.swift # App entry point
├── MeshinViewModel.swift # Export state management
└── GradientSamplesView.swift # Template list + export UI
Tests/MeshingKitTests/ # Swift Testing suite
scripts/ # Git hooks
codemagic.yaml # CI configuration
.swiftlint.yml # SwiftLint config
The Meshin app demonstrates how to use MeshingKit in a real SwiftUI application:
# macOS
xcodebuild build -project Sources/Meshin/Meshin.xcodeproj -scheme Meshin -destination "generic/platform=macOS"
# iOS Simulator
xcodebuild build -project Sources/Meshin/Meshin.xcodeproj -scheme Meshin -destination "generic/platform=iOS Simulator"
MeshinViewModel.swift - Demonstrates proper usage of MeshingKit export APIsGradientSamplesView.swift - Shows how to integrate gradients with UI@MainActor
final class MyViewModel: ObservableObject {
@Published var selectedTemplate: PredefinedTemplate?
@Published var isExporting = false
func saveToPhotoLibrary() {
guard let template = selectedTemplate else { return }
MeshingKit.saveGradientToPhotoAlbum(
template: template,
size: CGSize(width: 1080, height: 1920)
) { result in
switch result {
case .success: print("Saved!")
case .failure(let error): print("Error: \(error)")
}
}
}
}
Sendable for concurrency safety#expect macro.swiftlint.yml) due to sizecodemagic.yaml)let template = PredefinedTemplate.aurora
let gradientView = MeshingKit.gradient(template: template)
let animatedView = MeshingKit.animatedGradient(
template: PredefinedTemplate.midnightDreams,
animationSpeed: 1.5
)
MeshingKit.animatedGradient(
template: template,
animationPattern: .waves
)
// iOS with blur
MeshingKit.saveGradientToPhotoAlbum(
template: template,
size: CGSize(width: 1080, height: 1920),
blurRadius: 15,
smoothsColors: true
) { /* ... */ }
// macOS with corner radius
MeshingKit.saveGradientToDisk(
template: template,
size: size,
showDots: false
) { /* ... */ }
development
Maintainer-only workflow for handling GitHub Secret Scanning alerts on OpenClaw. Use when Codex needs to triage, redact, clean up, and resolve secret leakage found in issue comments, issue bodies, PR comments, or other GitHub content.
development
Maintainer workflow for OpenClaw releases, prereleases, changelog release notes, and publish validation. Use when Codex needs to prepare or verify stable or beta release steps, align version naming, assemble release notes, check release auth requirements, or validate publish-time commands and artifacts.
development
Run, watch, debug, and extend OpenClaw QA testing with qa-lab and qa-channel. Use when Codex needs to execute the repo-backed QA suite, inspect live QA artifacts, debug failing scenarios, add new QA scenarios, or explain the OpenClaw QA workflow. Prefer the live OpenAI lane with regular openai/gpt-5.4 in fast mode; do not use gpt-5.4-pro or gpt-5.4-mini unless the user explicitly overrides that policy.
development
End-to-end Parallels smoke, upgrade, and rerun workflow for OpenClaw across macOS, Windows, and Linux guests. Use when Codex needs to run, rerun, debug, or interpret VM-based install, onboarding, gateway smoke tests, latest-release-to-main upgrade checks, fresh snapshot retests, or optional Discord roundtrip verification under Parallels.