Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
0075ab9
improvement(platform): remove tour, simplify sidebar/header, drop loa…
emir-karabeg Jun 6, 2026
20a00a1
fix(security): SSRF pinning, Twilio webhook auth, copilot token leak,…
waleedlatif1 Jun 6, 2026
15df511
chore(tables): own fractional-indexing in-house, drop runtime dep (#4…
TheodoreSpeaks Jun 7, 2026
c90a1eb
feat(tables): row-gutter drag-select, Cmd+F find, and select-all poli…
TheodoreSpeaks Jun 7, 2026
2c7b1ca
improvement(perms): member removal reassignment policies (#4906)
icecrasher321 Jun 8, 2026
d526b23
refactor(mothership-chats): rename task feature to chat, move route, …
waleedlatif1 Jun 8, 2026
ec256d2
fix(tables): compare order_key bytewise (COLLATE "C") to stop insert …
TheodoreSpeaks Jun 8, 2026
2577135
feat(enrichment): add ZeroBounce, NeverBounce, and MillionVerifier em…
waleedlatif1 Jun 8, 2026
27fc6dd
fix(user-input): atomic chip selection, modifier-key handling, and st…
waleedlatif1 Jun 8, 2026
e257d06
feat(integrations): suggest curated skills per integration with one-c…
waleedlatif1 Jun 8, 2026
ffd87a3
fix(home,integrations): optical-center home input + integrations page…
waleedlatif1 Jun 9, 2026
7677479
feat(auth): dynamic signup/login ban lists via AWS AppConfig (#4911)
TheodoreSpeaks Jun 9, 2026
7434df9
improvement(metrics): emit hosted-key metrics to CloudWatch instead o…
TheodoreSpeaks Jun 9, 2026
4f00baf
refactor(emcn): make ChipModal footer/header props-driven and migrate…
emir-karabeg Jun 9, 2026
a72e35e
feat(sendblue): add Sendblue iMessage/SMS integration with tools and …
waleedlatif1 Jun 9, 2026
05408fd
feat(emcn/toast): toast redesign — intent variants, stacking, hover r…
andresdjasso Jun 9, 2026
efeacb9
fix(tables): stop insert-row flicker and return order_key from rows l…
TheodoreSpeaks Jun 9, 2026
f7811f8
feat(tables): stable column ids for metadata-only rename (#4898)
TheodoreSpeaks Jun 9, 2026
b12b0f1
feat(models): add Claude Fable 5 (#4921)
waleedlatif1 Jun 9, 2026
24f0416
feat(integrations): expand tool coverage, audit integrations, regen d…
waleedlatif1 Jun 9, 2026
37f1141
fix(terminal): truncate console values by size and cycles, not nestin…
waleedlatif1 Jun 9, 2026
2f70188
fix(tables): route large CSV imports to the background job instead of…
TheodoreSpeaks Jun 9, 2026
1e35656
fix(modal): preserve spacing in workspace delete confirmation label (…
waleedlatif1 Jun 9, 2026
540835a
feat(integrations): add AWS AppConfig integration with tools, block, …
waleedlatif1 Jun 9, 2026
39418f9
improvement(mothership): v0.2 (#4923)
Sg312 Jun 9, 2026
c7689c0
fix(tables): key filter UI by stable column id; show column name in d…
TheodoreSpeaks Jun 9, 2026
efa4f27
fix(agent): unique tool ids for multi-instance tools + icon updates (…
waleedlatif1 Jun 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
87 changes: 84 additions & 3 deletions .agents/skills/add-block/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -627,19 +627,96 @@ export const ServiceV2Block: BlockConfig = {
}
```

## Block Metadata (BlockMeta)

Every integration block **must** export a `{Service}BlockMeta` object at the bottom of the block file. This metadata drives the integration catalog, tag filters, and workflow template suggestions shown to users.

### Structure

```typescript
import type { BlockConfig, BlockMeta } from '@/blocks/types'

// ... block definition above ...

export const {Service}BlockMeta = {
tags: ['messaging', 'automation'], // Same tags as the block's tags field
templates: [ // Optional but strongly encouraged
{
icon: {Service}Icon,
title: '{Service} use-case title',
prompt: 'Build a workflow that ...',
modules: ['agent', 'workflows'], // Modules the template uses
category: 'productivity', // Template category
tags: ['automation'], // Template-level tags
alsoIntegrations: ['slack'], // Other blocks referenced in the prompt (optional)
},
],
skills: [ // Optional but strongly encouraged
{
name: 'summarize-thread', // kebab-case, becomes the created skill's name
description: 'One line: what it does and when to use it.',
content:
'# Summarize Thread\n\n...\n\n## Steps\n1. ...\n\n## Output\n...', // markdown
},
],
} as const satisfies BlockMeta
```

### Rules

- **Import `BlockMeta`** from `@/blocks/types` alongside `BlockConfig`
- **`tags`** must match the `tags` array on the block config exactly
- **Templates are optional** but should be added for any integration that has a recognizable use case — aim for 2–4 templates per block
- **Template `prompt`** should start with "Build a workflow that..." or "Create a workflow that..." and be concrete enough to generate a real workflow in Mothership
- **Template `modules`** lists the Sim modules the template relies on: `'knowledge-base' | 'tables' | 'files' | 'workflows' | 'scheduled' | 'agent'`
- **Template `category`** is one of: `'popular' | 'sales' | 'support' | 'engineering' | 'marketing' | 'productivity' | 'operations'`
- **`alsoIntegrations`** names other block types (e.g. `'slack'`, `'linear'`) referenced in the template prompt — helps the catalog surface this template when those blocks are selected
- Place the export **after** the main `{Service}Block` export, at the very bottom of the file

#### `skills` — curated, ready-to-add agent skills

`skills` is an optional array of `SuggestedSkill` (`{ name, description, content }`) shown on the integration's detail page; users click **Add** to create the skill in their workspace. Aim for 3–5 skills for mainstream services, 2–3 for niche/low-level ones.

- **`name`** — kebab-case, lowercase letters/numbers/hyphens, ≤ 64 chars, unique within the integration, verb-led (e.g. `summarize-thread`).
- **`description`** — one line, ≤ 1024 chars: what it does and when to use it.
- **`content`** — markdown instructions for the agent (literal `\n` for newlines): a `# Title`, then `## Steps` and an output/guidance section. Keep ~600–2000 chars.
- **Ground every skill in operations the block actually exposes.** Cross-check each skill's steps against the block's `tools.access` list — never describe an action the integration cannot perform (e.g. "receive messages" when the block only sends).
- **Skills MUST be derived from real, popular use cases found online — never invented.** Before adding a skill, web-search the service's documented use cases (vendor use-case/solutions pages, official docs describing the workflow, reputable "top automations for X" articles). If you cannot source a use case as something people genuinely do with the service, do not add it. Do not hallucinate skills.

### Register in the blocksMeta object

After adding `{Service}BlockMeta` to the block file, register it in `apps/sim/blocks/registry.ts`:

```typescript
// Add import (alongside the block import, alphabetically)
import { ServiceBlock, ServiceBlockMeta } from '@/blocks/blocks/service'

// Add to blocksMeta object (alphabetically)
export const blocksMeta = {
// ... existing entries ...
service: ServiceBlockMeta,
}
```

## Registering Blocks

After creating the block, remind the user to:
1. Import in `apps/sim/blocks/registry.ts`
1. Import `{Service}Block` and `{Service}BlockMeta` in `apps/sim/blocks/registry.ts`
2. Add to the `registry` object (alphabetically):
3. Add to the `blocksMeta` object (alphabetically):

```typescript
import { ServiceBlock } from '@/blocks/blocks/service'
import { ServiceBlock, ServiceBlockMeta } from '@/blocks/blocks/service'

export const registry: Record<string, BlockConfig> = {
// ... existing blocks ...
service: ServiceBlock,
}

export const blocksMeta = {
// ... existing entries ...
service: ServiceBlockMeta,
}
```

## Complete Example
Expand Down Expand Up @@ -827,7 +904,11 @@ All tool IDs referenced in `tools.access` and returned by `tools.config.tool` MU
- [ ] Tools.access lists all tool IDs (snake_case)
- [ ] Tools.config.tool returns correct tool ID (snake_case)
- [ ] Outputs match tool outputs
- [ ] Block registered in registry.ts
- [ ] Block registered in `registry.ts` blocks object (alphabetically)
- [ ] `{Service}BlockMeta` exported at bottom of block file with `tags` and `templates`
- [ ] `skills` added to `{Service}BlockMeta`, each grounded in the block's `tools.access` and derived from a real online-sourced use case (not invented)
- [ ] `BlockMeta` imported from `@/blocks/types` alongside `BlockConfig`
- [ ] Block meta registered in `registry.ts` blocksMeta object (alphabetically)
- [ ] If icon missing: asked user to provide SVG
- [ ] If triggers exist: `triggers` config set, trigger subBlocks spread
- [ ] Optional/rarely-used fields set to `mode: 'advanced'`
Expand Down
45 changes: 40 additions & 5 deletions .agents/skills/add-integration/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ export const {service}{Action}Tool: ToolConfig<Params, Response> = {
### Block Structure
```typescript
import { {Service}Icon } from '@/components/icons'
import type { BlockConfig } from '@/blocks/types'
import type { BlockConfig, BlockMeta } from '@/blocks/types'
import { AuthMode } from '@/blocks/types'
import { getScopesForService } from '@/lib/oauth/utils'

Expand Down Expand Up @@ -177,8 +177,32 @@ export const {Service}Block: BlockConfig = {

outputs: { /* ... */ },
}

export const {Service}BlockMeta = {
tags: ['tag1', 'tag2'], // IntegrationTag values matching the service's capabilities
templates: [
{
icon: {Service}Icon,
title: '{Service} use-case title',
prompt: 'Build a workflow that ...',
modules: ['agent', 'workflows'],
category: 'productivity',
tags: ['automation'],
alsoIntegrations: ['slack'], // Optional: other blocks referenced in the prompt
},
],
} as const satisfies BlockMeta
```

### BlockMeta rules

- **Tags**: Use `IntegrationTag` values from `@/blocks/types`. Do NOT add a `tags` field to the `BlockConfig` object — tags belong only in `BlockMeta`.
- **`integrationType`**: Must be a valid `IntegrationType` enum value (AI, Analytics, Commerce, Communication, Databases, DevOps, Documents, Email, HR, Marketing, Observability, Productivity, Sales, Search, Security, Support). Never invent a value that doesn't exist in the enum.
- **Templates**: Aim for 2–4 templates per integration. Prompts should be concrete enough to generate a real workflow in Mothership. Start with "Build a workflow that..." or "Create a workflow that...".
- **`alsoIntegrations`**: List other block type IDs referenced in the template prompt (e.g. `'slack'`, `'linear'`).
- Place `{Service}BlockMeta` at the very bottom of the file, after the main block export.
- Register it in both the import and the `blocksMeta` object in `registry.ts`.

### Key SubBlock Patterns

**Condition-based visibility:**
Expand Down Expand Up @@ -359,14 +383,20 @@ export const tools: Record<string, ToolConfig> = {
### Block Registry (`apps/sim/blocks/registry.ts`)

```typescript
// Add import (alphabetically)
import { {Service}Block } from '@/blocks/blocks/{service}'
// Add import (alphabetically) — include BlockMeta
import { {Service}Block, {Service}BlockMeta } from '@/blocks/blocks/{service}'

// Add to registry (alphabetically)
// Add to blocks registry (alphabetically)
export const registry: Record<string, BlockConfig> = {
// ... existing blocks ...
{service}: {Service}Block,
}

// Add to blocksMeta registry (alphabetically)
export const blocksMeta = {
// ... existing entries ...
{service}: {Service}BlockMeta,
}
```

### Trigger Registry (`apps/sim/triggers/registry.ts`) - If triggers exist
Expand Down Expand Up @@ -433,7 +463,12 @@ If creating V2 versions (API-aligned outputs):
- [ ] Configured tools.access with all tool IDs
- [ ] Configured tools.config.tool selector
- [ ] Defined outputs matching tool outputs
- [ ] Registered block in `blocks/registry.ts`
- [ ] `integrationType` uses a valid `IntegrationType` enum value (no invented values)
- [ ] No `tags` field on the `BlockConfig` object (tags live only in `BlockMeta`)
- [ ] `{Service}BlockMeta` exported at bottom of file with `tags` and `templates`
- [ ] `BlockMeta` type imported from `@/blocks/types` alongside `BlockConfig`
- [ ] Block registered in `blocks/registry.ts` blocks object (alphabetically)
- [ ] Block meta registered in `blocks/registry.ts` blocksMeta object (alphabetically)
- [ ] If triggers: set `triggers.enabled` and `triggers.available`
- [ ] If triggers: spread trigger subBlocks with `getTrigger()`

Expand Down
6 changes: 6 additions & 0 deletions .agents/skills/validate-integration/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ For **each tool** in `tools.access`:
- [ ] `authMode` is set correctly (`AuthMode.OAuth` or `AuthMode.ApiKey`)
- [ ] Block is registered in `blocks/registry.ts` alphabetically

### BlockMeta Skills (catalog)
- [ ] `{Service}BlockMeta.skills` is present (3–5 for mainstream services, 2–3 for niche/low-level)
- [ ] **Every skill is grounded** — its steps only use operations the block exposes in `tools.access`; flag any skill that implies an unsupported action (e.g. "receive messages" when the block only sends)
- [ ] **Every skill is real, not hallucinated** — web-search the service and confirm each skill maps to a popular use case attested online (vendor use-case/solutions pages, official docs describing the workflow, reputable "top automations for X" articles). Rewrite or remove any skill you cannot source as something people genuinely do with the service.
- [ ] Each skill has a kebab-case `name` (≤64 chars, unique), a one-line `description`, and markdown `content` with `# Title` + `## Steps` + an output/guidance section

### Block Inputs
- [ ] `inputs` section lists all subBlock params that the block accepts
- [ ] Input types match the subBlock types
Expand Down
71 changes: 51 additions & 20 deletions .claude/commands/add-block.md
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ Maps multiple UI fields to a single serialized parameter:

**Critical constraints:**
- `canonicalParamId` must NOT match any other subblock's `id` in the same block (causes conflicts)
- `canonicalParamId` must be unique per block (only one basic/advanced pair per canonicalParamId)
- A `canonicalParamId` links exactly one basic/advanced pair for a single logical parameter. Do NOT reuse the same `canonicalParamId` for different parameters, even under mutually-exclusive conditions/operations
- ONLY use `canonicalParamId` to link basic/advanced mode alternatives for the same logical parameter
- Do NOT use it for any other purpose

Expand Down Expand Up @@ -519,7 +519,10 @@ tools: {
Block outputs only support:
- `type` - The data type ('string', 'number', 'boolean', 'json', 'array')
- `description` - Human readable description
- Nested object structure (for complex types)
- `condition` - Optional visibility condition
- `hiddenFromDisplay` - Optional flag to hide from the output display

**Nested object/`properties` outputs are tool-output-only and will fail TypeScript at build time on block outputs.** For complex shapes use `type: 'json'` and describe the inner fields in the `description` string.

```typescript
outputs: {
Expand All @@ -542,7 +545,7 @@ outputs: {

### Typed JSON Outputs

When using `type: 'json'` and you know the object shape in advance, **describe the inner fields in the description** so downstream blocks know what properties are available. For well-known, stable objects, use nested output definitions instead:
When using `type: 'json'` and you know the object shape in advance, **describe the inner fields in the description** so downstream blocks know what properties are available. Block outputs have no nested `properties` form — always keep the output flat and put the shape in the `description`:

```typescript
outputs: {
Expand All @@ -554,26 +557,10 @@ outputs: {
type: 'json',
description: 'Zone plan information (id, name, price, currency, frequency, is_subscribed)',
},

// BEST: Use nested output definition when the shape is stable and well-known
plan: {
id: { type: 'string', description: 'Plan identifier' },
name: { type: 'string', description: 'Plan name' },
price: { type: 'number', description: 'Plan price' },
currency: { type: 'string', description: 'Price currency' },
},
}
```

Use the nested pattern when:
- The object has a small, stable set of fields (< 10)
- Downstream blocks will commonly access specific properties
- The API response shape is well-documented and unlikely to change

Use `type: 'json'` with a descriptive string when:
- The object has many fields or a dynamic shape
- It represents a list/array of items
- The shape varies by operation
Nested object outputs (`plan: { id: { type: 'string' }, ... }`) are a **tool-output** feature only — `OutputFieldDefinition` for blocks does not allow them and they fail TypeScript at build time.

## V2 Block Pattern

Expand Down Expand Up @@ -798,6 +785,47 @@ Use `wandConfig` for fields that are hard to fill out manually, such as timestam

All tool IDs referenced in `tools.access` and returned by `tools.config.tool` MUST use `snake_case` (e.g., `x_create_tweet`, `slack_send_message`). Never use camelCase or PascalCase.

## BlockMeta (Required)

Every block file must export a `{Service}BlockMeta` alongside the block — **minimum 7 templates**. Look at existing examples in `apps/sim/blocks/blocks/` (e.g. `browser_use.ts`, `google_sheets.ts`) for the pattern.

```typescript
import type { BlockMeta } from '@/blocks/types'

export const {Service}BlockMeta = {
tags: ['tag1', 'tag2'], // IntegrationTag[]
templates: [
{
icon: {Service}Icon,
title: '{Service} <use-case>', // 2–5 words
prompt: 'Build a workflow that...', // specific use case, 1–3 sentences
modules: ['agent', 'workflows'], // 'agent' | 'workflows' | 'tables' | 'files' | 'scheduled' | 'knowledge-base'
category: 'operations', // 'operations' | 'marketing' | 'sales' | 'engineering' | 'productivity' | 'support' | 'popular'
tags: ['automation'],
alsoIntegrations: ['slack'], // optional — other block IDs referenced in the prompt
featured: true, // optional
},
// ... at least 6 more
],
skills: [ // SuggestedSkill[] — 3–5 mainstream, 2–3 niche
{
name: 'summarize-thread', // kebab-case, ≤64 chars, unique, verb-led
description: 'One line: what it does and when to use it.', // ≤1024 chars
content:
'# Summarize Thread\n\n...\n\n## Steps\n1. ...\n\n## Output\n...', // markdown
},
// ... more
],
} as const satisfies BlockMeta
```

Derive templates from the service's real use cases. Each prompt should name a concrete trigger, transformation, and output — not a generic description of what the service does.

`skills` are curated, ready-to-add agent skills shown on the integration's detail page (users click **Add** to create them in their workspace). Two hard rules:

- **Ground every skill in operations the block actually exposes** — cross-check each skill's steps against `tools.access`. Never describe an action the integration cannot perform.
- **Derive skills from real, popular use cases found online — never invent them.** Web-search the service's documented use cases (vendor use-case/solutions pages, official docs describing the workflow, reputable "top automations for X" articles) and only add a skill you can source as something people genuinely do with the service. Do not hallucinate skills.

## Checklist Before Finishing

- [ ] `integrationType` is set to the correct `IntegrationType` enum value
Expand All @@ -816,6 +844,8 @@ All tool IDs referenced in `tools.access` and returned by `tools.config.tool` MU
- [ ] If triggers exist: `triggers` config set, trigger subBlocks spread
- [ ] Optional/rarely-used fields set to `mode: 'advanced'`
- [ ] Timestamps and complex inputs have `wandConfig` enabled
- [ ] Exported `{Service}BlockMeta` with at least 7 templates
- [ ] `skills` added to `{Service}BlockMeta`, each grounded in `tools.access` and sourced from a real online use case (not invented)

## Final Validation (Required)

Expand All @@ -829,3 +859,4 @@ After creating the block, you MUST validate it against every tool it references:
- Type coercions in `tools.config.params` for any params that need conversion (Number(), Boolean(), JSON.parse())
3. **Verify block outputs** cover the key fields returned by all tools
4. **Verify conditions** — each subBlock should only show for the operations that actually use it
5. **Verify `{Service}BlockMeta` is exported** with at least 7 templates, each having `icon`, `title`, `prompt`, `modules`, `category`, and `tags`
Loading
Loading