{"description":"Discover Glyphfield labs, shaders, identities, generation contracts, and the programmatic Studio browser API from one agent-readable interface.","execution":{"completion":["Re-read source or controls after every mutation and confirm the requested state.","For a rendered artifact, verify that the returned Blob is non-empty and its MIME type and file name match the requested format.","For visual work, inspect the authentic rendered canvas; for motion, inspect more than the first frame and verify the requested loop behavior.","For an exact saved shader look, invoke design.frame.capture and retain its portable source. Continuous playback is not proof of a finite seamless loop.","Use design.frame.pause to pause without creating captured-frame assets. PNG/JPG export freezes the current visible frame; GIF/MP4 explicitly sample motion from its anchor. Exports leave the canvas paused and do not persist new frame assets.","Report browser capability failures explicitly. Never claim an export completed from a successful request alone."],"discoveryOrder":["/api/agent","/api/labs","/api/materials or another task-specific catalog","/api/generate for the current schema","/docs/agents/choose-interface.md for interface selection"],"mutation":["Read the current source document before editing an open Studio artifact.","Preserve unknown document fields and make the smallest targeted change.","Apply through the active tool validator; do not mutate React state or storage directly.","Do not run browser exports concurrently because they share renderer and encoder resources.","Shaders.com image effects (/api/materials imageEffects) are Design Lab Effect layers, not shader materials: use design.effects.add { effectId } and design.effects.configure { layerId, effectProps }. They need WebGPU; check design.effects.describe status before exporting."],"never":["Do not invent catalog IDs, accessible labels, source fields, or enum values.","Do not put filesystem paths into browser file inputs; construct an authorized File object.","Do not silently replace MP4 with GIF or a live shader with a static approximation.","Do not retry an unchanged validation failure."]},"brand":{"browserActions":["identity.export.json","identity.read","identity.validate","identity.apply","identity.asset.add","identity.font.add","identity.audit","identity.fix","identity.save","identity.export.kit","identity.setup.prompt","identity.project.create"],"guide":"/docs/agents/brand-setup.md","kit":"/api/brand/kit","skill":"skills/glyphfield-brand/SKILL.md","validate":"/api/brand/validate","workflow":["Research the brand from the user's website, repository or design files; never invent facts.","Open /studio?tool=identity&project=<id>, wait for window.glyphfield.studio, call describe().","identity.validate a merge patch, fix every error, then identity.apply { identity: patch }.","identity.asset.add and identity.font.add with File objects built from authorized bytes.","identity.audit, identity.fix or follow each finding agentPrompt until no errors remain.","identity.save, then identity.export.kit and verify the returned Blob."]},"generation":{"endpoint":"/api/generate","examples":{"background":{"identity":{"preset":"gt"},"kind":"background","output":"json","settings":{"colorA":"#FFFFFF","colorB":"#181818","colorC":"#737373","height":630,"pattern":"dots","patternOpacity":12,"surfaceDepth":68,"surfaceMaterial":"woven-wire","surfaceMetallic":90,"surfaceOpenArea":62,"surfaceRoughness":24,"surfaceScale":38,"logoOpacity":100,"logoX":0,"logoY":0,"style":"grain-gradient","width":1200}},"brief":{"elementId":"email-signature","identity":{"name":"Acme","preset":"custom","tagline":"Tools for careful teams.","website":"acme.test"},"kind":"element-brief"},"designSequence":{"backgroundColor":"#111216","effect":{"background":"#111216","foreground":"#F5F5F2","kind":"bayer","opacity":0.76},"export":{"fps":30,"quality":"best","width":1920},"identity":{"preset":"gt"},"includeBrandMark":true,"kind":"design-sequence","ratio":"wide","sequence":{"cutCount":10,"finalHoldMs":5000,"pace":"accelerating"},"shader":{"materialId":"paper-gem-smoke","shaderSize":1},"texts":[{"value":"Open Source","weight":500}]},"slide":{"body":"Foundation\nExpression\nApplication\nDelivery","identity":{"preset":"gt"},"kind":"template","output":"raw","slideLayout":"agenda","template":"slides","texture":"white","title":"Code is the source of truth."}},"identity":{"fields":{"description":"Optional string, maximum 320 characters","ink":"Optional six-digit HEX color","logoDataUrl":"Optional base64 image data URL, maximum 5 MB","name":"Optional string, maximum 80 characters","paper":"Optional six-digit HEX color","positioning":"Optional string, maximum 320 characters","id":"Optional ID from /api/identities; send { id } alone or the complete identity object from /api/identities. Unknown fields next to preset are rejected with unknown_field.","preset":"starter | template | basement | gt | ramp | mintlify | tailwind | viteplus | cloudflare | stripe | custom","shortName":"Optional string, maximum 8 characters","tagline":"Optional string, maximum 180 characters","website":"Optional string, maximum 200 characters"}},"kinds":{"background":{"description":"Generate a standalone SVG gradient, grain, dither, pattern, or tactile physical surface.","fields":{"identity":"Agent identity object","kind":"background","output":"json | raw; defaults to json","settings":{"angle":"-360–360","bandCount":"3–24 integer","bandDepth":"0–100","bandGap":"0–64","colorA":"Six-digit HEX","colorB":"Six-digit HEX","colorC":"Six-digit HEX","ditherMatrix":"2 | 4 | 8","ditherShape":"dots | squares","focalX":"0–100","focalY":"0–100","gradient":"linear | radial | mesh | orbit | wave | bloom","grain":"0–100","height":"64–4096 integer; total pixels may not exceed 12,000,000","logoColor":"Six-digit HEX","logoScale":"5–90","logoOpacity":"0–100","logoX":"-50–50","logoY":"-50–50","logoTone":"black | white","lightingEnabled":"Boolean; use false for flat bands without gradient lighting","pattern":"none | dots | lines | grid | fibers | speckles | topographic | crosshatch","patternOpacity":"0–100","relief":"0–80","spacing":"8–256 integer","style":"gradient | grain-gradient | dither | pattern","surfaceAngle":"0–180","surfaceDepth":"0–100 height/relief response","surfaceIrregularity":"0–100 surface variation","surfaceLibraryAssetId":"Empty or one of: polyhaven-velour-velvet | ambientcg-fabric-061 | ambientcg-leather-037 | polyhaven-oak-veneer | polyhaven-plywood | polyhaven-marble | polyhaven-metal-plate | ambientcg-metal-063 | polyhaven-beige-wall | polyhaven-rubber-tiles | ambientcg-paper-006","surfaceMaterial":"none | kerf-wood | woven-wire | perforated-metal | carved-stone | embossed-paper | brushed-metal | hammered-foil | corrugated-polymer | cork-composite | frosted-glass | iridescent-film | holo-cloth | linen-weave | felted-wool | pebbled-leather | crackle-glaze | sandblasted-plaster | graphite | carbon-twill","surfaceMetallic":"0–100 specular response","surfaceOpenArea":"0–92 porosity or opening ratio","surfaceRoughness":"0–100 highlight spread","surfaceScale":"12–140 physical pattern scale","surfaceTextureAmount":"0–100 texture-map contribution","width":"64–4096 integer; total pixels may not exceed 12,000,000"}},"mimeTypes":["application/json","image/svg+xml"]},"design-sequence":{"description":"Create an apply-ready Design Lab compatibility document for a fixed composition. Design Lab validates and normalizes it to the current CanvasDocument before authentic browser-native PNG, JPG, GIF, and MP4 export.","fields":{"backgroundColor":"Optional six-digit HEX; defaults to #111216","effect":"Optional bayer | ascii | halftone | posterize converter with opacity and converter settings","export":"width 320–3840; fps 12 | 15 | 24 | 30; quality fast | balanced | best; durationMs 1200–4000; gifLoop raw | seamless","identity":"Agent identity object","includeBrandMark":"Boolean; defaults to true","kind":"design-sequence","ratio":"wide | square | opengraph","sequence":"cutCount 8–12; finalHoldMs 3000–6000; pace accelerating | even","shader":"materialId from /api/materials; blendMode; opacity; shaderSize 0.1–10; shared settings","texts":"Optional array of up to 32 positioned text layers"},"mimeTypes":["application/json"],"programmaticExport":"Open /studio, apply response.document (version 3 compatibility source), re-read the normalized CanvasDocument schema 2 / Design Lab source 4, then invoke design.export with format png | jpg | gif | mp4, optional mode shader-sequence, and optional download true."},"element-brief":{"description":"Resolve one /api/elements record against a preset or custom identity.","fields":{"elementId":"Required ID from /api/elements","identity":"Agent identity object","kind":"element-brief"},"mimeTypes":["application/json"]},"template":{"description":"Generate a standalone OpenGraph, terminal card, slide, blog cover, or partnership SVG from the same brand templates and renderer as the Studio, with the brand fonts and images embedded.","fields":{"background":"Optional six-digit HEX page surface","backgroundImageDataUrl":"Optional base64 image data URL, maximum 5 MB","body":"Optional string, maximum 1000 characters (4000 for terminal code); slides: newline-delimited list items; terminal: the code; other templates: supporting copy","foreground":"Optional six-digit HEX for every text layer","format":"Optional format preset: opengraph | wide | square | portrait | story | linkedin | lockup (slides: 16x9 | 4x3 | square)","identity":"Agent identity object","kind":"template","language":"Optional code language for template terminal: typescript | tsx | javascript | python | bash | json | html | css","layout":"Optional layout variant; opengraph: split | statement | media | centered | editorial; blog: editorial | feature | statement | centered | ledger; terminal: card | split | focus | caption; partnership: lockup | centered | hero | announcement; slides: use slideLayout or layout","output":"json | raw; defaults to json","partnerId":"Optional partner ID: the identity's proof assets from /api/identities, another identity ID, or template-northstar. Without it the lockup uses the identity's own proof partner, or a written \"Partner\" placeholder.","partnerLogoDataUrl":"Optional base64 image data URL, maximum 5 MB","slideLayout":"title | section | agenda | split | metrics | quote | timeline | statement | comparison | process | chart | team | image | closing","template":"slides | blog | partnership | opengraph | terminal","texture":"white | dark | grid | noise","title":"Optional string, maximum 240 characters"},"mimeTypes":["application/json","image/svg+xml"]}},"method":"POST","requestContentType":"application/json","requestSchema":{"discriminator":{"propertyName":"kind"},"oneOf":[{"additionalProperties":false,"properties":{"identity":{"additionalProperties":true,"properties":{"description":{"maxLength":320,"minLength":1,"type":"string"},"ink":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"logoDataUrl":{"maxLength":5000000,"pattern":"^data:image/(gif|jpeg|png|svg\\+xml|webp);base64,[A-Za-z0-9+/=]+$","type":"string"},"name":{"maxLength":80,"minLength":1,"type":"string"},"paper":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"positioning":{"maxLength":320,"minLength":1,"type":"string"},"id":{"description":"An identity ID from /api/identities. Send { id } alone, or the complete identity object from /api/identities (custom identities included) to render with its edits. Do not combine with preset.","maxLength":120,"minLength":1,"type":"string"},"preset":{"enum":["custom","starter","template","basement","gt","ramp","mintlify","tailwind","viteplus","cloudflare","stripe"],"type":"string"},"shortName":{"maxLength":8,"minLength":1,"type":"string"},"tagline":{"maxLength":180,"minLength":1,"type":"string"},"website":{"maxLength":200,"minLength":1,"type":"string"}},"type":"object"},"kind":{"const":"background"},"output":{"enum":["json","raw"],"type":"string"},"settings":{"additionalProperties":true,"properties":{"angle":{"maximum":360,"minimum":-360,"type":"number"},"bandCount":{"maximum":24,"minimum":3,"type":"integer"},"bandDepth":{"maximum":100,"minimum":0,"type":"number"},"bandGap":{"maximum":64,"minimum":0,"type":"number"},"colorA":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"colorB":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"colorC":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"ditherMatrix":{"enum":[2,4,8],"type":"integer"},"ditherShape":{"enum":["dots","squares"],"type":"string"},"focalX":{"maximum":100,"minimum":0,"type":"number"},"focalY":{"maximum":100,"minimum":0,"type":"number"},"gradient":{"enum":["linear","radial","mesh","orbit","wave","bloom"],"type":"string"},"grain":{"maximum":100,"minimum":0,"type":"number"},"height":{"maximum":4096,"minimum":64,"type":"integer"},"lightingEnabled":{"type":"boolean"},"logoColor":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"logoOpacity":{"maximum":100,"minimum":0,"type":"number"},"logoScale":{"maximum":90,"minimum":5,"type":"number"},"logoTone":{"enum":["black","white"],"type":"string"},"logoX":{"maximum":50,"minimum":-50,"type":"number"},"logoY":{"maximum":50,"minimum":-50,"type":"number"},"pattern":{"enum":["none","dots","lines","grid","fibers","speckles","topographic","crosshatch"],"type":"string"},"patternOpacity":{"maximum":100,"minimum":0,"type":"number"},"relief":{"maximum":80,"minimum":0,"type":"number"},"spacing":{"maximum":256,"minimum":8,"type":"integer"},"style":{"enum":["gradient","grain-gradient","dither","pattern"],"type":"string"},"surfaceAngle":{"maximum":180,"minimum":0,"type":"number"},"surfaceDepth":{"maximum":100,"minimum":0,"type":"number"},"surfaceIrregularity":{"maximum":100,"minimum":0,"type":"number"},"surfaceLibraryAssetId":{"enum":["","polyhaven-velour-velvet","ambientcg-fabric-061","ambientcg-leather-037","polyhaven-oak-veneer","polyhaven-plywood","polyhaven-marble","polyhaven-metal-plate","ambientcg-metal-063","polyhaven-beige-wall","polyhaven-rubber-tiles","ambientcg-paper-006"],"type":"string"},"surfaceMaterial":{"enum":["none","kerf-wood","woven-wire","perforated-metal","carved-stone","embossed-paper","brushed-metal","hammered-foil","corrugated-polymer","cork-composite","frosted-glass","iridescent-film","holo-cloth","linen-weave","felted-wool","pebbled-leather","crackle-glaze","sandblasted-plaster","graphite","carbon-twill"],"type":"string"},"surfaceMetallic":{"maximum":100,"minimum":0,"type":"number"},"surfaceOpenArea":{"maximum":92,"minimum":0,"type":"number"},"surfaceRoughness":{"maximum":100,"minimum":0,"type":"number"},"surfaceScale":{"maximum":140,"minimum":12,"type":"number"},"surfaceTextureAmount":{"maximum":100,"minimum":0,"type":"number"},"width":{"maximum":4096,"minimum":64,"type":"integer"}},"type":"object"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"backgroundColor":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"effect":{"additionalProperties":true,"properties":{"background":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"cellSize":{"maximum":64,"minimum":1,"type":"number"},"contrast":{"maximum":4,"minimum":0.1,"type":"number"},"foreground":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"invert":{"type":"boolean"},"kind":{"enum":["ascii","bayer","halftone","posterize"],"type":"string"},"levels":{"maximum":8,"minimum":2,"type":"integer"},"opacity":{"maximum":1,"minimum":0,"type":"number"},"threshold":{"maximum":1,"minimum":0,"type":"number"}},"type":"object"},"export":{"additionalProperties":true,"properties":{"durationMs":{"maximum":4000,"minimum":1200,"type":"integer"},"fps":{"enum":[12,15,24,30],"type":"integer"},"gifLoop":{"enum":["raw","seamless"],"type":"string"},"quality":{"enum":["fast","balanced","best"],"type":"string"},"width":{"maximum":3840,"minimum":320,"type":"integer"}},"type":"object"},"identity":{"additionalProperties":true,"properties":{"description":{"maxLength":320,"minLength":1,"type":"string"},"ink":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"logoDataUrl":{"maxLength":5000000,"pattern":"^data:image/(gif|jpeg|png|svg\\+xml|webp);base64,[A-Za-z0-9+/=]+$","type":"string"},"name":{"maxLength":80,"minLength":1,"type":"string"},"paper":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"positioning":{"maxLength":320,"minLength":1,"type":"string"},"id":{"description":"An identity ID from /api/identities. Send { id } alone, or the complete identity object from /api/identities (custom identities included) to render with its edits. Do not combine with preset.","maxLength":120,"minLength":1,"type":"string"},"preset":{"enum":["custom","starter","template","basement","gt","ramp","mintlify","tailwind","viteplus","cloudflare","stripe"],"type":"string"},"shortName":{"maxLength":8,"minLength":1,"type":"string"},"tagline":{"maxLength":180,"minLength":1,"type":"string"},"website":{"maxLength":200,"minLength":1,"type":"string"}},"type":"object"},"includeBrandMark":{"type":"boolean"},"kind":{"const":"design-sequence"},"ratio":{"enum":["wide","square","opengraph"],"type":"string"},"sequence":{"additionalProperties":true,"properties":{"cutCount":{"maximum":12,"minimum":8,"type":"integer"},"finalHoldMs":{"maximum":6000,"minimum":3000,"type":"integer"},"pace":{"enum":["accelerating","even"],"type":"string"}},"type":"object"},"shader":{"additionalProperties":true,"properties":{"blendMode":{"enum":["multiply","normal","overlay","screen"],"type":"string"},"materialId":{"enum":["paper-gem-smoke","shaders-fluid-chrome","study-line-field","paper-liquid-metal","study-chrome-glares","paper-god-rays","paper-warp","glyphfield-dither-gradient","glyphfield-mesh-gradient","shaders-spectral-bloom","study-radiant-void","study-galactic-rings","pavel-fluid-energy","holo-cloth-silk","glyphfield-liquid-glass","glyphfield-caustics","glyphfield-iridescent-foil","glyphfield-nebula","paper-liquid-metal-noir","glyphfield-silk-ribbons","paper-liquid-metal-stripes","study-relief-gradient","study-orbit-gradient","paper-gem-smoke-fire","paper-liquid-metal-backdrop","paper-gem-smoke-fluorescent","paper-god-rays-ether","paper-smoke-ring-solar","shader-effects-aurora","paper-gem-smoke-infrared","shader-effects-liquid-metal","shader-effects-chrome","shader-effects-holographic","shader-effects-godrays","shader-effects-plasma","shaders-soft-register","shader-effects-mesh-gradient","shader-effects-nebula","shader-effects-flowing-gradient","paper-god-rays-linear","glyphfield-grain-gradient","paper-god-rays-warp","paper-mesh-gradient-purple","shader-effects-prism","shader-effects-strands","paper-smoke-ring","paper-warp-live-ink","shaders-chroma-flow","paper-smoke-ring-cloud","paper-mesh-gradient","paper-smoke-ring-line","shaders-pistons","paper-grain-gradient-wave","paper-mesh-gradient-beach","shaders-drift","paper-mesh-gradient-ink","paper-water-abstract","shadergradient-prismatic-sphere","glyphfield-glyph-field","shader-effects-obsidian","paper-warp-cauldron-pot","shader-effects-light-edge","paper-warp-kelp","paper-grain-gradient","paper-warp-nectar","shader-effects-neon","paper-warp-passion","shader-effects-irradiance","shader-effects-water","shader-effects-marble","shader-effects-swirl","shader-effects-blob","shader-effects-brushed-metal","paper-grain-gradient-blob","shader-effects-hologram","paper-grain-gradient-dots","shader-effects-frost","paper-grain-gradient-ripple","shader-effects-plastic","paper-grain-gradient-truchet","paper-water","shader-effects-goo","shader-effects-lens-flare","shaders-circuit","paper-water-slow-mo","paper-neuro-noise","paper-water-streaming","paper-neuro-noise-bloodstream","paper-metaballs","paper-neuro-noise-ghost","paper-metaballs-background","paper-neuro-noise-sensation","paper-metaballs-ink-drops","shader-effects-smoke-fill","paper-metaballs-solar","shader-effects-ink-flow","shader-effects-smoke","shader-effects-smoke-flow","shaders-mosaic","shader-effects-reaction-diffusion","shader-effects-chroma-flow","shader-effects-fog","shader-effects-particle-flow","shader-effects-magnetic-filings","shader-effects-boids","shaders-pixel-beams","paper-swirl","paper-color-panels","paper-swirl-007","paper-color-panels-glass","paper-swirl-candy","paper-color-panels-gradient","paper-swirl-opening","paper-color-panels-opening","paper-dithering","paper-heatmap","paper-dithering-bugs","paper-heatmap-sepia","paper-dithering-ripple","paper-fluted-glass","paper-dithering-sine-wave","paper-fluted-glass-abstract","paper-dithering-swirl","paper-fluted-glass-folds","paper-dithering-warp","paper-fluted-glass-waves","shader-effects-cursor-trail","shader-effects-multi-point-gradient","shader-effects-waveform","shader-effects-sun-burst","shader-effects-carbon-fiber","shader-effects-heatmap","shader-effects-curl-noise","shader-effects-voronoi","shader-effects-ripples","shader-effects-conic-gradient","shader-effects-voxels","shader-effects-particles","shader-effects-floating-particles","shader-effects-falling-lines","shader-effects-fractal-noise","shader-effects-erosion-noise","shader-effects-beam","paper-voronoi","paper-spiral","paper-voronoi-bubbles","paper-spiral-droplet","paper-voronoi-cells","paper-spiral-jungle","paper-voronoi-lights","paper-spiral-swirl","paper-pulsing-border","shader-effects-worley-noise","paper-pulsing-border-circle","shader-effects-isometric-cubes","paper-pulsing-border-northern-lights","shader-effects-truchet","paper-pulsing-border-solid-line","shader-effects-weave","shader-effects-spiral","shader-effects-scratches","shader-effects-sine-wave","paper-dot-orbit","paper-paper-texture","paper-dot-orbit-bubbles","paper-paper-texture-abstract","paper-dot-orbit-hallucinatory","paper-paper-texture-cardboard","paper-dot-orbit-shine","paper-paper-texture-details","shader-effects-color-wheel","shader-effects-triangular-grid","shader-effects-hex-grid","shader-effects-dot-grid","shader-effects-brick-pattern","shader-effects-chevron","shader-effects-stripes","shader-effects-block-noise","shader-effects-blue-noise","paper-dot-grid","paper-image-dithering","paper-dot-grid-tree-line","paper-image-dithering-natural","paper-dot-grid-triangles","paper-image-dithering-noise","paper-dot-grid-wallpaper","paper-image-dithering-retro","paper-halftone-dots","paper-halftone-cmyk","paper-halftone-dots-led-screen","paper-halftone-cmyk-drops","paper-halftone-dots-mosaic","paper-halftone-cmyk-newspaper","paper-halftone-dots-round-and-square","paper-halftone-cmyk-vintage","shader-effects-checkerboard","shader-effects-grid"],"type":"string"},"opacity":{"maximum":1,"minimum":0,"type":"number"},"settings":{"additionalProperties":false,"properties":{"effectProps":{"type":"object","description":"Native Shaders.com props: only the values to change. Keys, defaults, options and ranges are declared by each material nativeControls in /api/materials; omitted keys use those defaults. Remote media URLs are not accepted."},"amplitude":{"maximum":8,"minimum":0,"type":"number"},"brightness":{"maximum":2,"minimum":0.1,"type":"number"},"centerX":{"maximum":1,"minimum":0,"type":"number"},"centerY":{"maximum":1,"minimum":0,"type":"number"},"colorA":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"colorB":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"colorC":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"density":{"maximum":2,"minimum":0.1,"type":"number"},"detail":{"maximum":8,"minimum":0.5,"type":"number"},"frequency":{"maximum":10,"minimum":0.2,"type":"number"},"grain":{"maximum":100,"minimum":0,"type":"number"},"rotationX":{"maximum":360,"minimum":0,"type":"number"},"rotationY":{"maximum":360,"minimum":0,"type":"number"},"rotationZ":{"maximum":360,"minimum":0,"type":"number"},"speed":{"maximum":1.5,"minimum":0,"type":"number"},"strength":{"maximum":2,"minimum":0,"type":"number"}},"type":"object"},"shaderSize":{"maximum":10,"minimum":0.1,"type":"number"}},"type":"object"},"texts":{"items":{"additionalProperties":true,"properties":{"align":{"enum":["center","left","right"],"type":"string"},"color":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"fontRole":{"enum":["Accent","Body","Code","Display"],"type":"string"},"lineHeight":{"maximum":1.8,"minimum":0.7,"type":"number"},"name":{"maxLength":80,"minLength":1,"type":"string"},"opacity":{"maximum":1,"minimum":0,"type":"number"},"scale":{"maximum":3,"minimum":0.2,"type":"number"},"tracking":{"maximum":0.2,"minimum":-0.12,"type":"number"},"value":{"maxLength":1000,"minLength":1,"type":"string"},"weight":{"maximum":900,"minimum":100,"type":"integer"},"widthScale":{"maximum":3,"minimum":0.25,"type":"number"},"wrap":{"enum":["nowrap","wrap"],"type":"string"},"x":{"maximum":5000,"minimum":-5000,"type":"number"},"y":{"maximum":5000,"minimum":-5000,"type":"number"}},"type":"object"},"maxItems":32,"type":"array"}},"required":["kind"],"type":"object"},{"additionalProperties":false,"properties":{"elementId":{"enum":["welcome-email","onboarding-day3-no-api-key-email","onboarding-day3-api-key-email","onboarding-day3-live-email","onboarding-day5-no-api-key-email","onboarding-day6-api-key-email","onboarding-day6-live-email","onboarding-payment-confirmation-email","auth-magic-link-email","membership-invitation-email","enterprise-intro-email","enterprise-day3-follow-up-email","enterprise-day7-follow-up-email","balance-soft-limit-email","balance-hard-limit-email","free-credit-soft-limit-email","free-credit-hard-limit-email","usage-soft-limit-email","usage-hard-limit-email","billing-payment-failed-email","billing-plan-canceled-email","upgrade-confirmation-email","locadex-setup-complete-email","locadex-pr-reminder-email","email-system-sheet","email-signature","web-card","logo-background","opengraph","error-page","favicon-set","app-icon","navigation-bar","hero-section","feature-grid","pricing-card","testimonial-card","form-controls","command-menu","modal-dialog","toast-notification","data-table","dashboard-widget","empty-state","checkout-card","settings-panel","cli-banner","ascii-mark","terminal-theme","github-readme","docs-header","package-card","x-post","linkedin-post","community-card","social-avatar","launch-card","slide-title","slide-section","blog-cover","report-cover","press-kit","lanyard","event-badge","event-backdrop","partnership-lockup","business-card","sticker-sheet","packaging-label","letterhead","newsletter-email","app-store-gallery","event-invitation-email","auth-screen","sidebar-navigation","search-surface","onboarding-checklist","file-uploader","status-page","api-reference-hero","code-playground","release-notes","video-thumbnail","podcast-cover","social-carousel","case-study-cover","whitepaper-cover","booth-wall","notebook-cover"],"type":"string"},"identity":{"additionalProperties":true,"properties":{"description":{"maxLength":320,"minLength":1,"type":"string"},"ink":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"logoDataUrl":{"maxLength":5000000,"pattern":"^data:image/(gif|jpeg|png|svg\\+xml|webp);base64,[A-Za-z0-9+/=]+$","type":"string"},"name":{"maxLength":80,"minLength":1,"type":"string"},"paper":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"positioning":{"maxLength":320,"minLength":1,"type":"string"},"id":{"description":"An identity ID from /api/identities. Send { id } alone, or the complete identity object from /api/identities (custom identities included) to render with its edits. Do not combine with preset.","maxLength":120,"minLength":1,"type":"string"},"preset":{"enum":["custom","starter","template","basement","gt","ramp","mintlify","tailwind","viteplus","cloudflare","stripe"],"type":"string"},"shortName":{"maxLength":8,"minLength":1,"type":"string"},"tagline":{"maxLength":180,"minLength":1,"type":"string"},"website":{"maxLength":200,"minLength":1,"type":"string"}},"type":"object"},"kind":{"const":"element-brief"}},"required":["elementId","kind"],"type":"object"},{"additionalProperties":false,"properties":{"background":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"backgroundImageDataUrl":{"maxLength":5000000,"pattern":"^data:image/(gif|jpeg|png|svg\\+xml|webp);base64,[A-Za-z0-9+/=]+$","type":"string"},"body":{"maxLength":1000,"minLength":1,"type":"string"},"foreground":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"format":{"description":"Format preset ID: opengraph | wide | square | portrait | story | linkedin | lockup, or for slides 16x9 | 4x3 | square.","type":"string"},"identity":{"additionalProperties":true,"properties":{"description":{"maxLength":320,"minLength":1,"type":"string"},"ink":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"logoDataUrl":{"maxLength":5000000,"pattern":"^data:image/(gif|jpeg|png|svg\\+xml|webp);base64,[A-Za-z0-9+/=]+$","type":"string"},"name":{"maxLength":80,"minLength":1,"type":"string"},"paper":{"pattern":"^#[0-9A-Fa-f]{6}$","type":"string"},"positioning":{"maxLength":320,"minLength":1,"type":"string"},"id":{"description":"An identity ID from /api/identities. Send { id } alone, or the complete identity object from /api/identities (custom identities included) to render with its edits. Do not combine with preset.","maxLength":120,"minLength":1,"type":"string"},"preset":{"enum":["custom","starter","template","basement","gt","ramp","mintlify","tailwind","viteplus","cloudflare","stripe"],"type":"string"},"shortName":{"maxLength":8,"minLength":1,"type":"string"},"tagline":{"maxLength":180,"minLength":1,"type":"string"},"website":{"maxLength":200,"minLength":1,"type":"string"}},"type":"object"},"kind":{"const":"template"},"language":{"enum":["typescript","tsx","javascript","python","bash","json","html","css"],"type":"string"},"layout":{"description":"Layout variant ID for the template (the Studio layout list). Slides also accept slideLayout.","type":"string"},"output":{"enum":["json","raw"],"type":"string"},"partnerId":{"maxLength":80,"minLength":1,"type":"string"},"partnerLogoDataUrl":{"maxLength":5000000,"pattern":"^data:image/(gif|jpeg|png|svg\\+xml|webp);base64,[A-Za-z0-9+/=]+$","type":"string"},"slideLayout":{"enum":["title","section","agenda","split","metrics","quote","timeline","statement","comparison","process","chart","team","image","closing"],"type":"string"},"template":{"enum":["slides","blog","partnership","opengraph","terminal"],"type":"string"},"texture":{"enum":["white","dark","grid","noise"],"type":"string"},"title":{"maxLength":240,"minLength":1,"type":"string"}},"required":["kind"],"type":"object"}]},"unknownTopLevelFields":"Rejected with HTTP 400 and error code unknown_field","schemaVersion":3},"interfaces":{"browser":{"bestFor":["Canvas","WebGL","local files","local fonts","visual placement","PNG","JPG","GIF","MP4","Lottie"],"contract":"/docs/reference/browser-api.md","global":"window.glyphfield.studio","workspace":"/studio"},"docs":{"complete":"/llms-full.txt","concise":"/llms.txt","markdownPattern":"/docs/:path.md","search":"/api/search"},"http":{"bestFor":["discovery","deterministic SVG","identity data","identity validation","brand tokens and brand.md","element briefs","Design Lab source generation"],"contract":"/openapi.json","generation":"/api/generate"}},"name":"Glyphfield Agent API","policies":{"assets":"Use only assets you are authorized to process. Remote URL fetching is not supported.","data":"Generation requests are processed in memory and are not persisted by Glyphfield.","license":"Glyphfield source is licensed under MIT; see https://github.com/Kevin-Liu-01/Glyphfield/blob/main/LICENSE and /llms.txt. Bundled third-party marks remain separately owned."},"resources":{"brandKit":"/api/brand/kit","brandSetupGuide":"/docs/agents/brand-setup","brandValidate":"/api/brand/validate","catalog":"/api/catalog","docs":"/docs","fullInstructions":"/llms-full.txt","elements":"/api/elements","generate":"/api/generate","identities":"/api/identities","instructions":"/llms.txt","markdownDocs":"/docs/:path.md","integrationGuide":"/docs/agents/connect","labs":"/api/labs","materials":"/api/materials","openapi":"/openapi.json","search":"/api/search","skillGuide":"/docs/skills.md","surfaceTextures":"/api/surface-textures/:assetId/:map","workspace":"/studio"},"schemaVersion":3,"skills":{"guide":"/docs/skills.md","packages":[{"id":"glyphfield-create","repositoryPath":"skills/glyphfield-create","useFor":"Layered Design Lab composition, shaders, authored layers, and saved designs"},{"id":"glyphfield-api","repositoryPath":"skills/glyphfield-api","useFor":"Deterministic HTTP discovery, generation, and batch workflows"},{"id":"glyphfield-studio","repositoryPath":"skills/glyphfield-studio","useFor":"Authentic browser Studio operation, source round trips, and local files"},{"id":"glyphfield-export","repositoryPath":"skills/glyphfield-export","useFor":"Still and motion export with artifact, loop, frame, and audio verification"},{"id":"glyphfield-brand","repositoryPath":"skills/glyphfield-brand","useFor":"Set up or improve a brand identity end to end: research, validate, apply, add logo and font files, audit, fix, and export the brand kit"}],"repositoryDirectory":"skills"},"studioBrowserApi":{"event":"glyphfield:studio-api-ready","global":"window.glyphfield.studio","operations":{"activate":"Activate any visible control by its accessible label","activeTool":"Return the active Studio tool ID","applySource":"Apply a JSON object or string through the active tool validator","controls":"List visible interactive controls and current values","describe":"List exact actions, input/output contracts, source support, exports, and HTTP capability for the active tool","download":"Save a generated Blob artifact with its deterministic file name","invoke":"Invoke source, control, export, or tool-specific actions","readSource":"Read the exact current source document","set":"Set a visible form control by accessible label"},"standardActionContracts":{"artifact.download":{"description":"Download a previously returned Blob artifact using its deterministic file name.","input":"{ blob: Blob, fileName: non-empty string }","output":"{ fileName: string }"},"control.activate":{"description":"Activate one enabled control in the active Studio workspace by exact accessible label.","input":"Accessible control label string","output":"null"},"control.set":{"description":"Set one enabled form control in the active Studio workspace by exact accessible label.","input":"{ label: string, value: string | number | boolean | File | File[] }","output":"null"},"controls.list":{"description":"List enabled interactive controls scoped to the active Studio workspace.","input":"No input","output":"Array of { kind, label, value? }"},"source.apply":{"description":"Validate and apply a JSON string or object through the active tool source boundary.","input":"JSON string or object","output":"Normalized source string when readable, otherwise null"},"source.read":{"description":"Read the active tool source document without mutating it.","input":"No input","output":"JSON string"}},"standardActions":["artifact.download","control.activate","control.set","controls.list","source.apply","source.read"],"toolCapabilities":{"animation":{"directHttpGeneration":[],"exports":[{"action":"animation.export.gif","format":"GIF","route":"browser-action"},{"action":"animation.export.mp4","format":"MP4","route":"browser-action"},{"action":"animation.export.png","format":"PNG poster frame","route":"browser-action"},{"action":"animation.export.project","format":"JSON project","route":"browser-action"}],"source":{"apply":true,"boundary":"CanvasDocument schema 2 with Animation state and portable assets","format":"JSON","read":true}},"blog":{"directHttpGeneration":["template"],"exports":[{"action":"blog.export.png","format":"PNG","route":"browser-action"},{"action":"blog.export.svg","format":"SVG","route":"browser-action"},{"format":"SVG","route":"http"}],"source":{"apply":true,"boundary":"Expression document: CanvasDocument schema 2 with expression source version 2","format":"JSON","read":true}},"brand-book":{"directHttpGeneration":[],"exports":[{"action":"brand-book.print","format":"PDF print flow","route":"browser-action"}],"source":{"apply":true,"boundary":"Brand book section order and visibility, and per-page visibility, layout, surface, image, and copy","format":"JSON","read":true}},"brand-elements":{"directHttpGeneration":["element-brief"],"exports":[{"action":"brand-element.export.png","format":"PNG at real pixel size","route":"browser-action"},{"action":"brand-element.export.html","format":"HTML email (inlined styles)","route":"browser-action"},{"action":"brand-element.export.brief","format":"JSON brief","route":"browser-action"}],"source":{"apply":true,"boundary":"Selected brand-element override","format":"JSON","read":true}},"buttons":{"directHttpGeneration":[],"exports":[{"action":"components.code.read","format":"React + Tailwind or HTML + CSS component code","route":"browser-action"},{"action":"components.code.copy","format":"Component code via clipboard","route":"browser-action"}],"source":{"apply":true,"boundary":"Component Library workspace configuration (version 2: pattern, content, system, palette, typography, theme, code format)","format":"JSON","read":true}},"colors":{"directHttpGeneration":[],"exports":[{"action":"colors.tokens.copy","format":"OKLCH CSS, CSS variables, Tailwind v4 or DTCG tokens via clipboard","route":"browser-action"},{"action":"colors.tokens.read","format":"OKLCH CSS, CSS variables, Tailwind v4 or DTCG tokens","route":"browser-action"}],"source":{"apply":true,"boundary":"Identity palette, colorPairings and colorSystem (version 2), plus per-token opacity","format":"JSON","read":true}},"design-board":{"directHttpGeneration":[],"exports":[{"action":"moodboard.export.png","format":"PNG","route":"browser-action"},{"action":"moodboard.export.svg","format":"SVG","route":"browser-action"},{"action":"moodboard.export.identity","format":"Identity JSON","route":"browser-action"}],"source":{"apply":true,"boundary":"Moodboard boards, tiles (order, visibility, layout, size, surface, image, copy), and export settings","format":"JSON","read":true}},"identity":{"directHttpGeneration":[],"exports":[{"action":"identity.export.json","format":"BrandIdentity JSON","route":"browser-action"},{"action":"identity.export.kit","format":"Brand kit ZIP, DTCG JSON, CSS, Tailwind v4 theme, brand.md, logo ZIP","route":"browser-action"},{"format":"DTCG JSON, CSS, Tailwind v4 theme, brand.md via POST /api/brand/kit","route":"http"}],"source":{"apply":true,"boundary":"Complete BrandIdentity","format":"JSON","read":true}},"lottie":{"directHttpGeneration":[],"exports":[{"action":"lottie.export.frame.png","format":"PNG frame","route":"browser-action"},{"action":"lottie.export.gif","format":"GIF","route":"browser-action"},{"action":"lottie.export.mp4","format":"MP4","route":"browser-action"},{"action":"lottie.export.source","format":"JSON or .lottie","route":"browser-action"}],"source":{"apply":true,"boundary":"Portable Lottie composition; raw animation data retained when authorized","format":"JSON","read":true}},"material":{"directHttpGeneration":["design-sequence"],"exports":[{"action":"design.export.png","format":"PNG","route":"browser-action"},{"action":"design.export.jpg","format":"JPG","route":"browser-action"},{"action":"design.export.gif","format":"GIF","route":"browser-action"},{"action":"design.export.mp4","format":"MP4","route":"browser-action"},{"action":"design.export.project","format":"JSON project","route":"browser-action"}],"source":{"apply":true,"boundary":"CanvasDocument schema 2 with Design Lab metadata source 4","format":"JSON","read":true}},"opengraph":{"directHttpGeneration":["background","template"],"exports":[{"action":"opengraph.export.png","format":"PNG","route":"browser-action"},{"action":"opengraph.export.svg","format":"SVG","route":"browser-action"},{"format":"SVG background","route":"http"}],"source":{"apply":true,"boundary":"Expression document: CanvasDocument schema 2 with expression source version 2","format":"JSON","read":true}},"partnership":{"directHttpGeneration":["template"],"exports":[{"action":"partnership.export.png","format":"PNG","route":"browser-action"},{"action":"partnership.export.svg","format":"SVG","route":"browser-action"},{"format":"SVG","route":"http"}],"source":{"apply":true,"boundary":"Expression document: CanvasDocument schema 2 with expression source version 2","format":"JSON","read":true}},"slides":{"directHttpGeneration":["template"],"exports":[{"action":"slides.export.png","format":"PNG","route":"browser-action"},{"action":"slides.export.svg","format":"SVG","route":"browser-action"},{"action":"slides.export.pdf","format":"PDF deck","route":"browser-action"},{"format":"SVG","route":"http"}],"source":{"apply":true,"boundary":"Expression document: CanvasDocument schema 2 with expression source version 2 (one page per slide)","format":"JSON","read":true}},"terminal":{"directHttpGeneration":["template"],"exports":[{"action":"terminal.export.png","format":"PNG","route":"browser-action"},{"action":"terminal.export.svg","format":"SVG","route":"browser-action"},{"format":"SVG","route":"http"}],"source":{"apply":true,"boundary":"Expression document: CanvasDocument schema 2 with expression source version 2","format":"JSON","read":true}},"typography":{"directHttpGeneration":[],"exports":[{"action":"typography.tokens.read","format":"CSS, Tailwind v4 or DTCG type tokens","route":"browser-action"},{"action":"typography.tokens.copy","format":"Type tokens via clipboard","route":"browser-action"}],"source":{"apply":true,"boundary":"Identity typography roles and typeScale plus specimen settings (version 2)","format":"JSON","read":true}}},"toolActions":{"animation":{"animation.export":{"description":"Render the current Animation workspace with its authentic timeline, shaders, and MP4 audio mix, or a PNG poster frame at the playhead.","input":"{ format: 'gif' | 'mp4' | 'png', download?: boolean }","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"animation.export.gif":{"description":"Render the current Animation workspace as GIF.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"animation.export.mp4":{"description":"Render the current Animation workspace as MP4, including configured timeline audio.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"animation.export.png":{"description":"Render the frame at the playhead at full output size as a PNG poster frame.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"animation.export.project":{"description":"Package the complete editable animation and authorized local assets.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"animation.describe":{"description":"Describe scenes with their master-timeline start, hold, outgoing transition, keyframes, and text entrance, plus brand starters.","input":"No input","output":"{ durationMs, fps, width, height, playheadMs, scenes: [{ id, index, kind, label, startMs, holdMs, transitionMs, keyframes, textAnimation }], starters }"},"animation.seek":{"description":"Pause and move the playhead; the inspector follows the displayed scene or transition.","input":"{ timeMs: non-negative number }","output":"animation.describe result"},"animation.scene.update":{"description":"Set a scene hold or outgoing transition (null follows the sequence default), its text entrance (null removes it), or its pose at the playhead (a keyframe when the layer is keyframed).","input":"{ sceneId, holdMs?: number | null, transitionMs?: number | null, textAnimation?: { preset: 'none' | 'type-on' | 'word-rise' | 'line-reveal' | 'glyph-stagger' | 'tracking-in', durationMs?, staggerMs?, easing? } | null, pose?: { alignX?, alignY?, scale?, rotation?, opacity? } } (pose channels clamp to alignX/alignY -1.5..1.5, scale 0.05..8, rotation -720..720, opacity 0..1)","output":"animation.describe result"},"animation.keyframe.set":{"description":"Add or update the scene layer keyframe at a time into its hold, optionally with a pose and outgoing easing.","input":"{ sceneId, atMs, pose?: { alignX?, alignY?, scale?, rotation?, opacity? }, easing?: [x1, y1, x2, y2] } (pose channels clamp like animation.scene.update)","output":"animation.describe result"},"animation.keyframe.remove":{"description":"Remove one keyframe; removing the last keeps its pose as the static pose.","input":"{ sceneId, keyframeId }","output":"animation.describe result"},"animation.motion.preset":{"description":"Replace a scene layer keyframes with a preset built around its settled pose.","input":"{ sceneId, preset: 'push-in' | 'rise-in' | 'slide-in' | 'pop-in' | 'float' }","output":"animation.describe result"},"animation.starter.apply":{"description":"Replace the active artboard with a brand starter composed in the identity art direction. Undo restores the previous sequence.","input":"{ starterId: 'brand-intro' | 'product-reel' | 'proof-points' }","output":"animation.describe result"}},"brand-book":{"brand-book.print":{"description":"Open the browser print flow for every visible page of the edited brand book, one 16 × 10 in page per sheet.","input":"No input","output":"null"}},"brand-elements":{"brand-element.export.brief":{"description":"Create the selected brand element configuration brief as JSON.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"brand-element.export.png":{"description":"Render a brand element, including in-place edits, as PNG at its real pixel size (for example 1200 × 630 for OpenGraph), or twice that with scale 2. Selects elementId first when given.","input":"{ elementId?: string (from /api/elements), scale?: 1 | 2, download?: boolean }","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save; width and height are the PNG pixel size"},"brand-element.export.html":{"description":"Export an email element as a send-ready HTML document: 600 px table layout, inlined styles, MSO wrapper, hidden preheader, bulletproof button and absolute image URLs. Generated header art is embedded as a PNG data URL; host it and replace the src before sending through clients that block data URLs, such as Gmail.","input":"{ elementId?: string (an email element), assetOrigin?: string (origin for image URLs, default the Studio origin), download?: boolean }","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save; previewText holds the HTML"}},"buttons":{"components.code.copy":{"description":"Copy the generated code for a component to the clipboard: React + Tailwind (TSX and theme.css) or HTML + CSS (markup and components.css), built from the same settings as the preview.","input":"{ pattern?: component id, format?: 'react' | 'html' } (defaults to the selected pattern and code format)","output":"The copied text: every file, each headed by its file name"},"components.code.read":{"description":"Return the generated code files for a component without touching the clipboard.","input":"{ pattern?: component id, format?: 'react' | 'html' }","output":"{ pattern, files: [{ name, language, code }] }"},"components.list":{"description":"List every component pattern with its family, description and the states its preview shows.","input":"No input","output":"Array of { id, label, family, description, states }"}},"colors":{"colors.contrast.read":{"description":"Return the WCAG and APCA contrast of every text/background pair in the palette, the approved colorPairings, and the semantic role checks for light and dark.","input":"No input","output":"{ matrix: [{ foreground, background, ratio, wcag, apca, apcaLevel, approved }], pairings, semantic: { light, dark } }"},"colors.pairing.toggle":{"description":"Approve or remove one text pairing in colorPairings. New pairs record AA (4.5:1) or AA-large (3:1); pairs below 3:1 are refused. The change is pending until identity.save or Save changes.","input":"{ foreground: color id, background: color id }","output":"The resulting colorPairings array"},"colors.proportion.balance":{"description":"Apply the 60 / 30 / 10 balance to the palette: paper 60, ink 30, emphasis 10, other colors 0. Pending until saved.","input":"No input","output":"Array of { id, proportion }"},"colors.scale.read":{"description":"Return the OKLCH tint and shade scale (steps 50–950) of one palette color, or of every color.","input":"{ id?: color id }","output":"Record of color id → [{ step, hex, oklch, anchored }]"},"colors.semantic.read":{"description":"Return every semantic role (background … negative) resolved for light and dark: its color ref, HEX, derived default and whether it is overridden.","input":"No input","output":"{ light: Record<role, { ref, hex, defaultRef, overridden }>, dark: … }"},"colors.tokens.copy":{"description":"Copy color tokens to the clipboard. The default is the original OKLCH CSS; css, tailwind and dtcg include scales and semantic light/dark roles.","input":"{ format?: 'oklch-css' | 'css' | 'tailwind' | 'dtcg' } (default 'oklch-css')","output":"The copied text"},"colors.tokens.read":{"description":"Return color tokens without accessing the clipboard. The default is the original OKLCH CSS; css, tailwind and dtcg come from the brand token serializers.","input":"{ format?: 'oklch-css' | 'css' | 'tailwind' | 'dtcg' } (default 'oklch-css')","output":"Token text (CSS, Tailwind v4 theme, or DTCG JSON)"},"colors.vision.read":{"description":"Simulate the palette for a color vision deficiency (Machado 2009, full severity) and list pairs that nearly merge.","input":"{ mode?: 'normal' | 'protanopia' | 'deuteranopia' | 'tritanopia' | 'achromatopsia' } (default 'deuteranopia')","output":"{ mode, colors: [{ id, hex, simulated }], confusable: [{ first, second, distance, typicalDistance }] }"}},"design-board":{"moodboard.export.identity":{"description":"Export the active identity used by the moodboard as JSON.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"moodboard.export.png":{"description":"Render the current moodboard board, including tile edits, as PNG.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"moodboard.export.svg":{"description":"Package the current moodboard board as a standalone SVG with embedded fonts and images.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"}},"identity":{"identity.export.json":{"description":"Export the complete active BrandIdentity as JSON.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"identity.read":{"description":"Read the active BrandIdentity as an object (a copy; mutate through identity.apply).","input":"No input","output":"BrandIdentity object"},"identity.validate":{"description":"Validate a merge patch or complete identity against the BrandIdentity schema without applying it. The schema is served by GET /api/brand/validate.","input":"{ identity: object, mode?: 'patch' | 'full' } (default patch)","output":"{ ok: boolean, issues: [{ code, message, path, severity }] }"},"identity.apply":{"description":"Validate and merge identity source. Records merge by id (typography by role), string lists are replaced, unknown fields and project fields are kept. replace lists collections to overwrite as a whole. Throws a TypeError listing every issue.","input":"{ identity: object, mode?: 'merge' | 'replace', replace?: ('colors' | 'colorPairings' | 'applications' | 'assets' | 'fonts' | …)[], remove?: { assets?, colors?, fonts?, applications?, references?, motion?, proofAssets?: string[] }, save?: boolean }","output":"{ identity, warnings: [{ code, message, path, severity }], saved: boolean, health: { score, grade, counts } }"},"identity.asset.add":{"description":"Add an image asset from file bytes. A logo slot (mark-dark for light surfaces, mark-light for dark surfaces, wordmark, wordmark-light, mark-mono) replaces that slot in place.","input":"{ file: File, slot?: 'mark-dark' | 'mark-light' | 'wordmark' | 'wordmark-light' | 'mark-mono', id?, type?, label?, surface?, usage?, alt?, license?, sourceUrl?, sourceOwner?, redistribution?, tags?, save?: boolean }","output":"{ asset: BrandAsset }"},"identity.font.add":{"description":"Store a TTF, OTF, WOFF or WOFF2 file (2.5 MB maximum) with the identity and optionally assign it to typography roles.","input":"{ file: File, roles?: ('Display' | 'Body' | 'Accent' | 'Code')[], family?, label?, weight?, weightMin?, weightMax?, style?: 'normal' | 'italic', license?, sourceUrl?, id?, save?: boolean }","output":"{ font: BrandFontAsset }"},"identity.audit":{"description":"Run the brand health audit: completeness score, section scores, WCAG contrast pairs and findings with one-click fixes or agent prompts.","input":"No input","output":"{ schemaVersion, score, grade, counts, sections, contrast, findings: [{ id, section, severity, title, detail, fix?: { id, label }, agentPrompt }] }"},"identity.fix":{"description":"Apply one deterministic audit fix by the fix.id of a finding.","input":"{ fixId: string, save?: boolean }","output":"Brand health report after the fix"},"identity.save":{"description":"Save pending identity changes on this device so every tool and future sessions use them.","input":"No input","output":"{ saved: true }"},"identity.export.kit":{"description":"Export the brand kit: a ZIP with brand.md, DTCG tokens, CSS variables, a Tailwind v4 theme, identity.json, logos and redistributable fonts, or one of those files.","input":"{ format?: 'zip' | 'dtcg' | 'css' | 'tailwind' | 'markdown' | 'logos', download?: boolean }","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"identity.setup.prompt":{"description":"Return the ready-to-run Set up with your agent prompt for this project.","input":"{ mode?: 'new' | 'improve' }","output":"{ mode, prompt: string }"},"identity.project.create":{"description":"Create a brand project and make it the active tab in the Brand identity tool, like Add brand project. from is the Starter template (default), a built-in identity id to copy, scratch for an empty identity, or a custom project id to duplicate with its workspaces. After it resolves, read window.glyphfield.studio again: the new project's workspace owns the API.","input":"{ from?: 'starter' | 'scratch' | string (built-in or project id), name?: string }","output":"{ id, name, kind: \"custom\", from, url }"}},"lottie":{"lottie.export":{"description":"Export the current rendered PNG frame, the edited JSON/.lottie source, or the trimmed segment as GIF or MP4 with the composited background.","input":"{ format: 'png' | 'source' | 'gif' | 'mp4', download?: boolean }","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"lottie.export.gif":{"description":"Render the trimmed segment, with speed, direction, edits, and background, as GIF.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"lottie.export.mp4":{"description":"Render the trimmed segment, with speed, direction, edits, and background, as MP4.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"lottie.describe":{"description":"Describe the active document: top-level layers with keys, text layers, static colours, markers, segment, edits, recolour mode, and whether the brand logo layer is shown.","input":"No input","output":"{ format, source, totalFrames, frameRate, segment, layers, textLayers, colors, markers, edits, recolor, brandLogo }"},"lottie.edit":{"description":"Apply non-destructive JSON edits. Each listed field replaces the stored one: hidden layer keys, colour map, text by layer key, named markers, recolour mode, and the brand logo layer (off for imports until turned on).","input":"{ hiddenLayers?: string[], colorMap?: Record<'#RRGGBB', '#RRGGBB'>, textOverrides?: Record<layerKey, string>, markers?: [{ name, frame, duration }], recolor?: 'palette' | 'source', brandLogo?: boolean }","output":"lottie.describe result"},"lottie.colors.brand":{"description":"Map every document colour to the nearest active brand token: chromatic colours to accents, neutrals by lightness.","input":"No input","output":"lottie.describe result"},"lottie.segment.set":{"description":"Play a named marker segment or set the in and out frames.","input":"{ marker: string } | { start: number, end: number }","output":"lottie.describe result"},"lottie.export.frame.png":{"description":"Render the current Lottie frame and configured background as PNG.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"lottie.export.source":{"description":"Export edited JSON or the original .lottie archive according to the active source.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"}},"blog":{"blog.export.png":{"description":"Render the current blog-cover composition as PNG.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"blog.document.describe":{"description":"Describe the blog cover: format, pages, layouts, and every layer with its id, kind, slot, bounds, visibility, and lock state (top layer first).","input":"No input","output":"{ format, formats, layouts, activePageId, selection, pages: [{ id, name, layout, surface, width, height, notes, layers }] }"},"blog.export.svg":{"description":"Render the blog cover as a self-contained SVG with embedded images and fonts.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"blog.format.set":{"description":"Change the output format preset and re-flow every page; free layers scale with the page.","input":"{ format: string } using an id from document.describe().formats","output":"null"},"blog.history.redo":{"description":"Redo the last undone canvas change.","input":"No input","output":"boolean (false when nothing to redo)"},"blog.history.undo":{"description":"Undo the last canvas change.","input":"No input","output":"boolean (false when nothing to undo)"},"blog.layer.add":{"description":"Add a layer: text, image (identity library id or data:image URL), logo, shape, divider, shader (Shader Library still), texture, or brand device.","input":"{ kind: 'text' | 'image' | 'logo' | 'shape' | 'divider' | 'shader' | 'texture' | 'device', content?, bounds?, fill?, libraryAssetId?, dataUrl?, materialId?, device?, shape?: 'rect' | 'ellipse', variant?: 'mark' | 'wordmark' }","output":"{ id: string }"},"blog.layer.align":{"description":"Align layers to an artboard edge or center.","input":"{ ids: string[], alignment: 'left' | 'horizontal-center' | 'right' | 'top' | 'vertical-center' | 'bottom' }","output":"null"},"blog.layer.duplicate":{"description":"Duplicate layers with a small offset and select the copies.","input":"{ ids: string[] }","output":"{ ids: string[] }"},"blog.layer.remove":{"description":"Delete layers.","input":"{ ids: string[] }","output":"null"},"blog.layer.reorder":{"description":"Move a layer in the stack.","input":"{ id: string, to: 'forward' | 'backward' | 'front' | 'back' | number }","output":"null"},"blog.layer.select":{"description":"Select layers on the canvas and in the inspector.","input":"{ ids: string[] }","output":"null"},"blog.layer.update":{"description":"Edit a layer: text, bounds (x, y, width, height, rotation), opacity, visibility, lock, brand color role, type role, size, weight, tracking (em), line height, alignment, casing, or layer data.","input":"{ id, name?, content?, bounds?, opacity?, hidden?, locked?, fill?, fontRole?, fontSize?, fontWeight?, letterSpacing?, lineHeight?, align?, casing?, radius?, data? }","output":"null"},"blog.layout.apply":{"description":"Re-flow a page into a layout variant. Content and hand-set styles stay; geometry follows the layout.","input":"{ layout: string, pageId?: string } using an id from document.describe().layouts","output":"null"},"blog.template.reset":{"description":"Start over from the identity's brand template for this tool.","input":"No input","output":"null"}},"material":{"design.workspace.describe":{"description":"Describe the open canvas, loose layer IDs, artboards, and active editing surface.","input":"No input","output":"{ activeSurface, canvas: { layerIds }, artboards: [{ id, name, x, y, width, height, layerIds }] }"},"design.workspace.frameSelection":{"description":"Create a fitted artboard around the current loose-layer selection without changing its on-canvas scale or layout.","input":"No input; select canvas layers first using the layer controls","output":"null"},"design.workspace.activate":{"description":"Edit the loose canvas or an existing artboard with the shared layer controls.","input":"{ target: 'canvas' | artboardId }","output":"null"},"design.workspace.move":{"description":"Move active layers between the canvas and artboards, preserving their world-space boxes, text layout, and appearance. IDs change only to avoid a destination collision.","input":"{ target: 'canvas' | artboardId, layerIds: string[], placement?: 'preserve' | 'beside' }","output":"null"},"design.export":{"description":"Render the selected artboard using the authentic Design Lab renderer. Loose canvas layers are not exported; select an artboard first.","input":"{ format: 'png' | 'jpg' | 'gif' | 'mp4', mode?: 'standard' | 'shader-sequence', download?: boolean }","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"design.text.format":{"description":"Format a non-empty range of text on the active surface without changing other characters. Ordered runs survive source, history, saved designs, and export.","input":"{ layerId, start, end, style: { color?, fontRole?: 'Display' | 'Body' | 'Accent' | 'Code', fontSize?, weight?, fontStyle?: 'normal' | 'italic', underline?, strikethrough?, tracking? } }; start/end are UTF-16 offsets, end exclusive; fontSize is authored pixels before layer scale","output":"null"},"design.export.gif":{"description":"Render the current design as GIF.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"design.export.jpg":{"description":"Render the current design as JPG.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"design.export.mp4":{"description":"Render the current design as MP4.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"design.export.png":{"description":"Render the current design as PNG.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"design.export.project":{"description":"Package every editable artboard, authorized local image, shader frame, and local font in the portable project format.","input":"No input","output":"ExportPreviewAsset: non-empty application/json Blob, .glyphfield.json fileName, format JSON, previewKind file; use studio.download(artifact) to save"},"design.export.shader-sequence.gif":{"description":"Render the configured shader sequence as GIF.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"design.export.shader-sequence.mp4":{"description":"Render the configured shader sequence as MP4.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"design.frame.capture":{"description":"Freeze ready native shader pixels and persist lossless PNG checkpoints with editable renderer state.","input":"No input","output":"Portable CanvasDocument JSON string with embedded captured-frame assets"},"design.frame.pause":{"description":"Synchronously pause the visible native shader frame without encoding PNGs or writing captured-frame assets.","input":"No input","output":"null"},"design.frame.play":{"description":"Resume native shader playback.","input":"No input","output":"null"},"design.frame.seek":{"description":"Select shader time for editable, seekable materials; reject stateful simulation replay.","input":"{ timeMs: non-negative finite number }","output":"null"},"design.motion.describe":{"description":"Describe current layer providers, seek/capture support, and known or unverified loop behavior.","input":"No input","output":"Motion capability object for every active shader layer"},"design.sequence.configure":{"description":"Update validated shader-sequence settings.","input":"Partial shader-sequence settings object","output":"null"},"design.sequence.describe":{"description":"Describe resolved shader-sequence settings, duration, and material timeline.","input":"No input","output":"{ durationMs, materials, settings }"},"design.sequence.preview":{"description":"Start the configured shader-sequence preview.","input":"No input","output":"null"},"design.sequence.stop":{"description":"Stop the shader-sequence preview.","input":"No input","output":"null"},"design.layers.arrange":{"description":"Align unlocked layers to the bounds of the selection, or space them evenly. A fully selected group moves as one unit.","input":"{ arrangement: 'left' | 'horizontal-center' | 'right' | 'top' | 'vertical-center' | 'bottom' | 'distribute-horizontal' | 'distribute-vertical', layerIds?: string[] }; omit layerIds to use the current selection; align needs 2 units, distribute 3","output":"null"},"design.layers.lock":{"description":"Lock or unlock layers. Locked layers ignore canvas pointer and keyboard edits but stay editable in the inspector; source records element.locked.","input":"{ layerIds: string[], locked: boolean }","output":"null"},"design.layers.rotate":{"description":"Turn unlocked layers clockwise about their own centers to an absolute angle. Locked layers are skipped; source records bounds.rotation.","input":"{ layerIds: string[], rotation: number } (degrees; normalized to -180..180, 0 removes the rotation)","output":"null"},"design.layers.copyStyle":{"description":"Copy one layer's appearance (type, color, effects, opacity and material), never its content or geometry.","input":"{ layerId: string }","output":"null"},"design.layers.pasteStyle":{"description":"Apply the copied style to unlocked layers. Each target takes the fields it shares with the source; a copied material fills content layers.","input":"{ layerIds: string[] }","output":"null"},"design.effects.describe":{"description":"List the active artboard's Effect layers (built-in converter kind, or image effectId, effectProps and WebGPU status) and the image effects on offer.","input":"No input","output":"{ builtIn, imageEffects: { categories, effects, controls }, layers }"},"design.effects.add":{"description":"Add an Effect layer above every layer of the active artboard: a built-in converter (kind) or a Shaders.com image effect (effectId) that processes the composited layers beneath it. Image effects need WebGPU; exports refuse without it.","input":"{ kind?: 'bayer' | 'ascii' | 'halftone' | 'posterize', effectId?: string from /api/materials imageEffects, effectProps?: object (explicit edits; validated against nativeControls; sourceImage is not accepted), opacity?: 0..1 }","output":"{ layerId }"},"design.effects.configure":{"description":"Switch an Effect layer to another converter kind or image effectId, replace its effectProps (pass {} to reset), or set its opacity.","input":"{ layerId: string, kind?: string, effectId?: string, effectProps?: object, opacity?: 0..1 }; kind and effectId are exclusive","output":"{ layerId }"}},"opengraph":{"opengraph.export.png":{"description":"Render the current OpenGraph composition as PNG.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"opengraph.document.describe":{"description":"Describe the OpenGraph composition: format, pages, layouts, and every layer with its id, kind, slot, bounds, visibility, and lock state (top layer first).","input":"No input","output":"{ format, formats, layouts, activePageId, selection, pages: [{ id, name, layout, surface, width, height, notes, layers }] }"},"opengraph.export.svg":{"description":"Render the OpenGraph composition as a self-contained SVG with embedded images and fonts.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"opengraph.format.set":{"description":"Change the output format preset and re-flow every page; free layers scale with the page.","input":"{ format: string } using an id from document.describe().formats","output":"null"},"opengraph.history.redo":{"description":"Redo the last undone canvas change.","input":"No input","output":"boolean (false when nothing to redo)"},"opengraph.history.undo":{"description":"Undo the last canvas change.","input":"No input","output":"boolean (false when nothing to undo)"},"opengraph.layer.add":{"description":"Add a layer: text, image (identity library id or data:image URL), logo, shape, divider, shader (Shader Library still), texture, or brand device.","input":"{ kind: 'text' | 'image' | 'logo' | 'shape' | 'divider' | 'shader' | 'texture' | 'device', content?, bounds?, fill?, libraryAssetId?, dataUrl?, materialId?, device?, shape?: 'rect' | 'ellipse', variant?: 'mark' | 'wordmark' }","output":"{ id: string }"},"opengraph.layer.align":{"description":"Align layers to an artboard edge or center.","input":"{ ids: string[], alignment: 'left' | 'horizontal-center' | 'right' | 'top' | 'vertical-center' | 'bottom' }","output":"null"},"opengraph.layer.duplicate":{"description":"Duplicate layers with a small offset and select the copies.","input":"{ ids: string[] }","output":"{ ids: string[] }"},"opengraph.layer.remove":{"description":"Delete layers.","input":"{ ids: string[] }","output":"null"},"opengraph.layer.reorder":{"description":"Move a layer in the stack.","input":"{ id: string, to: 'forward' | 'backward' | 'front' | 'back' | number }","output":"null"},"opengraph.layer.select":{"description":"Select layers on the canvas and in the inspector.","input":"{ ids: string[] }","output":"null"},"opengraph.layer.update":{"description":"Edit a layer: text, bounds (x, y, width, height, rotation), opacity, visibility, lock, brand color role, type role, size, weight, tracking (em), line height, alignment, casing, or layer data.","input":"{ id, name?, content?, bounds?, opacity?, hidden?, locked?, fill?, fontRole?, fontSize?, fontWeight?, letterSpacing?, lineHeight?, align?, casing?, radius?, data? }","output":"null"},"opengraph.layout.apply":{"description":"Re-flow a page into a layout variant. Content and hand-set styles stay; geometry follows the layout.","input":"{ layout: string, pageId?: string } using an id from document.describe().layouts","output":"null"},"opengraph.template.reset":{"description":"Start over from the identity's brand template for this tool.","input":"No input","output":"null"}},"partnership":{"partnership.export.png":{"description":"Render the current partnership lockup as PNG.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"partnership.document.describe":{"description":"Describe the partnership lockup: format, pages, layouts, and every layer with its id, kind, slot, bounds, visibility, and lock state (top layer first).","input":"No input","output":"{ format, formats, layouts, activePageId, selection, pages: [{ id, name, layout, surface, width, height, notes, layers }] }"},"partnership.export.svg":{"description":"Render the partnership lockup as a self-contained SVG with embedded images and fonts.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"partnership.format.set":{"description":"Change the output format preset and re-flow every page; free layers scale with the page.","input":"{ format: string } using an id from document.describe().formats","output":"null"},"partnership.history.redo":{"description":"Redo the last undone canvas change.","input":"No input","output":"boolean (false when nothing to redo)"},"partnership.history.undo":{"description":"Undo the last canvas change.","input":"No input","output":"boolean (false when nothing to undo)"},"partnership.layer.add":{"description":"Add a layer: text, image (identity library id or data:image URL), logo, shape, divider, shader (Shader Library still), texture, or brand device.","input":"{ kind: 'text' | 'image' | 'logo' | 'shape' | 'divider' | 'shader' | 'texture' | 'device', content?, bounds?, fill?, libraryAssetId?, dataUrl?, materialId?, device?, shape?: 'rect' | 'ellipse', variant?: 'mark' | 'wordmark' }","output":"{ id: string }"},"partnership.layer.align":{"description":"Align layers to an artboard edge or center.","input":"{ ids: string[], alignment: 'left' | 'horizontal-center' | 'right' | 'top' | 'vertical-center' | 'bottom' }","output":"null"},"partnership.layer.duplicate":{"description":"Duplicate layers with a small offset and select the copies.","input":"{ ids: string[] }","output":"{ ids: string[] }"},"partnership.layer.remove":{"description":"Delete layers.","input":"{ ids: string[] }","output":"null"},"partnership.layer.reorder":{"description":"Move a layer in the stack.","input":"{ id: string, to: 'forward' | 'backward' | 'front' | 'back' | number }","output":"null"},"partnership.layer.select":{"description":"Select layers on the canvas and in the inspector.","input":"{ ids: string[] }","output":"null"},"partnership.layer.update":{"description":"Edit a layer: text, bounds (x, y, width, height, rotation), opacity, visibility, lock, brand color role, type role, size, weight, tracking (em), line height, alignment, casing, or layer data.","input":"{ id, name?, content?, bounds?, opacity?, hidden?, locked?, fill?, fontRole?, fontSize?, fontWeight?, letterSpacing?, lineHeight?, align?, casing?, radius?, data? }","output":"null"},"partnership.layout.apply":{"description":"Re-flow a page into a layout variant. Content and hand-set styles stay; geometry follows the layout.","input":"{ layout: string, pageId?: string } using an id from document.describe().layouts","output":"null"},"partnership.template.reset":{"description":"Start over from the identity's brand template for this tool.","input":"No input","output":"null"},"partnership.partner.add":{"description":"Add a partner to the lockup from the partner list or as written text.","input":"{ partnerId?: string, kind?: 'logo' | 'text', label?: string }","output":"{ id: string }"},"partnership.partner.remove":{"description":"Remove a partner from the lockup; the active brand stays.","input":"{ id: string }","output":"null"},"partnership.lockup.update":{"description":"Set lockup alignment rules.","input":"{ separator?: '×' | '+' | '/' | '|' | 'none', sizing?: 'optical' | 'height' | 'width', justify?: 'start' | 'center' | 'end', verticalAlign?: 'center' | 'top' | 'bottom', gap?: number, tone?: 'original' | 'mono' }","output":"null"}},"slides":{"slides.export.png":{"description":"Render the active slide as PNG.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"slides.document.describe":{"description":"Describe the deck: format, pages, layouts, and every layer with its id, kind, slot, bounds, visibility, and lock state (top layer first).","input":"No input","output":"{ format, formats, layouts, activePageId, selection, pages: [{ id, name, layout, surface, width, height, notes, layers }] }"},"slides.export.svg":{"description":"Render the active slide as a self-contained SVG with embedded images and fonts.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"slides.format.set":{"description":"Change the output format preset and re-flow every page; free layers scale with the page.","input":"{ format: string } using an id from document.describe().formats","output":"null"},"slides.history.redo":{"description":"Redo the last undone canvas change.","input":"No input","output":"boolean (false when nothing to redo)"},"slides.history.undo":{"description":"Undo the last canvas change.","input":"No input","output":"boolean (false when nothing to undo)"},"slides.layer.add":{"description":"Add a layer: text, image (identity library id or data:image URL), logo, shape, divider, shader (Shader Library still), texture, or brand device.","input":"{ kind: 'text' | 'image' | 'logo' | 'shape' | 'divider' | 'shader' | 'texture' | 'device', content?, bounds?, fill?, libraryAssetId?, dataUrl?, materialId?, device?, shape?: 'rect' | 'ellipse', variant?: 'mark' | 'wordmark' }","output":"{ id: string }"},"slides.layer.align":{"description":"Align layers to an artboard edge or center.","input":"{ ids: string[], alignment: 'left' | 'horizontal-center' | 'right' | 'top' | 'vertical-center' | 'bottom' }","output":"null"},"slides.layer.duplicate":{"description":"Duplicate layers with a small offset and select the copies.","input":"{ ids: string[] }","output":"{ ids: string[] }"},"slides.layer.remove":{"description":"Delete layers.","input":"{ ids: string[] }","output":"null"},"slides.layer.reorder":{"description":"Move a layer in the stack.","input":"{ id: string, to: 'forward' | 'backward' | 'front' | 'back' | number }","output":"null"},"slides.layer.select":{"description":"Select layers on the canvas and in the inspector.","input":"{ ids: string[] }","output":"null"},"slides.layer.update":{"description":"Edit a layer: text, bounds (x, y, width, height, rotation), opacity, visibility, lock, brand color role, type role, size, weight, tracking (em), line height, alignment, casing, or layer data.","input":"{ id, name?, content?, bounds?, opacity?, hidden?, locked?, fill?, fontRole?, fontSize?, fontWeight?, letterSpacing?, lineHeight?, align?, casing?, radius?, data? }","output":"null"},"slides.layout.apply":{"description":"Re-flow a page into a layout variant. Content and hand-set styles stay; geometry follows the layout.","input":"{ layout: string, pageId?: string } using an id from document.describe().layouts","output":"null"},"slides.template.reset":{"description":"Start over from the identity's brand template for this tool.","input":"No input","output":"null"},"slides.export.pdf":{"description":"Render every slide into one multi-page PDF (lossless page images).","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"slides.slide.add":{"description":"Add a slide after the active one using a layout.","input":"{ layout?: string, index?: number }","output":"{ pageId: string }"},"slides.slide.duplicate":{"description":"Duplicate a slide (default: active).","input":"{ pageId?: string }","output":"{ pageId: string }"},"slides.slide.move":{"description":"Move a slide to a new position.","input":"{ pageId: string, index: number }","output":"null"},"slides.slide.remove":{"description":"Delete a slide; the deck keeps at least one.","input":"{ pageId: string }","output":"null"},"slides.slide.select":{"description":"Show a slide on the canvas.","input":"{ pageId: string }","output":"null"}},"terminal":{"terminal.export.png":{"description":"Render the current syntax-highlighted terminal card as PNG.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"terminal.document.describe":{"description":"Describe the terminal card: format, pages, layouts, and every layer with its id, kind, slot, bounds, visibility, and lock state (top layer first).","input":"No input","output":"{ format, formats, layouts, activePageId, selection, pages: [{ id, name, layout, surface, width, height, notes, layers }] }"},"terminal.export.svg":{"description":"Render the terminal card as a self-contained SVG with embedded images and fonts.","input":"No input","output":"ExportPreviewAsset with a non-empty Blob and deterministic fileName; use studio.download(artifact) to save"},"terminal.format.set":{"description":"Change the output format preset and re-flow every page; free layers scale with the page.","input":"{ format: string } using an id from document.describe().formats","output":"null"},"terminal.history.redo":{"description":"Redo the last undone canvas change.","input":"No input","output":"boolean (false when nothing to redo)"},"terminal.history.undo":{"description":"Undo the last canvas change.","input":"No input","output":"boolean (false when nothing to undo)"},"terminal.layer.add":{"description":"Add a layer: text, image (identity library id or data:image URL), logo, shape, divider, shader (Shader Library still), texture, or brand device.","input":"{ kind: 'text' | 'image' | 'logo' | 'shape' | 'divider' | 'shader' | 'texture' | 'device', content?, bounds?, fill?, libraryAssetId?, dataUrl?, materialId?, device?, shape?: 'rect' | 'ellipse', variant?: 'mark' | 'wordmark' }","output":"{ id: string }"},"terminal.layer.align":{"description":"Align layers to an artboard edge or center.","input":"{ ids: string[], alignment: 'left' | 'horizontal-center' | 'right' | 'top' | 'vertical-center' | 'bottom' }","output":"null"},"terminal.layer.duplicate":{"description":"Duplicate layers with a small offset and select the copies.","input":"{ ids: string[] }","output":"{ ids: string[] }"},"terminal.layer.remove":{"description":"Delete layers.","input":"{ ids: string[] }","output":"null"},"terminal.layer.reorder":{"description":"Move a layer in the stack.","input":"{ id: string, to: 'forward' | 'backward' | 'front' | 'back' | number }","output":"null"},"terminal.layer.select":{"description":"Select layers on the canvas and in the inspector.","input":"{ ids: string[] }","output":"null"},"terminal.layer.update":{"description":"Edit a layer: text, bounds (x, y, width, height, rotation), opacity, visibility, lock, brand color role, type role, size, weight, tracking (em), line height, alignment, casing, or layer data.","input":"{ id, name?, content?, bounds?, opacity?, hidden?, locked?, fill?, fontRole?, fontSize?, fontWeight?, letterSpacing?, lineHeight?, align?, casing?, radius?, data? }","output":"null"},"terminal.layout.apply":{"description":"Re-flow a page into a layout variant. Content and hand-set styles stay; geometry follows the layout.","input":"{ layout: string, pageId?: string } using an id from document.describe().layouts","output":"null"},"terminal.template.reset":{"description":"Start over from the identity's brand template for this tool.","input":"No input","output":"null"},"terminal.tab.add":{"description":"Add a file tab to the code window and show it.","input":"{ name?: string, language?: string, code?: string }","output":"{ tabId: string }"},"terminal.tab.remove":{"description":"Remove a file tab; the window keeps at least one.","input":"{ tabId: string }","output":"null"},"terminal.tab.select":{"description":"Show a file tab.","input":"{ tabId: string }","output":"null"},"terminal.tab.update":{"description":"Edit a tab's name, language, code, or highlighted lines (1-based).","input":"{ tabId: string, name?, language?, code?, highlight?: number[] }","output":"null"}},"typography":{"typography.axes.read":{"description":"Read the variation axes (wght, opsz, slnt …) of each role’s font file. WOFF2 needs a browser that decodes Brotli; unreadable files return null.","input":"No input","output":"Record of role → { family, fontId, axes: [{ tag, min, default, max }] | null }"},"typography.guidance.read":{"description":"Return leading, tracking, measure, scale and weight warnings for every role at its scale size.","input":"No input","output":"Array of { id, role?, severity, message }"},"typography.scale.read":{"description":"Return the modular type scale: base, ratio and its name, each step in px and rem, and the step each role is set at.","input":"No input","output":"{ basePx, ratio, ratioName, roleSteps, steps: [{ name, step, px, rem }] }"},"typography.tokens.copy":{"description":"Copy the type tokens (families, sizes, weights, leading, tracking, axes, scale) to the clipboard.","input":"{ format?: 'css' | 'tailwind' | 'dtcg' } (default 'css')","output":"The copied text"},"typography.tokens.read":{"description":"Return the type tokens without accessing the clipboard, from the brand token serializers.","input":"{ format?: 'css' | 'tailwind' | 'dtcg' } (default 'css')","output":"Token text"}}},"version":1},"version":"0.3.0"}