Skip to main content
ClaudeWave
Skill29.5k repo starsupdated 2d ago

add-block

The add-block Claude Code slash command generates block configuration files for Sim integrations. Use it when you need to create a new block type with properly configured subBlocks, conditions, tool wiring, and authentication modes for integrating external services into the Sim platform.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/simstudioai/sim /tmp/add-block && cp -r /tmp/add-block/.agents/skills/add-block ~/.claude/skills/add-block
Then start a new Claude Code session; the skill loads automatically.

SKILL.md

# Add Block Skill

You are an expert at creating block configurations for Sim. You understand the serializer, subBlock types, conditions, dependsOn, modes, and all UI patterns.

## Your Task

When the user asks you to create a block:
1. Create the block file in `apps/sim/blocks/blocks/{service}.ts`
2. Configure all subBlocks with proper types, conditions, and dependencies
3. Wire up tools correctly

## Hard Rule: No Guessed Tool Outputs

Blocks depend on tool outputs. If the underlying tool response schema is not documented or live-verified, you MUST tell the user instead of guessing block outputs.

When block work changes tool execution, same-process work must use a registered
`InternalToolConfig.operation`. Never add a Sim `/api/...` self-hop or the retired
`directExecution` property.

- Do NOT invent block outputs for undocumented tool responses
- Do NOT describe unknown JSON shapes as if they were confirmed
- Do NOT wire fields into the block just because they seem likely to exist

If the tool outputs are not known, do one of these instead:
1. Ask the user for sample tool responses
2. Ask the user for test credentials so the tool responses can be verified
3. Limit the block to operations whose outputs are documented
4. Leave uncertain outputs out and explicitly tell the user what remains unknown

## Block Configuration Structure

```typescript
import { {ServiceName}Icon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import { AuthMode, IntegrationType } from '@/blocks/types'
import { getScopesForService } from '@/lib/oauth/utils'

export const {ServiceName}Block: BlockConfig = {
  type: '{service}',                    // snake_case identifier
  name: '{Service Name}',               // Human readable
  description: 'Brief description',     // One sentence
  longDescription: 'Detailed description for docs',
  docsLink: 'https://docs.sim.ai/integrations/{service}',
  category: 'tools',                    // 'tools' | 'blocks' | 'triggers'
  integrationType: IntegrationType.X,   // Primary category (see IntegrationType enum)
  tags: ['oauth', 'api'],              // Cross-cutting tags (see IntegrationTag type)
  bgColor: '#HEXCOLOR',                 // Brand color
  icon: {ServiceName}Icon,

  // Auth mode
  authMode: AuthMode.OAuth,             // or AuthMode.ApiKey

  // Card summary sentences — see "Canvas Sentences" below
  canvasPresentation: {
    defaultTitle: '{Default Operation}',
    sentences: { byOperation: { /* one per operation dropdown option id */ } },
  },

  subBlocks: [
    // Define all UI fields here
  ],

  tools: {
    access: ['tool_id_1', 'tool_id_2'], // Array of tool IDs this block can use
    config: {
      tool: (params) => `{service}_${params.operation}`,  // Tool selector function
      params: (params) => ({
        // Transform subBlock values to tool params
      }),
    },
  },

  inputs: {
    // Optional: define expected inputs from other blocks
  },

  outputs: {
    // Define outputs available to downstream blocks
  },
}
```

## SubBlock Types Reference

**Critical:** Every subblock `id` must be unique within the block. Duplicate IDs cause conflicts even with different conditions.

### Text Inputs
```typescript
// Single-line input
{ id: 'field', title: 'Label', type: 'short-input', placeholder: '...' }

// Multi-line input
{ id: 'field', title: 'Label', type: 'long-input', placeholder: '...', rows: 6 }

// Password input
{ id: 'apiKey', title: 'API Key', type: 'short-input', password: true }
```

### Selection Inputs
```typescript
// Dropdown (static options)
{
  id: 'operation',
  title: 'Operation',
  type: 'dropdown',
  options: [
    { label: 'Create', id: 'create' },
    { label: 'Update', id: 'update' },
  ],
  value: () => 'create',  // Default value function
}

// Combobox (searchable dropdown)
{
  id: 'field',
  title: 'Label',
  type: 'combobox',
  options: [...],
  searchable: true,
}
```

### Code/JSON Inputs
```typescript
{
  id: 'code',
  title: 'Code',
  type: 'code',
  language: 'javascript',  // 'javascript' | 'json' | 'python'
  placeholder: '// Enter code...',
}
```

### OAuth/Credentials
```typescript
{
  id: 'credential',
  title: 'Account',
  type: 'oauth-input',
  serviceId: '{service}',  // Must match OAuth provider service key
  requiredScopes: getScopesForService('{service}'),  // Import from @/lib/oauth/utils
  placeholder: 'Select account',
  required: true,
}
```

**Scopes:** Always use `getScopesForService(serviceId)` from `@/lib/oauth/utils` for `requiredScopes`. Never hardcode scope arrays — the single source of truth is `OAUTH_PROVIDERS` in `lib/oauth/oauth.ts`.

**Scope descriptions:** When adding a new OAuth provider, also add human-readable descriptions for all scopes in `SCOPE_DESCRIPTIONS` within `lib/oauth/utils.ts`.

**Service accounts (shared, app-level credentials):** A plain `oauth-input` already lets users *select* an existing service account — those credentials fold into the picker automatically (a Google service account created for any Google service appears in every Google block's picker). You only set `credentialKind` when you want to change the *connect* action:

```typescript
{
  id: 'credential',
  title: 'Account',
  type: 'oauth-input',
  serviceId: '{service}',
  requiredScopes: getScopesForService('{service}'),
  credentialKind: 'any',   // omit | 'service-account' | 'any'
}
```

- **omit (default):** lists OAuth accounts + any existing service accounts; the only connect action is "Connect account" (OAuth). Use this for the common "let users pick a service account someone set up elsewhere, but don't offer inline setup" case — no config needed.
- **`'service-account'`:** service-account credentials *only*, plus an inline setup action that opens the provider's connect modal. Use when a block accepts *only* an app credential.
- **`'any'`:** merged picker — OAuth accounts *and* service accounts in one grouped dropdown, with a connect action for each. Use when a block
add-connectorSkill

Add or update a Sim knowledge base connector for syncing documents from an external source, including auth mode, config fields, pagination, document mapping, tags, and registry wiring. Use when working in `apps/sim/connectors/{service}/` or adding a new external document source.

add-enrichmentSkill

Add a code-defined table enrichment (registry entry) under `apps/sim/enrichments/` backed by an ordered provider cascade, ensuring every provider tool it calls has hosted-key support. Use when adding a per-row table enrichment that fills cells via existing Sim tools.

add-hosted-keySkill

Add hosted API key support to a tool so Sim provides the key (metered and billed to the workspace) when a user has not brought their own. Use when adding a `hosting` config to a tool under `apps/sim/tools/{service}/`.

add-integrationSkill

Add a complete Sim integration from API docs, covering tools, block, icon, optional triggers, registrations, resolved-secret/model-input safety, and integration conventions. Use when introducing a new service under `apps/sim/tools`, `apps/sim/blocks`, and `apps/sim/triggers`.

add-modelSkill

Add a new LLM model to apps/sim/providers/models.ts with specs verified against the provider's live API docs (no hallucination)

add-toolsSkill

Create tool configurations for a Sim integration by reading API docs

add-triggerSkill

Create webhook or polling triggers for a Sim integration

cleanupSkill

Run all code quality skills — effects, memo, callbacks, state, React Query, emcn design review, url-state, and comments — analyzing in parallel, then applying fixes sequentially