workato-connector-ux
This skill should be used when the user asks to "build a Workato connector", "create a custom connector", "improve connector UX", "add input fields to connector", "make fields sticky", "use extends_schema", "add dynamic fields", or is working with Workato SDK Ruby DSL for custom connectors. Also use proactively when implementing connector actions or configuring input field visibility.
What this skill does
# Workato Connector SDK - Recipe Developer UX Patterns
Guide for building Workato custom connectors with excellent recipe developer experience. Focus on field visibility, dynamic schemas, and input patterns that make connectors intuitive to configure.
## Core Principle: Recipe Developer First
Connector inputs must be designed from the recipe developer's perspective. Every field must be:
- **Visible when needed** — Use `sticky: true` for primary inputs
- **Pre-configured when possible** — Use `default:` for common choices
- **Contextually shown** — Use `ngIf` and `extends_schema` for conditional fields
## Field Visibility Patterns
### sticky: true
Mark fields as sticky to keep them visible in the recipe editor. Without sticky, optional fields collapse into "Show optional fields".
**When to use:**
- Primary input fields (the main data users enter)
- Fields users configure in most recipes
- Source type selectors after a parent choice
- Both fields in a paired object (like `type` + `budget_tokens`)
```ruby
{
name: 'message',
label: 'Text to send',
type: 'string',
control_type: 'text-area',
sticky: true, # Always visible
optional: true,
hint: 'The message content.'
}
```
### default: value
Pre-populate selectors so users see input fields immediately without making a selection first.
**When to use:**
- Mode selectors where one option is most common
- Configuration fields with sensible defaults
- Version fields with a current stable value
```ruby
{
name: 'message_type',
control_type: 'select',
pick_list: 'message_types',
optional: false,
default: 'single_message', # Most common choice
hint: 'Choose message type.'
}
```
### Combining sticky + default
For the best UX, combine both patterns:
```ruby
{
name: 'temperature',
control_type: 'number',
convert_input: 'float_conversion',
sticky: true, # Always visible
default: 1.0, # Sensible starting value
hint: 'Controls randomness (0.0-2.0).'
}
```
## Dynamic Schema Patterns
### extends_schema
Use `extends_schema: true` when a field selection should reveal additional fields. Workato re-evaluates the schema when this field changes.
```ruby
{
name: 'source_type',
control_type: 'select',
pick_list: 'source_types',
extends_schema: true, # Triggers schema refresh
sticky: true,
hint: 'How to provide the data.'
}
```
### ngIf Conditionals
Show fields only when relevant using `ngIf` with input path expressions:
```ruby
# Show URL field only when source_type is 'url'
{
name: 'image_url',
label: 'Image URL',
type: 'string',
ngIf: 'input.source_type == "url"',
hint: 'Public URL of the image.'
},
# Show base64 fields only when source_type is 'base64'
{
name: 'image_data',
label: 'Image data (Base64)',
type: 'string',
control_type: 'text-area',
ngIf: 'input.source_type == "base64"',
hint: 'Base64-encoded image data.'
}
```
### Nested ngIf Paths
For fields inside objects or arrays, use dot notation:
```ruby
ngIf: 'input.tool_choice.type == "tool"'
ngIf: 'input.block_type == "document" && input.document_source_type == "file"'
```
## toggle_field Pattern
Allow both dropdown selection and custom text input:
```ruby
{
name: 'model',
control_type: 'select',
pick_list: 'model_list',
toggle_hint: 'Select from list',
toggle_field: {
name: 'model',
label: 'Model ID',
type: 'string',
control_type: 'text',
toggle_hint: 'Enter model ID',
hint: 'Enter model ID directly, e.g. custom-model-v1'
}
}
```
## Control Types Reference
| control_type | Use For | Notes |
|--------------|---------|-------|
| `text` | Short strings | Default for string type |
| `text-area` | Long text, JSON | Multi-line input |
| `select` | Single choice | Requires `pick_list` or `options` |
| `multiselect` | Multiple choices | Returns array, needs `delimiter` |
| `number` | Decimals | Use with `float_conversion` |
| `integer` | Whole numbers | Use with `integer_conversion` |
| `checkbox` | Boolean | Use with `boolean_conversion` |
| `password` | Secrets | Masked input |
| `schema-designer` | JSON schema | Visual schema builder |
## Type Conversions
Always pair control types with appropriate conversions:
```ruby
{ control_type: 'integer', convert_input: 'integer_conversion' }
{ control_type: 'number', convert_input: 'float_conversion' }
{ control_type: 'checkbox', convert_input: 'boolean_conversion' }
```
## List Mode Patterns
### Static Lists (Fixed Items)
Use for small, bounded collections:
```ruby
{
name: 'items',
type: 'array',
of: 'object',
list_mode: 'static',
list_mode_toggle: true, # Allow switching to dynamic
properties: [...]
}
```
### Dynamic Lists (From Datapills)
Use when items come from upstream data:
```ruby
{
name: 'messages',
type: 'array',
of: 'object',
list_mode: 'dynamic',
list_mode_toggle: true,
properties: [...]
}
```
## Object Definitions Pattern
Define reusable schemas in `object_definitions:` block:
```ruby
object_definitions: {
message_input: {
fields: lambda do |_connection, config_fields, _object_definitions|
# Dynamic field generation based on config_fields
is_single = config_fields['mode'] == 'single'
if is_single
[{ name: 'text', type: 'string', sticky: true }]
else
[{ name: 'messages', type: 'array', of: 'object', properties: [...] }]
end
end
}
}
```
Reference in actions:
```ruby
input_fields: lambda do |object_definitions|
object_definitions['message_input']
end
```
## Pick Lists
### Static Pick Lists
Define in `pick_lists:` block:
```ruby
pick_lists: {
source_types: lambda do
[['Base64 encoded', 'base64'], ['URL', 'url']]
end
}
```
### Dynamic Pick Lists (API-driven)
Fetch options from API:
```ruby
pick_lists: {
model_list: lambda do
get('v1/models')&.[]('data')&.map do |model|
[model['display_name'], model['id']]
end
end
}
```
### Connection Fields Limitation
Connection fields cannot reference `pick_lists:` (authentication not yet available). Use inline `options:` instead:
```ruby
# In connection: fields:
{
name: 'version',
control_type: 'select',
options: [['2023-06-01', '2023-06-01']], # Inline, not pick_list
default: '2023-06-01'
}
```
## Helper Methods Pattern
Define reusable logic in `methods:` block:
```ruby
methods: {
get_content_block_properties: lambda do
[
{ name: 'block_type', control_type: 'select', ... },
{ name: 'url', ngIf: 'input.block_type == "url"', ... }
]
end
}
```
Call methods with `call('method_name', args)`:
```ruby
content_props = call('get_content_block_properties')
```
## Hints Best Practices
Hints must be crafted from the recipe developer's perspective:
- **Explain what, not how** — "The maximum tokens to generate" not "Set this to control output length"
- **Mention defaults** — "Defaults to 4096 if left blank"
- **Link to docs** — Use `<a href="..." target="_blank">docs</a>` for complex topics
- **Be concise** — One sentence when possible
```ruby
hint: 'Maximum tokens to generate. See <a href="https://docs.example.com/models" ' \
'target="_blank">models</a> for limits. Defaults to 4096.'
```
## Additional Resources
### Reference Files
For detailed patterns and complete examples, consult:
- **`references/field-patterns.md`** — Complete sticky, default, optional patterns with examples
- **`references/control-types.md`** — All control types with conversion requirements
- **`references/schema-patterns.md`** — Object definitions, methods, config_fields patterns
Related in Design
contribute
IncludedLocal-only OSS contribution command center. Auto-refreshes the user's in-flight PR and issue state on invoke so conversations start with full context — no need to brief Claude on what's in flight. Helps the user find issues to contribute to on GitHub, builds per-repo dossiers of what each upstream expects (CLA, DCO, branch convention, AI policy, draft-first, review bots, issue templates), runs deterministic gates before any external action so AI-assisted contributions don't reach maintainers as slop. State is markdown-only: candidate files at ~/.contribute-system/candidates/, repo dossiers at ~/.contribute-system/research/, append-only event log at ~/.contribute-system/log.jsonl. No database, no cloud calls. Use when the user asks about their PRs / issues / contributions, wants to find new work to take on, claim an issue, build/refresh a repo's dossier, or draft a Design Issue or PR. Trigger with "/contribute", "what's my PR status", "find a contribution", "claim issue X", "draft a Design Issue for Y", "refresh dossier for Z".
architectural-analysis
IncludedUser-triggered deep architectural analysis of a codebase or scoped subtree across eight modes — information architecture, data flow, integration points, UI surfaces, interaction patterns, data model, control flow, and failure modes. This skill should be used when the user asks to "diagram this codebase," "map the architecture," "show the data flow," "give me an ERD," "trace control flow," "find the integration points," "verify the layout pattern," "audit the UX architecture," or any similar request whose primary deliverable is mermaid diagrams plus cited reports under docs/architecture/. Dispatches haiku/sonnet sub-agents in parallel for per-mode exploration, then verifies every citation mechanically before any node lands in a diagram. Not for one-off prose explanations of code (use code-explanation) or for high-level system design from scratch (use system-design).
mcp
IncludedModel Context Protocol (MCP) server development and tool management. Languages: Python, TypeScript. Capabilities: build MCP servers, integrate external APIs, discover/execute MCP tools, manage multi-server configs, design agent-centric tools. Actions: create, build, integrate, discover, execute, configure MCP servers/tools. Keywords: MCP, Model Context Protocol, MCP server, MCP tool, stdio transport, SSE transport, tool discovery, resource provider, prompt template, external API integration, Gemini CLI MCP, Claude MCP, agent tools, tool execution, server config. Use when: building MCP servers, integrating external APIs as MCP tools, discovering available MCP tools, executing MCP capabilities, configuring multi-server setups, designing tools for AI agents.
react-native-skia
IncludedDesign, build, debug, and optimise high-polish animated graphics in React Native or Expo using @shopify/react-native-skia, Reanimated, and Gesture Handler. Use when the user wants canvas-driven UI, shaders, paths, rich text, image filters, sprite fields, Skottie, video frames, snapshots, web CanvasKit setup, or performance tuning for custom motion-heavy elements such as loaders, hero art, cards, charts, progress indicators, particle systems, or gesture-driven surfaces. Also use when the user asks for fluid, glow, glass, blob, parallax, 60fps/120fps, or GPU-friendly animated effects in React Native, even if they do not explicitly say "Skia". Do not use for ordinary form/layout work with standard views.
plaid
IncludedProduct Led AI Development — guides founders from idea to launched product. Six capabilities: Idea (discover a product idea), Validate (pressure-test the idea against fatal flaws, problem reality, competition, and 2-week MVP feasibility), Plan (vision intake + document generation), Design (translate image references into a design.md spec), Launch (go-to-market strategy), and Build (roadmap execution). Use when someone says "PLAID", "plaid idea", "help me find an idea", "product idea", "idea from my business", "idea from my expertise", "plaid validate", "validate my idea", "pressure-test", "is this idea good", "find fatal flaws", "validate the problem", "plan a product", "define my vision", "generate a PRD", "product strategy", "plaid design", "design from image", "translate image to design", "create design.md", "extract design tokens", "plaid launch", "go-to-market", "launch plan", "GTM strategy", "launch playbook", "plaid build", "build the app", "start building", or "execute the roadmap".
nextjs-framer-motion-animations
IncludedAdds production-safe Motion for React or Framer Motion animations to Next.js apps, including reveal, hover and tap micro-interactions, whileInView, stagger, AnimatePresence, layout and layoutId transitions, reorder, scroll-linked UI, and lightweight route-content transitions. Use when the user asks to add, refactor, or debug Motion or Framer Motion in App Router or Pages Router codebases, especially around server/client boundaries, reduced motion, LazyMotion, bundle size, hydration, or route transitions. Avoid for GSAP-style timelines, WebGL or 3D scenes, heavy scroll storytelling, or CSS-only effects unless Motion is explicitly requested.